diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2014-07-28 15:37:05 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2014-09-10 14:31:35 +0200 |
commit | 2368e62f32e39abdad54260fa4a7b1b6018e5b04 (patch) | |
tree | ee8a37e8384418b3d8d99e2d703d4d8e59a4bf7d /src | |
parent | 2d2dc976d83b7a862af20f631657175f6a83790c (diff) |
qpa: Make screen geometry updates (full and available geometry) atomic
Updating the geometry and available geometry in two steps means that
QScreen will be in an inconsistent state when emitting the geometry
change signal, as the available geometry has not been updated yet.
Piggy-backing changes to the availableGeometry based on the virtual
geometry changing does not make sense, so we now tie geometry and
availableGeometry (and their size variants) to their own separate
geometryChanged and availableGeometryChanged signals.
Change-Id: Iee0ced642cbb91c470cb54bc507d2c0512482c13
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 52 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication_p.h | 1 | ||||
-rw-r--r-- | src/gui/kernel/qscreen.h | 5 | ||||
-rw-r--r-- | src/gui/kernel/qwindowsysteminterface.cpp | 11 | ||||
-rw-r--r-- | src/gui/kernel/qwindowsysteminterface.h | 3 | ||||
-rw-r--r-- | src/gui/kernel/qwindowsysteminterface_p.h | 11 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbscreen.cpp | 3 | ||||
-rw-r--r-- | src/plugins/platforms/android/qandroidplatformscreen.cpp | 5 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaintegration.mm | 3 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosscreen.mm | 28 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxscreen.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsscreen.cpp | 10 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.cpp | 3 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.cpp | 4 |
14 files changed, 54 insertions, 89 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 75311616a4..19f15d88bf 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1646,10 +1646,6 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv QGuiApplicationPrivate::reportGeometryChange( static_cast<QWindowSystemInterfacePrivate::ScreenGeometryEvent *>(e)); break; - case QWindowSystemInterfacePrivate::ScreenAvailableGeometry: - QGuiApplicationPrivate::reportAvailableGeometryChange( - static_cast<QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *>(e)); - break; case QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInch: QGuiApplicationPrivate::reportLogicalDotsPerInchChange( static_cast<QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *>(e)); @@ -2546,40 +2542,36 @@ void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate: return; QScreen *s = e->screen.data(); - s->d_func()->geometry = e->geometry; - Qt::ScreenOrientation primaryOrientation = s->primaryOrientation(); - s->d_func()->updatePrimaryOrientation(); + bool geometryChanged = e->geometry != s->d_func()->geometry; + s->d_func()->geometry = e->geometry; - emit s->geometryChanged(s->geometry()); - emit s->physicalSizeChanged(s->physicalSize()); - emit s->physicalDotsPerInchChanged(s->physicalDotsPerInch()); - emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch()); - foreach (QScreen* sibling, s->virtualSiblings()) - emit sibling->virtualGeometryChanged(sibling->virtualGeometry()); + bool availableGeometryChanged = e->availableGeometry != s->d_func()->availableGeometry; + s->d_func()->availableGeometry = e->availableGeometry; - if (s->primaryOrientation() != primaryOrientation) - emit s->primaryOrientationChanged(s->primaryOrientation()); + if (geometryChanged) { + Qt::ScreenOrientation primaryOrientation = s->primaryOrientation(); + s->d_func()->updatePrimaryOrientation(); - if (s->d_func()->orientation == Qt::PrimaryOrientation) - updateFilteredScreenOrientation(s); -} + emit s->geometryChanged(s->geometry()); + emit s->physicalSizeChanged(s->physicalSize()); + emit s->physicalDotsPerInchChanged(s->physicalDotsPerInch()); + emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch()); -void QGuiApplicationPrivate::reportAvailableGeometryChange( - QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e) -{ - // This operation only makes sense after the QGuiApplication constructor runs - if (QCoreApplication::startingUp()) - return; + if (s->primaryOrientation() != primaryOrientation) + emit s->primaryOrientationChanged(s->primaryOrientation()); - if (!e->screen) - return; + if (s->d_func()->orientation == Qt::PrimaryOrientation) + updateFilteredScreenOrientation(s); + } - QScreen *s = e->screen.data(); - s->d_func()->availableGeometry = e->availableGeometry; + if (availableGeometryChanged) + emit s->availableGeometryChanged(s->geometry()); - foreach (QScreen* sibling, s->virtualSiblings()) - emit sibling->virtualGeometryChanged(sibling->virtualGeometry()); + if (geometryChanged || availableGeometryChanged) { + foreach (QScreen* sibling, s->virtualSiblings()) + emit sibling->virtualGeometryChanged(sibling->virtualGeometry()); + } } void QGuiApplicationPrivate::reportLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e) diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 0fd4458083..d82abfe20a 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -137,7 +137,6 @@ public: static void reportScreenOrientationChange(QScreen *screen); static void reportScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e); static void reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e); - static void reportAvailableGeometryChange(QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e); static void reportLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e); static void reportRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e); static void processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce); diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h index 9e439f5a20..4ee48ad5ad 100644 --- a/src/gui/kernel/qscreen.h +++ b/src/gui/kernel/qscreen.h @@ -69,11 +69,11 @@ class Q_GUI_EXPORT QScreen : public QObject Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(int depth READ depth CONSTANT) Q_PROPERTY(QSize size READ size NOTIFY geometryChanged) - Q_PROPERTY(QSize availableSize READ availableSize NOTIFY virtualGeometryChanged) + Q_PROPERTY(QSize availableSize READ availableSize NOTIFY availableGeometryChanged) Q_PROPERTY(QSize virtualSize READ virtualSize NOTIFY virtualGeometryChanged) Q_PROPERTY(QSize availableVirtualSize READ availableVirtualSize NOTIFY virtualGeometryChanged) Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged) - Q_PROPERTY(QRect availableGeometry READ availableGeometry NOTIFY virtualGeometryChanged) + Q_PROPERTY(QRect availableGeometry READ availableGeometry NOTIFY availableGeometryChanged) Q_PROPERTY(QRect virtualGeometry READ virtualGeometry NOTIFY virtualGeometryChanged) Q_PROPERTY(QRect availableVirtualGeometry READ availableVirtualGeometry NOTIFY virtualGeometryChanged) Q_PROPERTY(QSizeF physicalSize READ physicalSize NOTIFY physicalSizeChanged) @@ -142,6 +142,7 @@ public: Q_SIGNALS: void geometryChanged(const QRect &geometry); + void availableGeometryChanged(const QRect &geometry); void physicalSizeChanged(const QSizeF &size); void physicalDotsPerInchChanged(qreal dpi); void logicalDotsPerInchChanged(qreal dpi); diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index b716e84a42..59766d0bb2 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -493,17 +493,10 @@ void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt:: QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } -void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry) +void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry, const QRect &availableGeometry) { QWindowSystemInterfacePrivate::ScreenGeometryEvent *e = - new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, geometry); - QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); -} - -void QWindowSystemInterface::handleScreenAvailableGeometryChange(QScreen *screen, const QRect &availableGeometry) -{ - QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e = - new QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent(screen, availableGeometry); + new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, geometry, availableGeometry); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 580f1f86fa..c681185c35 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -164,8 +164,7 @@ public: // Changes to the screen static void handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation newOrientation); - static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry); - static void handleScreenAvailableGeometryChange(QScreen *screen, const QRect &newAvailableGeometry); + static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry, const QRect &newAvailableGeometry); static void handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal newDpiX, qreal newDpiY); static void handleScreenRefreshRateChange(QScreen *screen, qreal newRefreshRate); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 89ca4064b2..87f40e2b04 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -279,17 +279,10 @@ public: class ScreenGeometryEvent : public WindowSystemEvent { public: - ScreenGeometryEvent(QScreen *s, const QRect &g) - : WindowSystemEvent(ScreenGeometry), screen(s), geometry(g) { } + ScreenGeometryEvent(QScreen *s, const QRect &g, const QRect &ag) + : WindowSystemEvent(ScreenGeometry), screen(s), geometry(g), availableGeometry(ag) { } QPointer<QScreen> screen; QRect geometry; - }; - - class ScreenAvailableGeometryEvent : public WindowSystemEvent { - public: - ScreenAvailableGeometryEvent(QScreen *s, const QRect &g) - : WindowSystemEvent(ScreenAvailableGeometry), screen(s), availableGeometry(g) { } - QPointer<QScreen> screen; QRect availableGeometry; }; diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp index a962a5eb59..f4fb41c5a7 100644 --- a/src/platformsupport/fbconvenience/qfbscreen.cpp +++ b/src/platformsupport/fbconvenience/qfbscreen.cpp @@ -171,8 +171,7 @@ void QFbScreen::setGeometry(const QRect &rect) mGeometry = rect; mScreenImage = new QImage(mGeometry.size(), mFormat); invalidateRectCache(); - QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry()); - QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry()); + QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry()); resizeMaximizedWindows(); } diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index 870d81688c..3746d79675 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -221,7 +221,7 @@ void QAndroidPlatformScreen::setPhysicalSize(const QSize &size) void QAndroidPlatformScreen::setSize(const QSize &size) { m_size = size; - QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry()); + QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry()); } void QAndroidPlatformScreen::setAvailableGeometry(const QRect &rect) @@ -233,8 +233,7 @@ void QAndroidPlatformScreen::setAvailableGeometry(const QRect &rect) QRect oldGeometry = m_availableGeometry; m_availableGeometry = rect; - QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry()); - QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry()); + QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry()); resizeMaximizedWindows(); if (oldGeometry.width() == 0 && oldGeometry.height() == 0 && rect.width() > 0 && rect.height() > 0) { diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 4be49ed68f..ebe58be155 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -137,10 +137,9 @@ void QCocoaScreen::updateGeometry() m_name = QString::fromUtf8([[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]); [deviceInfo release]; - QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry()); + QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), m_logicalDpi.first, m_logicalDpi.second); QWindowSystemInterface::handleScreenRefreshRateChange(screen(), m_refreshRate); - QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), availableGeometry()); } qreal QCocoaScreen::devicePixelRatio() const diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index f1184be1b4..eb3b7e3c44 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -238,30 +238,26 @@ QIOSScreen::~QIOSScreen() void QIOSScreen::updateProperties() { + QRect previousGeometry = m_geometry; + QRect previousAvailableGeometry = m_availableGeometry; + bool inPortrait = UIInterfaceOrientationIsPortrait(m_uiWindow.rootViewController.interfaceOrientation); - QRect geometry = inPortrait ? fromCGRect(m_uiScreen.bounds).toRect() + m_geometry = inPortrait ? fromCGRect(m_uiScreen.bounds).toRect() : QRect(m_uiScreen.bounds.origin.x, m_uiScreen.bounds.origin.y, m_uiScreen.bounds.size.height, m_uiScreen.bounds.size.width); - if (geometry != m_geometry) { - m_geometry = geometry; - - const qreal millimetersPerInch = 25.4; - m_physicalSize = QSizeF(m_geometry.size()) / m_unscaledDpi * millimetersPerInch; - - QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); - } - - QRect availableGeometry = geometry; + m_availableGeometry = m_geometry; CGSize applicationFrameSize = m_uiScreen.applicationFrame.size; - int statusBarHeight = geometry.height() - (inPortrait ? applicationFrameSize.height : applicationFrameSize.width); + int statusBarHeight = m_geometry.height() - (inPortrait ? applicationFrameSize.height : applicationFrameSize.width); + + m_availableGeometry.adjust(0, statusBarHeight, 0, 0); - availableGeometry.adjust(0, statusBarHeight, 0, 0); + if (m_geometry != previousGeometry || m_availableGeometry != previousAvailableGeometry) { + const qreal millimetersPerInch = 25.4; + m_physicalSize = QSizeF(m_geometry.size()) / m_unscaledDpi * millimetersPerInch; - if (availableGeometry != m_availableGeometry) { - m_availableGeometry = availableGeometry; - QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); + QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry, m_availableGeometry); } if (screen()) diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index 59dc84ebc8..d6e5574392 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -445,7 +445,7 @@ void QQnxScreen::setRotation(int rotation) // Rotating only the primary screen is what we had in the navigator event handler before refactoring if (m_primaryScreen) { QWindowSystemInterface::handleScreenOrientationChange(screen(), orientation()); - QWindowSystemInterface::handleScreenGeometryChange(screen(), m_currentGeometry); + QWindowSystemInterface::handleScreenGeometryChange(screen(), m_currentGeometry, availableGeometry()); } // Flush everything, so that the windows rotations are applied properly. @@ -705,7 +705,7 @@ void QQnxScreen::keyboardHeightChanged(int height) m_keyboardHeight = height; - QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), availableGeometry()); + QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); } void QQnxScreen::addOverlayWindow(screen_window_t window) diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index f491b51aa8..8d8505ea05 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -346,15 +346,11 @@ void QWindowsScreen::handleChanges(const QWindowsScreenData &newData) { m_data.physicalSizeMM = newData.physicalSizeMM; - if (m_data.geometry != newData.geometry) { + if (m_data.geometry != newData.geometry || m_data.availableGeometry != newData.availableGeometry) { m_data.geometry = newData.geometry; - QWindowSystemInterface::handleScreenGeometryChange(screen(), - newData.geometry); - } - if (m_data.availableGeometry != newData.availableGeometry) { m_data.availableGeometry = newData.availableGeometry; - QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), - newData.availableGeometry); + QWindowSystemInterface::handleScreenGeometryChange(screen(), + newData.geometry, newData.availableGeometry); } if (!qFuzzyCompare(m_data.dpi.first, newData.dpi.first) || !qFuzzyCompare(m_data.dpi.second, newData.dpi.second)) { diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index b981b94748..a18bd2834e 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -1032,8 +1032,7 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs * // a more advanced compositor is written. d->logicalSize = logicalSize; const QRect newGeometry = geometry(); - QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry); - QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), newGeometry); + QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry); QPlatformScreen::resizeMaximizedWindows(); handleExpose(); diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 83ffb02362..b936df4b85 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -403,7 +403,7 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan case XCB_RANDR_ROTATION_REFLECT_Y: break; } - QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry()); + QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry()); QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation); QDpi ldpi = logicalDpi(); @@ -451,7 +451,7 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) m_geometry = QRect(xGeometry.topLeft()/dpr, xGeometry.size()/dpr); m_availableGeometry = QRect(xAvailableGeometry.topLeft()/dpr, xAvailableGeometry.size()/dpr); - QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), m_availableGeometry); + QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry); } void QXcbScreen::updateRefreshRate() |