diff options
author | Richard Moe Gustavsen <richard.gustavsen@nokia.com> | 2011-02-14 08:32:26 (GMT) |
---|---|---|
committer | Eckhart Koppen <eckhart.koppen@nokia.com> | 2011-02-15 06:02:03 (GMT) |
commit | 6415f2814ae30d162e335d1ffd6d093b12701f03 (patch) | |
tree | 745b0bbfc2a57a9d92a08bfda7d72900621a71c6 /src | |
parent | e5152123c7fea830c522916a2bb9c16583d5f666 (diff) | |
download | Qt-6415f2814ae30d162e335d1ffd6d093b12701f03.zip Qt-6415f2814ae30d162e335d1ffd6d093b12701f03.tar.gz Qt-6415f2814ae30d162e335d1ffd6d093b12701f03.tar.bz2 |
Cocoa/Alien: bugfix corner cases with popups and enter/leave
It turns out that we sometimes hit a strange bug with enter/leave
events when a popup is showing. If you righpress to show the popup,
and then move the mouse outside the window, we get a continues series
of leave events. This patch separates more the native vs alien logic
for dispatching enter/leave to accommondate this problem
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qcocoaapplicationdelegate_mac.mm | 4 | ||||
-rw-r--r-- | src/gui/kernel/qcocoaview_mac.mm | 2 | ||||
-rw-r--r-- | src/gui/kernel/qt_cocoa_helpers_mac.mm | 33 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_mac.mm | 7 |
4 files changed, 28 insertions, 18 deletions
diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index 6d7bc19..77cd890 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -91,6 +91,7 @@ QT_BEGIN_NAMESPACE extern void onApplicationChangedActivation(bool); // qapplication_mac.mm extern void qt_release_apple_event_handler(); //qapplication_mac.mm extern QPointer<QWidget> qt_last_mouse_receiver; // qapplication_mac.cpp +extern QPointer<QWidget> qt_last_native_mouse_receiver; // qt_cocoa_helpers_mac.mm extern QPointer<QWidget> qt_button_down; // qapplication_mac.cpp QT_END_NAMESPACE @@ -268,6 +269,8 @@ static void cleanupCocoaApplicationDelegate() qt_mac_getTargetForMouseEvent(0, QEvent::Enter, qlocal, qglobal, 0, &widgetUnderMouse); QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, 0); qt_last_mouse_receiver = widgetUnderMouse; + qt_last_native_mouse_receiver = widgetUnderMouse ? + (widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget()) : 0; } } @@ -282,6 +285,7 @@ static void cleanupCocoaApplicationDelegate() if (!QWidget::mouseGrabber()) QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver); qt_last_mouse_receiver = 0; + qt_last_native_mouse_receiver = 0; qt_button_down = 0; } diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index f0ae886..3d87a9e 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -78,6 +78,7 @@ QT_BEGIN_NAMESPACE extern void qt_mac_update_cursor(); // qcursor_mac.mm extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); // qapplication.cpp extern QPointer<QWidget> qt_last_mouse_receiver; // qapplication_mac.cpp +extern QPointer<QWidget> qt_last_native_mouse_receiver; // qt_cocoa_helpers_mac.mm extern OSViewRef qt_mac_nativeview_for(const QWidget *w); // qwidget_mac.mm extern OSViewRef qt_mac_effectiveview_for(const QWidget *w); // qwidget_mac.mm extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp @@ -461,6 +462,7 @@ static int qCocoaViewCount = 0; if (widgetUnderMouse == 0) { QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver); qt_last_mouse_receiver = 0; + qt_last_native_mouse_receiver = 0; } } } diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index e50bdd3..c8132e8 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -1064,7 +1064,7 @@ QWidget *qt_mac_getTargetForMouseEvent( // Resolve the widget under the mouse: QWidget *widgetUnderMouse = 0; - if (popup || qt_button_down || !nativeWidget) { + if (popup || qt_button_down || !nativeWidget || !nativeWidget->isVisible()) { // Using QApplication::widgetAt for finding the widget under the mouse // is most safe, since it ignores cocoas own mouse down redirections (which // we need to be prepared for when using nativeWidget as starting point). @@ -1139,6 +1139,8 @@ QWidget *qt_mac_getTargetForMouseEvent( return target; } +QPointer<QWidget> qt_last_native_mouse_receiver = 0; + static inline void qt_mac_checkEnterLeaveForNativeWidgets(QWidget *maybeEnterWidget) { // Dispatch enter/leave for the cases where QApplicationPrivate::sendMouseEvent do @@ -1149,29 +1151,25 @@ static inline void qt_mac_checkEnterLeaveForNativeWidgets(QWidget *maybeEnterWid if (qt_button_down || QWidget::mouseGrabber()) return; - if ((maybeEnterWidget == qt_last_mouse_receiver) && qt_last_mouse_receiver) - return; + if ((maybeEnterWidget == qt_last_native_mouse_receiver) && qt_last_native_mouse_receiver) + return; if (maybeEnterWidget) { - if (!qt_last_mouse_receiver) { + if (!qt_last_native_mouse_receiver) { // case 3 QApplicationPrivate::dispatchEnterLeave(maybeEnterWidget, 0); - qt_last_mouse_receiver = maybeEnterWidget; - } else if (qt_last_mouse_receiver->internalWinId() && maybeEnterWidget->internalWinId()) { + qt_last_native_mouse_receiver = maybeEnterWidget->internalWinId() ? maybeEnterWidget : maybeEnterWidget->nativeParentWidget(); + } else if (maybeEnterWidget->internalWinId()) { // case 1 - if (qt_last_mouse_receiver->isVisible()) { - QApplicationPrivate::dispatchEnterLeave(maybeEnterWidget, qt_last_mouse_receiver); - qt_last_mouse_receiver = maybeEnterWidget; - } + QApplicationPrivate::dispatchEnterLeave(maybeEnterWidget, qt_last_native_mouse_receiver); + qt_last_native_mouse_receiver = maybeEnterWidget->internalWinId() ? maybeEnterWidget : maybeEnterWidget->nativeParentWidget(); } // else at lest one of the widgets are alien, so enter/leave will be handled in QApplicationPrivate } else { - if (qt_last_mouse_receiver && qt_last_mouse_receiver->internalWinId()) { + if (qt_last_native_mouse_receiver) { // case 2 - QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver); - // This seems to be the only case where we need to update qt_last_mouse_receiver - // from the mac specific code. Otherwise, QApplicationPrivate::sendMouseEvent - // will handle it: + QApplicationPrivate::dispatchEnterLeave(0, qt_last_native_mouse_receiver); qt_last_mouse_receiver = 0; + qt_last_native_mouse_receiver = 0; } } } @@ -1276,8 +1274,9 @@ bool qt_mac_handleMouseEvent(NSEvent *event, QEvent::Type eventType, Qt::MouseBu if (eventType == QEvent::MouseButtonRelease) { // A mouse button was released, which means that the implicit grab was // released. We therefore need to re-check if should send (delayed) enter leave events: - // qt_button_down has now become NULL since the call at the top of the function. - widgetToGetMouse = qt_mac_getTargetForMouseEvent(0, QEvent::None, localPoint, globalPoint, nativeWidget, &widgetUnderMouse); + // qt_button_down has now become NULL since the call at the top of the function. Also, since + // the relase might have closed a window, we dont give the nativeWidget hint + qt_mac_getTargetForMouseEvent(0, QEvent::None, localPoint, globalPoint, nativeWidget, &widgetUnderMouse); qt_mac_checkEnterLeaveForNativeWidgets(widgetUnderMouse); } diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 3ba12cd..9a5a5f1 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -186,6 +186,7 @@ extern void qt_mac_event_release(QWidget *w); //qapplication_mac.mm extern void qt_event_request_showsheet(QWidget *); //qapplication_mac.mm extern void qt_event_request_window_change(QWidget *); //qapplication_mac.mm extern QPointer<QWidget> qt_last_mouse_receiver; //qapplication_mac.mm +extern QPointer<QWidget> qt_last_native_mouse_receiver; //qt_cocoa_helpers_mac.mm extern IconRef qt_mac_create_iconref(const QPixmap &); //qpixmap_mac.cpp extern void qt_mac_set_cursor(const QCursor *, const QPoint &); //qcursor_mac.mm extern void qt_mac_update_cursor(); //qcursor_mac.mm @@ -3524,6 +3525,8 @@ void QWidgetPrivate::show_sys() qt_mac_getTargetForMouseEvent(0, QEvent::Enter, qlocal, qglobal, 0, &widgetUnderMouse); QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, qt_last_mouse_receiver); qt_last_mouse_receiver = widgetUnderMouse; + qt_last_native_mouse_receiver = widgetUnderMouse ? + (widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget()) : 0; } #endif @@ -3676,8 +3679,10 @@ void QWidgetPrivate::hide_sys() QPoint qlocal, qglobal; QWidget *widgetUnderMouse = 0; qt_mac_getTargetForMouseEvent(0, QEvent::Leave, qlocal, qglobal, 0, &widgetUnderMouse); - QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, qt_last_mouse_receiver); + QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, qt_last_native_mouse_receiver); qt_last_mouse_receiver = widgetUnderMouse; + qt_last_native_mouse_receiver = widgetUnderMouse ? + (widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget()) : 0; } #endif |