-
Bug
-
Resolution: Unresolved
-
P1: Critical
-
None
-
6.3.2, 6.4.3, 6.5.3, 6.6.3, 6.7.3, 6.8.3, 6.9.3, 6.10.0
-
None
`QTabBar::insertTab` calls `d->refresh()`, which checks if the widget is visible and sets `layoutDirty = true`if so instead of calling `layoutTabs()`. On versions of Qt before 6.3 this means that calling `setVisible(false)` on a QTabWidget before adding many tabs and then setting it visible when done adding can mean that `layoutTabs()` is only called once, after the QTabWidget is shown again.
However, commit 02164b292f002b051f34a88871145415fad94f32 "Don't use QCursor::pos in QTabBar and fix hover handling" added a call to `tabAt(d->mousePosition)` after the tab is added. `tabAt` calls `tabRect` which calls `layoutTabs()` if `layoutDirty` is set, and none of these check if the QTabBar is visible before doing so (even though, ultimately, if the QTabBar is not visible then it is known the tabRect will be empty and there will be no tab at the mouse position). This means that on Qt 6.3 and later, `layoutTabs()` is *always* called once per `insertTab` call, even if the QTabWidget is hidden and not visible.
`layoutTabs()` checks the sizeHint and minimumSizeHint for every tab currently in the tabBar. Thus, on Qt 6.2 and earlier, adding many tabs is O(N^2) when the QTabWidget is visible but only O(N) when it is not visible. However, on Qt 6.3 and later, adding many tabs is always O(N^2), even if the QTabWidget is not visible, and there is no way around this.
This causes a particularly large reassembled frame with many non byte aligned fields (and thus 4594 tabs) to be hundreds to thousands of times slower to initially render on Qt 6.3 and later than on earlier versions of Qt.
https://gitlab.com/wireshark/wireshark/-/issues/20797