diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 16 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication_p.h | 8 | ||||
-rw-r--r-- | src/gui/kernel/qplatformscreen.cpp | 24 | ||||
-rw-r--r-- | src/gui/kernel/qplatformscreen.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.mm | 10 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoascreen.mm | 20 |
6 files changed, 53 insertions, 27 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 712699ddc9..40d82d9269 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1864,19 +1864,19 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv static_cast<QWindowSystemInterfacePrivate::CloseEvent *>(e)); break; case QWindowSystemInterfacePrivate::ScreenOrientation: - QGuiApplicationPrivate::reportScreenOrientationChange( + QGuiApplicationPrivate::processScreenOrientationChange( static_cast<QWindowSystemInterfacePrivate::ScreenOrientationEvent *>(e)); break; case QWindowSystemInterfacePrivate::ScreenGeometry: - QGuiApplicationPrivate::reportGeometryChange( + QGuiApplicationPrivate::processScreenGeometryChange( static_cast<QWindowSystemInterfacePrivate::ScreenGeometryEvent *>(e)); break; case QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInch: - QGuiApplicationPrivate::reportLogicalDotsPerInchChange( + QGuiApplicationPrivate::processScreenLogicalDotsPerInchChange( static_cast<QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *>(e)); break; case QWindowSystemInterfacePrivate::ScreenRefreshRate: - QGuiApplicationPrivate::reportRefreshRateChange( + QGuiApplicationPrivate::processScreenRefreshRateChange( static_cast<QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *>(e)); break; case QWindowSystemInterfacePrivate::ThemeChange: @@ -2907,7 +2907,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To } } -void QGuiApplicationPrivate::reportScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e) +void QGuiApplicationPrivate::processScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e) { // This operation only makes sense after the QGuiApplication constructor runs if (QCoreApplication::startingUp()) @@ -2944,7 +2944,7 @@ void QGuiApplicationPrivate::reportScreenOrientationChange(QScreen *s) QCoreApplication::sendEvent(QCoreApplication::instance(), &event); } -void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e) +void QGuiApplicationPrivate::processScreenGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e) { // This operation only makes sense after the QGuiApplication constructor runs if (QCoreApplication::startingUp()) @@ -2987,7 +2987,7 @@ void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate: } } -void QGuiApplicationPrivate::reportLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e) +void QGuiApplicationPrivate::processScreenLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e) { // This operation only makes sense after the QGuiApplication constructor runs if (QCoreApplication::startingUp()) @@ -3002,7 +3002,7 @@ void QGuiApplicationPrivate::reportLogicalDotsPerInchChange(QWindowSystemInterfa emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch()); } -void QGuiApplicationPrivate::reportRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e) +void QGuiApplicationPrivate::processScreenRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e) { // This operation only makes sense after the QGuiApplication constructor runs if (QCoreApplication::startingUp()) diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 145e764244..79c1a1c820 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -139,10 +139,10 @@ public: static void updateFilteredScreenOrientation(QScreen *screen); static void reportScreenOrientationChange(QScreen *screen); - static void reportScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e); - static void reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e); - static void reportLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e); - static void reportRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e); + static void processScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e); + static void processScreenGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e); + static void processScreenLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e); + static void processScreenRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e); static void processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce); static void processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e); diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp index e22037c1e9..358ff16930 100644 --- a/src/gui/kernel/qplatformscreen.cpp +++ b/src/gui/kernel/qplatformscreen.cpp @@ -104,6 +104,20 @@ QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const } /*! + Return all windows residing on this screen. +*/ +QWindowList QPlatformScreen::windows() const +{ + QWindowList windows; + for (QWindow *window : QGuiApplication::allWindows()) { + if (platformScreenForWindow(window) != this) + continue; + windows.append(window); + } + return windows; +} + +/*! Find the sibling screen corresponding to \a globalPos. Returns this screen if no suitable screen is found at the position. @@ -369,25 +383,17 @@ QPlatformCursor *QPlatformScreen::cursor() const */ void QPlatformScreen::resizeMaximizedWindows() { - QList<QWindow*> windows = QGuiApplication::allWindows(); - // 'screen()' still has the old geometry info while 'this' has the new geometry info const QRect oldGeometry = screen()->geometry(); const QRect oldAvailableGeometry = screen()->availableGeometry(); const QRect newGeometry = deviceIndependentGeometry(); const QRect newAvailableGeometry = QHighDpi::fromNative(availableGeometry(), QHighDpiScaling::factor(this), newGeometry.topLeft()); - // make sure maximized and fullscreen windows are updated - for (int i = 0; i < windows.size(); ++i) { - QWindow *w = windows.at(i); - + for (QWindow *w : windows()) { // Skip non-platform windows, e.g., offscreen windows. if (!w->handle()) continue; - if (platformScreenForWindow(w) != this) - continue; - if (w->windowState() & Qt::WindowMaximized || w->geometry() == oldAvailableGeometry) w->setGeometry(newAvailableGeometry); else if (w->windowState() & Qt::WindowFullScreen || w->geometry() == oldGeometry) diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h index 97fe3fed03..e9d64c8a29 100644 --- a/src/gui/kernel/qplatformscreen.h +++ b/src/gui/kernel/qplatformscreen.h @@ -123,6 +123,8 @@ public: virtual void setOrientationUpdateMask(Qt::ScreenOrientations mask); virtual QWindow *topLevelAt(const QPoint &point) const; + QWindowList windows() const; + virtual QList<QPlatformScreen *> virtualSiblings() const; const QPlatformScreen *screenForPosition(const QPoint &point) const; diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 332683f63e..13b4e2ecd1 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -159,13 +159,13 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo const qreal devicePixelRatio = m_image.devicePixelRatio(); - // If the flushed window is a content view, and not in unified toolbar mode, - // and is fully opaque, we can get away with copying the backingstore instead - // of blending. + // If the flushed window is a content view, and we're filling the drawn area + // completely, or it doesn't have a window background we need to preserve, + // we can get away with copying instead of blending the backing store. QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle()); const NSCompositingOperation compositingOperation = cocoaWindow->isContentView() - && cocoaWindow->isOpaque() && !windowHasUnifiedToolbar() ? - NSCompositingOperationCopy : NSCompositingOperationSourceOver; + && (cocoaWindow->isOpaque() || view.window.backgroundColor == NSColor.clearColor) + ? NSCompositingOperationCopy : NSCompositingOperationSourceOver; #ifdef QT_DEBUG static bool debugBackingStoreFlush = [[NSUserDefaults standardUserDefaults] diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index c15fea837f..f82ef202b1 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -147,7 +147,9 @@ void QCocoaScreen::updateProperties() m_name = displayName(dpy); - if (m_geometry != previousGeometry || m_availableGeometry != previousAvailableGeometry) + const bool didChangeGeometry = m_geometry != previousGeometry || m_availableGeometry != previousAvailableGeometry; + + if (didChangeGeometry) QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); if (m_logicalDpi != previousLogicalDpi) QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), m_logicalDpi.first, m_logicalDpi.second); @@ -155,6 +157,22 @@ void QCocoaScreen::updateProperties() QWindowSystemInterface::handleScreenRefreshRateChange(screen(), m_refreshRate); qCDebug(lcQpaScreen) << "Updated properties for" << this; + + if (didChangeGeometry) { + // When a screen changes its geometry, AppKit will send us a NSWindowDidMoveNotification + // for each window, resulting in calls to handleGeometryChange(), but this happens before + // the NSApplicationDidChangeScreenParametersNotification, so when we map the new geometry + // (which is correct at that point) to the screen using QCocoaScreen::mapFromNative(), we + // end up using the stale screen geometry, and the new window geometry we report is wrong. + // To make sure we finally report the correct window geometry, we need to do another pass + // of geometry reporting, now that the screen properties have been updates. FIXME: Ideally + // this would be solved by not caching the screen properties in QCocoaScreen, but that + // requires more research. + for (QWindow *window : windows()) { + if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow*>(window->handle())) + cocoaWindow->handleGeometryChange(); + } + } } // ----------------------- Display link ----------------------- |