diff options
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoawindow.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 298d11fe08..67b0cbdfe9 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1086,9 +1086,11 @@ void QCocoaWindow::setEmbeddedInForeignView() void QCocoaWindow::viewDidChangeFrame() { - if (isContentView()) - return; // Handled below - + // Note: When the view is the content view, it would seem redundant + // to deliver geometry changes both from windowDidResize and this + // callback, but in some cases such as when macOS native tabbed + // windows are enabled we may end up with the wrong geometry in + // the initial windowDidResize callback when a new tab is created. handleGeometryChange(); } @@ -1208,23 +1210,34 @@ void QCocoaWindow::windowDidChangeScreen() if (!window()) return; - const bool wasRunningDisplayLink = static_cast<QCocoaScreen *>(screen())->isRunningDisplayLink(); - - if (QCocoaScreen *newScreen = QCocoaIntegration::instance()->screenForNSScreen(m_view.window.screen)) { - if (newScreen == screen()) { - // Screen properties have changed. Will be handled by - // NSApplicationDidChangeScreenParametersNotification - // in QCocoaIntegration::updateScreens(). - return; - } - - qCDebug(lcQpaWindow) << window() << "moved to" << newScreen; - QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen()); - - if (hasPendingUpdateRequest() && wasRunningDisplayLink) - requestUpdate(); // Restart display-link on new screen - } else { - qCWarning(lcQpaWindow) << "Failed to get QCocoaScreen for" << m_view.window.screen; + // Note: When a window is resized to 0x0 Cocoa will report the window's screen as nil + auto *currentScreen = QCocoaScreen::get(m_view.window.screen); + auto *previousScreen = static_cast<QCocoaScreen*>(screen()); + + Q_ASSERT_X(!m_view.window.screen || currentScreen, + "QCocoaWindow", "Failed to get QCocoaScreen for NSScreen"); + + // Note: The previous screen may be the same as the current screen, either because + // a) the screen was just reconfigured, which still results in AppKit sending an + // NSWindowDidChangeScreenNotification, b) because the previous screen was removed, + // and we ended up calling QWindow::setScreen to move the window, which doesn't + // actually move the window to the new screen, or c) because we've delivered the + // screen change to the top level window, which will make all the child windows + // of that window report the new screen when requested via QWindow::screen(). + // We still need to deliver the screen change in all these cases, as the + // device-pixel ratio may have changed, and needs to be delivered to all + // windows, both top level and child windows. + + qCDebug(lcQpaWindow) << "Screen changed for" << window() << "from" << previousScreen << "to" << currentScreen; + QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>( + window(), currentScreen ? currentScreen->screen() : nullptr); + + if (currentScreen && hasPendingUpdateRequest()) { + // Restart display-link on new screen. We need to do this unconditionally, + // since we can't rely on the previousScreen reflecting whether or not the + // window actually moved from one screen to another, or just stayed on the + // same screen. + currentScreen->requestUpdate(); } } |