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>
This commit is contained in:
parent
2d2dc976d8
commit
2368e62f32
@ -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();
|
||||
|
||||
bool geometryChanged = e->geometry != s->d_func()->geometry;
|
||||
s->d_func()->geometry = e->geometry;
|
||||
|
||||
Qt::ScreenOrientation primaryOrientation = s->primaryOrientation();
|
||||
s->d_func()->updatePrimaryOrientation();
|
||||
|
||||
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());
|
||||
|
||||
if (s->primaryOrientation() != primaryOrientation)
|
||||
emit s->primaryOrientationChanged(s->primaryOrientation());
|
||||
|
||||
if (s->d_func()->orientation == Qt::PrimaryOrientation)
|
||||
updateFilteredScreenOrientation(s);
|
||||
}
|
||||
|
||||
void QGuiApplicationPrivate::reportAvailableGeometryChange(
|
||||
QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e)
|
||||
{
|
||||
// This operation only makes sense after the QGuiApplication constructor runs
|
||||
if (QCoreApplication::startingUp())
|
||||
return;
|
||||
|
||||
if (!e->screen)
|
||||
return;
|
||||
|
||||
QScreen *s = e->screen.data();
|
||||
bool availableGeometryChanged = e->availableGeometry != s->d_func()->availableGeometry;
|
||||
s->d_func()->availableGeometry = e->availableGeometry;
|
||||
|
||||
foreach (QScreen* sibling, s->virtualSiblings())
|
||||
emit sibling->virtualGeometryChanged(sibling->virtualGeometry());
|
||||
if (geometryChanged) {
|
||||
Qt::ScreenOrientation primaryOrientation = s->primaryOrientation();
|
||||
s->d_func()->updatePrimaryOrientation();
|
||||
|
||||
emit s->geometryChanged(s->geometry());
|
||||
emit s->physicalSizeChanged(s->physicalSize());
|
||||
emit s->physicalDotsPerInchChanged(s->physicalDotsPerInch());
|
||||
emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch());
|
||||
|
||||
if (s->primaryOrientation() != primaryOrientation)
|
||||
emit s->primaryOrientationChanged(s->primaryOrientation());
|
||||
|
||||
if (s->d_func()->orientation == Qt::PrimaryOrientation)
|
||||
updateFilteredScreenOrientation(s);
|
||||
}
|
||||
|
||||
if (availableGeometryChanged)
|
||||
emit s->availableGeometryChanged(s->geometry());
|
||||
|
||||
if (geometryChanged || availableGeometryChanged) {
|
||||
foreach (QScreen* sibling, s->virtualSiblings())
|
||||
emit sibling->virtualGeometryChanged(sibling->virtualGeometry());
|
||||
}
|
||||
}
|
||||
|
||||
void QGuiApplicationPrivate::reportLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
m_availableGeometry = m_geometry;
|
||||
|
||||
CGSize applicationFrameSize = m_uiScreen.applicationFrame.size;
|
||||
int statusBarHeight = m_geometry.height() - (inPortrait ? applicationFrameSize.height : applicationFrameSize.width);
|
||||
|
||||
m_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;
|
||||
|
||||
QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry);
|
||||
}
|
||||
|
||||
QRect availableGeometry = geometry;
|
||||
|
||||
CGSize applicationFrameSize = m_uiScreen.applicationFrame.size;
|
||||
int statusBarHeight = geometry.height() - (inPortrait ? applicationFrameSize.height : applicationFrameSize.width);
|
||||
|
||||
availableGeometry.adjust(0, statusBarHeight, 0, 0);
|
||||
|
||||
if (availableGeometry != m_availableGeometry) {
|
||||
m_availableGeometry = availableGeometry;
|
||||
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry);
|
||||
QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry, m_availableGeometry);
|
||||
}
|
||||
|
||||
if (screen())
|
||||
|
@ -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)
|
||||
|
@ -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)) {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user