summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.h8
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.mm51
2 files changed, 43 insertions, 16 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h
index 60243b79be..7ec9a2b5af 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.h
+++ b/src/plugins/platforms/cocoa/qcocoascreen.h
@@ -99,18 +99,18 @@ private:
static void add(CGDirectDisplayID displayId);
void remove();
- CGDirectDisplayID m_displayId = 0;
+ CGDirectDisplayID m_displayId = kCGNullDirectDisplay;
QRect m_geometry;
QRect m_availableGeometry;
QDpi m_logicalDpi;
- qreal m_refreshRate;
- int m_depth;
+ qreal m_refreshRate = 0;
+ int m_depth = 0;
QString m_name;
QImage::Format m_format;
QSizeF m_physicalSize;
QCocoaCursor *m_cursor;
- qreal m_devicePixelRatio;
+ qreal m_devicePixelRatio = 0;
CVDisplayLinkRef m_displayLink = nullptr;
dispatch_source_t m_displayLinkSource = nullptr;
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm
index 392099d083..40273bac84 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.mm
+++ b/src/plugins/platforms/cocoa/qcocoascreen.mm
@@ -54,6 +54,23 @@
QT_BEGIN_NAMESPACE
+namespace CoreGraphics {
+ Q_NAMESPACE
+ enum DisplayChange {
+ Moved = kCGDisplayMovedFlag,
+ SetMain = kCGDisplaySetMainFlag,
+ SetMode = kCGDisplaySetModeFlag,
+ Added = kCGDisplayAddFlag,
+ Removed = kCGDisplayRemoveFlag,
+ Enabled = kCGDisplayEnabledFlag,
+ Disabled = kCGDisplayDisabledFlag,
+ Mirrored = kCGDisplayMirrorFlag,
+ UnMirrored = kCGDisplayUnMirrorFlag,
+ DesktopShapeChanged = kCGDisplayDesktopShapeChangedFlag
+ };
+ Q_ENUM_NS(DisplayChange)
+}
+
void QCocoaScreen::initializeScreens()
{
uint32_t displayCount = 0;
@@ -73,6 +90,10 @@ void QCocoaScreen::initializeScreens()
Q_UNUSED(userInfo);
+ qCDebug(lcQpaScreen).verbosity(0).nospace() << "Display reconfiguration"
+ << " (" << QFlags<CoreGraphics::DisplayChange>(flags) << ")"
+ << " for displayId=" << displayId;
+
QCocoaScreen *cocoaScreen = QCocoaScreen::get(displayId);
if ((flags & kCGDisplayAddFlag) || !cocoaScreen) {
@@ -93,22 +114,24 @@ void QCocoaScreen::initializeScreens()
mainDisplay->updateProperties();
qCInfo(lcQpaScreen) << "Primary screen changed to" << mainDisplay;
QWindowSystemInterface::handlePrimaryScreenChanged(mainDisplay);
+ if (cocoaScreen == mainDisplay)
+ return; // Already reconfigured
}
- if (cocoaScreen == mainDisplay)
- return; // Already reconfigured
-
cocoaScreen->updateProperties();
- qCInfo(lcQpaScreen) << "Reconfigured" << cocoaScreen;
+ qCInfo(lcQpaScreen).nospace() << "Reconfigured " <<
+ (primaryScreen() == cocoaScreen ? "primary " : "")
+ << cocoaScreen;
}
}, nullptr);
}
void QCocoaScreen::add(CGDirectDisplayID displayId)
{
+ const bool isPrimary = CGDisplayIsMain(displayId);
QCocoaScreen *cocoaScreen = new QCocoaScreen(displayId);
- qCInfo(lcQpaScreen) << "Adding" << cocoaScreen;
- QWindowSystemInterface::handleScreenAdded(cocoaScreen, CGDisplayIsMain(displayId));
+ qCInfo(lcQpaScreen).nospace() << "Adding " << (isPrimary ? "new primary " : "") << cocoaScreen;
+ QWindowSystemInterface::handleScreenAdded(cocoaScreen, isPrimary);
}
QCocoaScreen::QCocoaScreen(CGDirectDisplayID displayId)
@@ -127,7 +150,7 @@ void QCocoaScreen::cleanupScreens()
void QCocoaScreen::remove()
{
- m_displayId = 0; // Prevent stale references during removal
+ m_displayId = kCGNullDirectDisplay; // Prevent stale references during removal
// This may result in the application responding to QGuiApplication::screenRemoved
// by moving the window to another screen, either by setGeometry, or by setScreen.
@@ -140,6 +163,7 @@ void QCocoaScreen::remove()
// QCocoaWindow::windowDidChangeScreen. At that point the window will appear to have
// already changed its screen, but that's only true if comparing the Qt screens,
// not when comparing the NSScreens.
+ qCInfo(lcQpaScreen).nospace() << "Removing " << (primaryScreen() == this ? "current primary " : "") << this;
QWindowSystemInterface::handleScreenRemoved(this);
}
@@ -552,10 +576,10 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height)
*/
QCocoaScreen *QCocoaScreen::primaryScreen()
{
- auto screen = static_cast<QCocoaScreen *>(QGuiApplication::primaryScreen()->handle());
- Q_ASSERT_X(screen == get(CGMainDisplayID()), "QCocoaScreen",
- "The application's primary screen should always be in sync with the main display");
- return screen;
+ // Note: The primary screen that Qt knows about may not match the current CGMainDisplayID()
+ // if macOS has not yet been able to inform us that the main display has changed, but we
+ // will update the primary screen accordingly once the reconfiguration callback comes in.
+ return static_cast<QCocoaScreen *>(QGuiApplication::primaryScreen()->handle());
}
QList<QPlatformScreen*> QCocoaScreen::virtualSiblings() const
@@ -597,7 +621,7 @@ NSScreen *QCocoaScreen::nativeScreen() const
QCFType<CFUUIDRef> uuid = CGDisplayCreateUUIDFromDisplayID(m_displayId);
for (NSScreen *screen in [NSScreen screens]) {
- if (CGDisplayCreateUUIDFromDisplayID(screen.qt_displayId) == uuid)
+ if (QCFType<CFUUIDRef>(CGDisplayCreateUUIDFromDisplayID(screen.qt_displayId)) == uuid)
return screen;
}
@@ -639,6 +663,7 @@ QDebug operator<<(QDebug debug, const QCocoaScreen *screen)
debug << ", geometry=" << screen->geometry();
debug << ", dpr=" << screen->devicePixelRatio();
debug << ", name=" << screen->name();
+ debug << ", displayId=" << screen->m_displayId;
debug << ", native=" << screen->nativeScreen();
}
debug << ')';
@@ -646,6 +671,8 @@ QDebug operator<<(QDebug debug, const QCocoaScreen *screen)
}
#endif // !QT_NO_DEBUG_STREAM
+#include "qcocoascreen.moc"
+
QT_END_NAMESPACE
@implementation NSScreen (QtExtras)