diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2016-10-13 14:49:01 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2016-10-27 13:08:24 +0000 |
commit | 7f507c16202003e834863b8f26213c5e1c06fd0e (patch) | |
tree | 8702dbe9524ada5b6617714e4f297fe77e25a129 /src/plugins/platforms/cocoa/qnsview.mm | |
parent | d04207342ea4d22e42257eb0adc1048fd2e068b4 (diff) |
macOS: Decouple NSWindow notifications and delegate callbacks from QNSView
The logic for handling NSWindow events was split partly between QNSView
observing notifications, and QNSWindowDelegate implementing direct delegate
callbacks. The logic of how to handle the events was then split further
by sometimes handling the event in the delegate callback or notification
handler, and sometimes forwarding the event to QCocoaWindow.
We now handle most events via notifications, and propagate these directly
to QCocoaWindow, so that all the logic is in one place. This improves the
situation for foreign windows, since we're not relying on having a QNSView,
or being able to inject our QNSWindowDelegate.
To keep code duplication to a minimum and risking missing a notification
in the forwarding logic, the logic is based on QMetatType and QMetaMethod
tags, so that the notifications are declared in the header file, along
with the handler function.
Change-Id: I2fb6372010048a8a1f6e4426b988a3f6f5abdbab
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa/qnsview.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 88 |
1 files changed, 14 insertions, 74 deletions
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index dfdc3facb4..504db06900 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -281,22 +281,6 @@ static bool _q_dontOverrideCtrlLMB = false; m_backingStore = Q_NULLPTR; } -- (void)viewWillMoveToWindow:(NSWindow *)newWindow -{ - // ### Merge "normal" window code path with this one for 5.1. - if (!(m_platformWindow->window()->type() & Qt::SubWindow)) - return; - - if (newWindow) { - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(windowNotification:) - name:nil // Get all notifications - object:newWindow]; - } - if ([self window]) - [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[self window]]; -} - - (QWindow *)topLevelWindow { QWindow *focusWindow = m_platformWindow->window(); @@ -395,64 +379,6 @@ static bool _q_dontOverrideCtrlLMB = false; m_platformWindow->setSynchedWindowStateFromWindow(); } -- (void)windowNotification : (NSNotification *) windowNotification -{ - //qDebug() << "windowNotification" << QString::fromNSString([windowNotification name]); - - NSString *notificationName = [windowNotification name]; - if (notificationName == NSWindowDidBecomeKeyNotification) { - if (!m_platformWindow->windowIsPopupType() && !m_isMenuView) - QWindowSystemInterface::handleWindowActivated(m_platformWindow->window()); - } else if (notificationName == NSWindowDidResignKeyNotification) { - // key window will be non-nil if another window became key... do not - // set the active window to zero here, the new key window's - // NSWindowDidBecomeKeyNotification hander will change the active window - NSWindow *keyWindow = [NSApp keyWindow]; - if (!keyWindow || keyWindow == windowNotification.object) { - // no new key window, go ahead and set the active window to zero - if (!m_platformWindow->windowIsPopupType() && !m_isMenuView) - QWindowSystemInterface::handleWindowActivated(0); - } - } else if (notificationName == NSWindowDidMiniaturizeNotification - || notificationName == NSWindowDidDeminiaturizeNotification) { - Qt::WindowState newState = notificationName == NSWindowDidMiniaturizeNotification ? - Qt::WindowMinimized : Qt::WindowNoState; - [self notifyWindowStateChanged:newState]; - } else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) { - m_platformWindow->obscureWindow(); - } else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) { - m_platformWindow->exposeWindow(); - } else if ([notificationName isEqualToString:NSWindowDidChangeOcclusionStateNotification]) { - // Several unit tests expect paint and/or expose events for windows that are - // sometimes (unpredictably) occluded and some unit tests depend on QWindow::isExposed - - // don't send Expose/Obscure events when running under QTestLib. - static const bool onTestLib = qt_mac_resolveOption(false, "QT_QTESTLIB_RUNNING"); - if (!onTestLib) { - if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible) { - m_platformWindow->exposeWindow(); - } else { - // Send Obscure events on window occlusion to stop animations. - m_platformWindow->obscureWindow(); - } - } - } else if (notificationName == NSWindowDidChangeScreenNotification) { - if (m_platformWindow->window()) { - NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen]; - if (screenIndex != NSNotFound) { - QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex); - if (cocoaScreen) - QWindowSystemInterface::handleWindowScreenChanged(m_platformWindow->window(), cocoaScreen->screen()); - m_platformWindow->updateExposedGeometry(); - } - } - } else if (notificationName == NSWindowDidEnterFullScreenNotification - || notificationName == NSWindowDidExitFullScreenNotification) { - Qt::WindowState newState = notificationName == NSWindowDidEnterFullScreenNotification ? - Qt::WindowFullScreen : Qt::WindowNoState; - [self notifyWindowStateChanged:newState]; - } -} - - (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification { Q_UNUSED(textInputContextKeyboardSelectionDidChangeNotification) @@ -2219,3 +2145,17 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin } @end + +@implementation QT_MANGLE_NAMESPACE(QNSView) (QtExtras) + +- (QCocoaWindow*)platformWindow +{ + return m_platformWindow.data();; +} + +- (BOOL)isMenuView +{ + return m_isMenuView; +} + +@end |