summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoawindow.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoawindow.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm45
1 files changed, 28 insertions, 17 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 298d11fe08..0d7eab9a94 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1208,23 +1208,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 = QCocoaIntegration::instance()->screenForNSScreen(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
+ // the screen was just reconfigured, which still results in AppKit sending an
+ // NSWindowDidChangeScreenNotification, 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 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();
}
}