summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/qguiapplication.cpp16
-rw-r--r--src/gui/kernel/qguiapplication_p.h8
-rw-r--r--src/gui/kernel/qplatformscreen.cpp24
-rw-r--r--src/gui/kernel/qplatformscreen.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.mm20
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 &region, 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 -----------------------