macOS: Don't assume NSWindows will be created on the screen we request

The user may have assigned the application to start up on a specific
display, in which case the window's screen is nil after creation, and
the resulting screen will be delivered as a normal screen change once
the window is ordered on screen.

Fixes: QTBUG-77154
Change-Id: Idade6d833e31654db239243f2430166b5d86eca2
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
bb10
Tor Arne Vestbø 2019-07-30 15:41:57 +02:00
parent bd8ef7fe24
commit a34b0855f1
1 changed files with 14 additions and 7 deletions

View File

@ -1569,8 +1569,8 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
}
rect.translate(-targetScreen->geometry().topLeft());
QCocoaScreen *cocoaScreen = static_cast<QCocoaScreen *>(targetScreen->handle());
NSRect frame = QCocoaScreen::mapToNative(rect, cocoaScreen);
auto *targetCocoaScreen = static_cast<QCocoaScreen *>(targetScreen->handle());
NSRect frame = QCocoaScreen::mapToNative(rect, targetCocoaScreen);
// Create NSWindow
Class windowClass = shouldBePanel ? [QNSPanel class] : [QNSWindow class];
@ -1579,15 +1579,22 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
// Deferring window creation breaks OpenGL (the GL context is
// set up before the window is shown and needs a proper window)
backing:NSBackingStoreBuffered defer:NO
screen:cocoaScreen->nativeScreen()
screen:targetCocoaScreen->nativeScreen()
platformWindow:this];
Q_ASSERT_X(nsWindow.screen == cocoaScreen->nativeScreen(), "QCocoaWindow",
"Resulting NSScreen should match the requested NSScreen");
// The resulting screen can be different from the screen requested if
// for example the application has been assigned to a specific display.
auto resultingScreen = QCocoaIntegration::instance()->screenForNSScreen(nsWindow.screen);
if (targetScreen != window()->screen()) {
// But may not always be resolved at this point, in which case we fall back
// to the target screen. The real screen will be delivered as a screen change
// when resolved as part of ordering the window on screen.
if (!resultingScreen)
resultingScreen = targetCocoaScreen;
if (resultingScreen->screen() != window()->screen()) {
QWindowSystemInterface::handleWindowScreenChanged<
QWindowSystemInterface::SynchronousDelivery>(window(), targetScreen);
QWindowSystemInterface::SynchronousDelivery>(window(), resultingScreen->screen());
}
static QSharedPointer<QNSWindowDelegate> sharedDelegate([[QNSWindowDelegate alloc] init],