diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-02-19 01:00:07 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-02-19 01:00:08 +0100 |
commit | 67c70b22f6376d3c8fbffaed73481d4e0675cb43 (patch) | |
tree | e3c40849413beb3c112de0fc380bc2aaa0a04ea8 /src/plugins/platforms | |
parent | 5242126a610ebe76513cee22ecd8b5354bbf96b7 (diff) | |
parent | 6273b484b35479eb5788425c8d90acacdf239623 (diff) |
Merge remote-tracking branch 'origin/5.12' into 5.13
Change-Id: Ifa143cc462301aaa305c9c85360e543553a751f0
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm | 24 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 40 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 85 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnswindow.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnswindow.mm | 13 |
7 files changed, 49 insertions, 117 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 44ab16d300..9e3c89b6a4 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -353,21 +353,6 @@ QT_USE_NAMESPACE [reflectionDelegate applicationDidBecomeActive:notification]; QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); -/* - onApplicationChangedActivation(true); - - if (!QWidget::mouseGrabber()){ - // Update enter/leave immidiatly, don't wait for a move event. But only - // if no grab exists (even if the grab points to this widget, it seems, ref X11) - QPoint qlocal, qglobal; - QWidget *widgetUnderMouse = 0; - 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; - } -*/ } - (void)applicationDidResignActive:(NSNotification *)notification @@ -377,15 +362,6 @@ QT_USE_NAMESPACE [reflectionDelegate applicationDidResignActive:notification]; QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive); -/* - onApplicationChangedActivation(false); - - 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; -*/ } - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index ebf33cf4e2..9771cd0289 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -168,10 +168,10 @@ public: uint processEventsCalled; NSModalSession currentModalSessionCached; NSModalSession currentModalSession(); - void updateChildrenWorksWhenModal(); void temporarilyStopAllModalSessions(); void beginModalSession(QWindow *widget); void endModalSession(QWindow *widget); + bool hasModalSession() const; void cleanupModalSessions(); void cancelWaitForMoreEvents(); diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index b0f2b6d940..84ffadea83 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -672,43 +672,9 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession() return currentModalSessionCached; } -static void setChildrenWorksWhenModal(QWindow *window, bool worksWhenModal) +bool QCocoaEventDispatcherPrivate::hasModalSession() const { - Q_UNUSED(window) - Q_UNUSED(worksWhenModal) - - // For NSPanels (but not NSWindows, sadly), we can set the flag - // worksWhenModal, so that they are active even when they are not modal. -/* - ### not ported - QList<QDialog *> dialogs = window->findChildren<QDialog *>(); - for (int i=0; i<dialogs.size(); ++i){ - NSWindow *window = qt_mac_window_for(dialogs[i]); - if (window && [window isKindOfClass:[NSPanel class]]) { - [static_cast<NSPanel *>(window) setWorksWhenModal:worksWhenModal]; - if (worksWhenModal && [window isVisible]){ - [window orderFront:window]; - } - } - } -*/ -} - -void QCocoaEventDispatcherPrivate::updateChildrenWorksWhenModal() -{ - // Make the dialog children of the window - // active. And make the dialog children of - // the previous modal dialog unactive again: - QMacAutoReleasePool pool; - int size = cocoaModalSessionStack.size(); - if (size > 0){ - if (QWindow *prevModal = cocoaModalSessionStack[size-1].window) - setChildrenWorksWhenModal(prevModal, true); - if (size > 1){ - if (QWindow *prevModal = cocoaModalSessionStack[size-2].window) - setChildrenWorksWhenModal(prevModal, false); - } - } + return !cocoaModalSessionStack.isEmpty(); } void QCocoaEventDispatcherPrivate::cleanupModalSessions() @@ -743,7 +709,6 @@ void QCocoaEventDispatcherPrivate::cleanupModalSessions() cocoaModalSessionStack.remove(i); } - updateChildrenWorksWhenModal(); cleanupModalSessionsNeeded = false; } @@ -764,7 +729,6 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) // stopped in cleanupModalSessions()). QCocoaModalSessionInfo info = {window, nullptr, nullptr}; cocoaModalSessionStack.push(info); - updateChildrenWorksWhenModal(); currentModalSessionCached = nullptr; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 0a913ef66e..fef72bc496 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -253,7 +253,6 @@ public: // for QNSView bool m_needsInvalidateShadow; - bool m_hasModalSession; bool m_frameStrutEventsEnabled; QRect m_exposedRect; int m_registerTouchCount; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 6bedbb556d..fc772181f0 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -153,7 +153,6 @@ QCocoaWindow::QCocoaWindow(QWindow *win, WId nativeHandle) , m_inSetStyleMask(false) , m_menubar(nullptr) , m_needsInvalidateShadow(false) - , m_hasModalSession(false) , m_frameStrutEventsEnabled(false) , m_registerTouchCount(0) , m_resizableTransientParent(false) @@ -304,13 +303,17 @@ void QCocoaWindow::setVisible(bool visible) { qCDebug(lcQpaWindow) << "QCocoaWindow::setVisible" << window() << visible; - m_inSetVisible = true; + QScopedValueRollback<bool> rollback(m_inSetVisible, true); QMacAutoReleasePool pool; QCocoaWindow *parentCocoaWindow = nullptr; if (window()->transientParent()) parentCocoaWindow = static_cast<QCocoaWindow *>(window()->transientParent()->handle()); + auto eventDispatcher = [] { + return static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(qApp->eventDispatcher())); + }; + if (visible) { // We need to recreate if the modality has changed as the style mask will need updating recreateWindowIfNeeded(); @@ -351,68 +354,46 @@ void QCocoaWindow::setVisible(bool visible) applyWindowState(window()->windowStates()); if (window()->windowState() != Qt::WindowMinimized) { - if ((window()->modality() == Qt::WindowModal - || window()->type() == Qt::Sheet) - && parentCocoaWindow) { - // show the window as a sheet + if (parentCocoaWindow && (window()->modality() == Qt::WindowModal || window()->type() == Qt::Sheet)) { + // Show the window as a sheet [parentCocoaWindow->nativeWindow() beginSheet:m_view.window completionHandler:nil]; - } else if (window()->modality() != Qt::NonModal) { - // show the window as application modal - QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher()); - Q_ASSERT(cocoaEventDispatcher); - QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher)); - cocoaEventDispatcherPrivate->beginModalSession(window()); - m_hasModalSession = true; - } else if ([m_view.window canBecomeKeyWindow]) { - QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher()); - QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = nullptr; - if (cocoaEventDispatcher) - cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher)); - - if (cocoaEventDispatcherPrivate && cocoaEventDispatcherPrivate->cocoaModalSessionStack.isEmpty()) - [m_view.window makeKeyAndOrderFront:nil]; - else - [m_view.window orderFront:nil]; + } else if (window()->modality() == Qt::ApplicationModal) { + // Show the window as application modal + eventDispatcher()->beginModalSession(window()); + } else if (m_view.window.canBecomeKeyWindow && !eventDispatcher()->hasModalSession()) { + [m_view.window makeKeyAndOrderFront:nil]; } else { [m_view.window orderFront:nil]; } - // We want the events to properly reach the popup, dialog, and tool - if ((window()->type() == Qt::Popup || window()->type() == Qt::Dialog || window()->type() == Qt::Tool) - && [m_view.window isKindOfClass:[NSPanel class]]) { - ((NSPanel *)m_view.window).worksWhenModal = YES; - if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) { - removeMonitor(); - NSEventMask eventMask = NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown - | NSEventMaskOtherMouseDown | NSEventMaskMouseMoved; - monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *e) { - const auto button = cocoaButton2QtButton(e); - const auto buttons = currentlyPressedMouseButtons(); - const auto eventType = cocoaEvent2QtMouseEvent(e); - const auto globalPoint = QCocoaScreen::mapFromNative(NSEvent.mouseLocation); - const auto localPoint = window()->mapFromGlobal(globalPoint.toPoint()); - QWindowSystemInterface::handleMouseEvent(window(), localPoint, globalPoint, buttons, button, eventType); - }]; - } + // Close popup when clicking outside it + if (window()->type() == Qt::Popup && !(parentCocoaWindow && window()->transientParent()->isActive())) { + removeMonitor(); + NSEventMask eventMask = NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown + | NSEventMaskOtherMouseDown | NSEventMaskMouseMoved; + monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *e) { + const auto button = cocoaButton2QtButton(e); + const auto buttons = currentlyPressedMouseButtons(); + const auto eventType = cocoaEvent2QtMouseEvent(e); + const auto globalPoint = QCocoaScreen::mapFromNative(NSEvent.mouseLocation); + const auto localPoint = window()->mapFromGlobal(globalPoint.toPoint()); + QWindowSystemInterface::handleMouseEvent(window(), localPoint, globalPoint, buttons, button, eventType); + }]; } } } + // In some cases, e.g. QDockWidget, the content view is hidden before moving to its own // Cocoa window, and then shown again. Therefore, we test for the view being hidden even // if it's attached to an NSWindow. if ([m_view isHidden]) [m_view setHidden:NO]; + } else { - // qDebug() << "close" << this; - QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher()); - QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = nullptr; - if (cocoaEventDispatcher) - cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher)); + // Window not visible, hide it if (isContentView()) { - if (m_hasModalSession) { - if (cocoaEventDispatcherPrivate) - cocoaEventDispatcherPrivate->endModalSession(window()); - m_hasModalSession = false; + if (eventDispatcher()->hasModalSession()) { + eventDispatcher()->endModalSession(window()); } else { if ([m_view.window isSheet]) { Q_ASSERT_X(parentCocoaWindow, "QCocoaWindow", "Window modal dialog has no transient parent."); @@ -422,8 +403,7 @@ void QCocoaWindow::setVisible(bool visible) [m_view.window orderOut:nil]; - if (m_view.window == [NSApp keyWindow] - && !(cocoaEventDispatcherPrivate && cocoaEventDispatcherPrivate->currentModalSession())) { + if (m_view.window == [NSApp keyWindow] && !eventDispatcher()->hasModalSession()) { // Probably because we call runModalSession: outside [NSApp run] in QCocoaEventDispatcher // (e.g., when show()-ing a modal QDialog instead of exec()-ing it), it can happen that // the current NSWindow is still key after being ordered out. Then, after checking we @@ -435,6 +415,7 @@ void QCocoaWindow::setVisible(bool visible) } else { [m_view setHidden:YES]; } + removeMonitor(); if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) @@ -448,8 +429,6 @@ void QCocoaWindow::setVisible(bool visible) nativeParentWindow.styleMask |= NSWindowStyleMaskResizable; } } - - m_inSetVisible = false; } NSInteger QCocoaWindow::windowLevel(Qt::WindowFlags flags) diff --git a/src/plugins/platforms/cocoa/qnswindow.h b/src/plugins/platforms/cocoa/qnswindow.h index 64f1ed0802..dcbcd58901 100644 --- a/src/plugins/platforms/cocoa/qnswindow.h +++ b/src/plugins/platforms/cocoa/qnswindow.h @@ -62,6 +62,7 @@ QT_FORWARD_DECLARE_CLASS(QCocoaWindow) @protocol QNSWindowProtocol @optional - (BOOL)canBecomeKeyWindow; +- (BOOL)worksWhenModal; - (void)sendEvent:(NSEvent*)theEvent; - (void)closeAndRelease; - (void)dealloc; diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index c17ad47aba..28a9fa8607 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -177,6 +177,19 @@ static bool isMouseEvent(NSEvent *ev) return canBecomeMain; } +- (BOOL)worksWhenModal +{ + if ([self isKindOfClass:[QNSPanel class]]) { + if (QCocoaWindow *pw = self.platformWindow) { + Qt::WindowType type = pw->window()->type(); + if (type == Qt::Popup || type == Qt::Dialog || type == Qt::Tool) + return YES; + } + } + + return qt_objcDynamicSuper(); +} + - (BOOL)isOpaque { return self.platformWindow ? |