diff options
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaglcontext.mm | 11 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 52 |
2 files changed, 43 insertions, 20 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index 7b124ea517..ba7d12ce30 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -197,8 +197,15 @@ NSOpenGLPixelFormat *QCocoaGLContext::pixelFormatForSurfaceFormat(const QSurface attrs << NSOpenGLPFAStencilSize << format.stencilBufferSize(); if (format.alphaBufferSize() > 0) attrs << NSOpenGLPFAAlphaSize << format.alphaBufferSize(); - if (format.redBufferSize() > 0 && format.greenBufferSize() > 0 && format.blueBufferSize() > 0) { - const int colorSize = format.redBufferSize() + format.greenBufferSize() + format.blueBufferSize(); + + auto rbz = format.redBufferSize(); + auto gbz = format.greenBufferSize(); + auto bbz = format.blueBufferSize(); + if (rbz > 0 || gbz > 0 || bbz > 0) { + auto fallbackSize = qMax(rbz, qMax(gbz, bbz)); + auto colorSize = (rbz > 0 ? rbz : fallbackSize) + + (gbz > 0 ? gbz : fallbackSize) + + (bbz > 0 ? bbz : fallbackSize); attrs << NSOpenGLPFAColorSize << colorSize << NSOpenGLPFAMinimumPolicy; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 8f3c192745..0c7ec7f736 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1544,12 +1544,6 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel) Qt::WindowType type = window()->type(); Qt::WindowFlags flags = window()->flags(); - // Note: The macOS window manager has a bug, where if a screen is rotated, it will not allow - // a window to be created within the area of the screen that has a Y coordinate (I quadrant) - // higher than the height of the screen in its non-rotated state, unless the window is - // created with the NSWindowStyleMaskBorderless style mask. - NSWindowStyleMask styleMask = windowStyleMask(flags); - QRect rect = geometry(); QScreen *targetScreen = nullptr; @@ -1560,35 +1554,57 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel) } } + NSWindowStyleMask styleMask = windowStyleMask(flags); + if (!targetScreen) { qCWarning(lcQpaWindow) << "Window position" << rect << "outside any known screen, using primary screen"; targetScreen = QGuiApplication::primaryScreen(); - // AppKit will only reposition a window that's outside the target screen area if - // the window has a title bar. If left out, the window ends up with no screen. - // The style mask will be corrected to the original style mask in setWindowFlags. - styleMask |= NSWindowStyleMaskTitled; + // Unless the window is created as borderless AppKit won't find a position and + // screen that's close to the requested invalid position, and will always place + // the window on the primary screen. + styleMask = NSWindowStyleMaskBorderless; } 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 contentRect = QCocoaScreen::mapToNative(rect, targetCocoaScreen); + + if (targetScreen->primaryOrientation() == Qt::PortraitOrientation) { + // The macOS window manager has a bug, where if a screen is rotated, it will not allow + // a window to be created within the area of the screen that has a Y coordinate (I quadrant) + // higher than the height of the screen in its non-rotated state (including a magic padding + // of 24 points), unless the window is created with the NSWindowStyleMaskBorderless style mask. + if (styleMask && (contentRect.origin.y + 24 > targetScreen->geometry().width())) { + qCDebug(lcQpaWindow) << "Window positioned on portrait screen." + << "Adjusting style mask during creation"; + styleMask = NSWindowStyleMaskBorderless; + } + } // Create NSWindow Class windowClass = shouldBePanel ? [QNSPanel class] : [QNSWindow class]; - QCocoaNSWindow *nsWindow = [[windowClass alloc] initWithContentRect:frame + QCocoaNSWindow *nsWindow = [[windowClass alloc] initWithContentRect:contentRect + // Mask will be updated in setWindowFlags if not the final mask styleMask:styleMask // 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 = QCocoaScreen::get(nsWindow.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 (targetScreen != window()->screen()) { + if (resultingScreen->screen() != window()->screen()) { QWindowSystemInterface::handleWindowScreenChanged< - QWindowSystemInterface::SynchronousDelivery>(window(), targetScreen); + QWindowSystemInterface::SynchronousDelivery>(window(), resultingScreen->screen()); } static QSharedPointer<QNSWindowDelegate> sharedDelegate([[QNSWindowDelegate alloc] init], |