diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2011-02-09 20:09:27 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2011-02-09 20:09:27 (GMT) |
commit | a1fcebed2b17b688c656f6a7326f7cc5516f4327 (patch) | |
tree | fd22c29e8c5f53e1cff0528f8df7c761f452b8c4 /src/gui | |
parent | 2243b39550f4c3a2880220bb852db5e4b3581bb1 (diff) | |
parent | 7526131cd169b208ed499e62cd493b3d48598a6e (diff) | |
download | Qt-a1fcebed2b17b688c656f6a7326f7cc5516f4327.zip Qt-a1fcebed2b17b688c656f6a7326f7cc5516f4327.tar.gz Qt-a1fcebed2b17b688c656f6a7326f7cc5516f4327.tar.bz2 |
Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-water-staging into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/qt-water-staging:
Cocoa: Mouse-grabbing in pop-up menus on OS X isn't working
Alien/Cocoa: popups in creator does not always work for press'n'hold
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qt_cocoa_helpers_mac.mm | 74 |
1 files changed, 36 insertions, 38 deletions
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index ddbf53f..e50bdd3 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -1060,30 +1060,26 @@ QWidget *qt_mac_getTargetForMouseEvent( returnGlobalPoint = flipPoint([NSEvent mouseLocation]).toPoint(); QWidget *mouseGrabber = QWidget::mouseGrabber(); bool buttonDownNotBlockedByModal = qt_button_down && !QApplicationPrivate::isBlockedByModal(qt_button_down); + QWidget *popup = QApplication::activePopupWidget(); // Resolve the widget under the mouse: QWidget *widgetUnderMouse = 0; - if (nativeWidget) { + if (popup || qt_button_down || !nativeWidget) { + // 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). + // (the only exception is for QMacNativeWidget, where QApplication::widgetAt fails). + // But it is also slower (I guess), so we try to avoid it and use nativeWidget if we can: + widgetUnderMouse = QApplication::widgetAt(returnGlobalPoint); + } + + if (!widgetUnderMouse && nativeWidget) { + // Entering here should be the common case. We + // also handle the QMacNativeWidget fallback case. QPoint p = nativeWidget->mapFromGlobal(returnGlobalPoint); widgetUnderMouse = nativeWidget->childAt(p); - if (!widgetUnderMouse){ - // Cocoa will redirct mouse event to the current - // mouse down widget, which is not what we want for our - // widgetUnderMouse assignment. So we need to check - // if we are actually inside nativeView: - if (nativeWidget->rect().contains(p)) { - widgetUnderMouse = nativeWidget; - } else { - // Ok, fallback to find the widget under mouse ourselves. - widgetUnderMouse = QApplication::widgetAt(returnGlobalPoint); - } - } - } else { - // Calling QApplication::widgetAt is potentially slow, hence the - // reason we avoid it if we can. So supplying a nativeWidget to - // this function is mostly an optimization. But at the same time, - // calling QApplication::widgetAt fails for QMacNativeWidget... - widgetUnderMouse = QApplication::widgetAt(returnGlobalPoint); + if (!widgetUnderMouse && nativeWidget->rect().contains(p)) + widgetUnderMouse = nativeWidget; } if (widgetUnderMouse) { @@ -1107,23 +1103,27 @@ QWidget *qt_mac_getTargetForMouseEvent( if (returnWidgetUnderMouse) *returnWidgetUnderMouse = widgetUnderMouse; - // Resolve the target for the mouse event. Default will be widgetUnderMouse, except - // if there is a popup-"grab", mousegrab, or button-down-"grab": - QWidget *popup = QApplication::activePopupWidget(); + // Resolve the target for the mouse event. Default will be + // widgetUnderMouse, except if there is a grab (popup/mouse/button-down): if (popup && !mouseGrabber) { - if (!popup->isAncestorOf(widgetUnderMouse)) { - // The popup will always grab the mouse unless the - // mouse is over a child, or the user scrolls: + // We special case handling of popups, since they have an implicitt mouse grab. + QWidget *candidate = buttonDownNotBlockedByModal ? qt_button_down : widgetUnderMouse; + if (!popup->isAncestorOf(candidate)) { + // INVARIANT: we have a popup, but the candidate is not + // in it. But the popup will grab the mouse anyway, + // except if the user scrolls: if (eventType == QEvent::Wheel) return 0; returnLocalPoint = popup->mapFromGlobal(returnGlobalPoint); return popup; - } else if (popup == widgetUnderMouse) { + } else if (popup == candidate) { + // INVARIANT: The candidate is the popup itself, and not a child: returnLocalPoint = popup->mapFromGlobal(returnGlobalPoint); return popup; } else { - returnLocalPoint = widgetUnderMouse->mapFromGlobal(returnGlobalPoint); - return widgetUnderMouse; + // INVARIANT: The candidate is a child inside the popup: + returnLocalPoint = candidate->mapFromGlobal(returnGlobalPoint); + return candidate; } } @@ -1192,16 +1192,14 @@ bool qt_mac_handleMouseEvent(NSEvent *event, QEvent::Type eventType, Qt::MouseBu if (!widgetToGetMouse) return false; - if (!nativeWidget) { - // Path typically taken for mouse moves (send - // directly from [QCocoaWindow sendEvent] - if (!widgetUnderMouse) - return false; - nativeWidget = widgetUnderMouse->internalWinId() ? - widgetUnderMouse : widgetUnderMouse->nativeParentWidget(); - if (!nativeWidget) - return false; - } + // From here on, we let nativeWidget actually be the native widget under widgetUnderMouse. The reason + // for this, is that qt_mac_getTargetForMouseEvent will set cocoa's mouse event redirection aside when + // determining which widget is under the mouse (in other words, it will usually ignore nativeWidget). + // nativeWidget will be used in QApplicationPrivate::sendMouseEvent to correctly dispatch enter/leave events. + if (widgetUnderMouse) + nativeWidget = widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget(); + if (!nativeWidget) + return false; NSView *view = qt_mac_effectiveview_for(nativeWidget); // Handle tablet events (if any) first. |