Review Request: KTabBar: Don't crash on middle-clicking tabs with Qt 4.5.2
Urs Wolfer
uwolfer at kde.org
Wed Jul 15 19:09:46 BST 2009
-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
http://reviewboard.kde.org/r/1017/#review1615
-----------------------------------------------------------
Ship it!
Looks good to me.
- Urs
On 2009-07-13 21:50:12, Frank Reininghaus wrote:
>
> -----------------------------------------------------------
> This is an automatically generated e-mail. To reply, visit:
> http://reviewboard.kde.org/r/1017/
> -----------------------------------------------------------
>
> (Updated 2009-07-13 21:50:12)
>
>
> Review request for kdelibs.
>
>
> Summary
> -------
>
> The combination of a QTabBar change in Qt 4.5.2 and the recent restoration of middle-click tab moving in KTabBars which have the movable attribute set leads to a crash if a tab is middle-clicked before the first "tab move" operation, see
>
> http://bugs.kde.org/show_bug.cgi?id=198075
>
> I think the reason is as follows:
>
> 1. If the middle mouse button is pressed on a tab, KTabBar::mousePressEvent() creates a "faked" QMouseEvent (with middle button replaced by left button) and sends that to itself to make QTabBar think that the left mouse button was pressed and a tab move operation can be started.
>
> 2. The faked event ends up in QTabBar::mousePressEvent(). In that method, d->pressedIndex is set from the default value -1 to the index of the pressed tab.
>
> [QTabBar::mouseMoveEvent(), which is never called in the problematic use case, uses d->pressedIndex to determine that a tab move operation is in progress, sets d->dragInProgress to true and calls QTabBarPrivate::setupMovableTab() which initialises the QWidget* d->movingTab, which is 0 initially]
>
> 3. If the middle mouse button is released *before* the mouse is moved, KTabBar::mouseReleaseEvent() emits a mouseMiddleClick signal and returns. No faked QMouseEvent is generated in this case because d->mMiddleMouseTabMoveInProgress is false unless the mouse is moved between pressing and releasing the button.
>
> [If QTabBar::mouseReleaseEvent() was called now, it would set d->pressedIndex back to its default value -1, indicating that no tab move is in progress].
>
> 4. If either QTabBar::mouseMoveEvent() or QTabBar::removeTab() (in case middle clicking is configured to close tabs) are called now, they think a tab move operation is in progress because d->pressedIndex is not -1 and try to finish that operation. We therefore end up in QTabBarPrivate::_q_moveTabFinished(int index), which relies on the QWidget* movingTab being initialised -> we get a segfault.
>
> I would suggest to fix it by also sending a faked QMouseEvent in 3. At the moment, I can't see any other way of resetting d->pressedIndex without breaking other things, but maybe I'm overlooking something.
>
>
> This addresses bug 198075.
> https://bugs.kde.org/show_bug.cgi?id=198075
>
>
> Diffs
> -----
>
> /trunk/KDE/kdelibs/kdeui/widgets/ktabbar.cpp 996095
>
> Diff: http://reviewboard.kde.org/r/1017/diff
>
>
> Testing
> -------
>
> Fixes the crash for me (no matter if middle-clicking is configured to close tabs or not). Everything else (including ktabwidgettest and ktabwidget_unittest) seems to work fine.
>
>
> Thanks,
>
> Frank
>
>
More information about the kde-core-devel
mailing list