From fe086ddb9e4640489595a4c12aef6a27b989ed70 Mon Sep 17 00:00:00 2001
From: Alexander Volkov <a.volkov@rusbitech.ru>
Date: Tue, 21 Apr 2015 18:54:55 +0300
Subject: [PATCH] xcb: Fix updating physical screen size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

X server may return an empty physical screen size, for example
on VNC, Xephyr or some not very well supported hardware.
In this case it's possible to use the size of the virtual desktop,
but until now it was done only in the QXcbScreen constructor.

Move it to QXcbScreen::updateGeometry() and calculate physical screen
size using the DPI of the virtual desktop.

Task-number: QTBUG-45564
Change-Id: I6b757818a2fcefdd7b2c0aa31b840a88d625d6ae
Reviewed-by: Daniel Vrátil <dvratil@redhat.com>
Reviewed-by: Paul Olav Tvete <paul.tvete@theqtcompany.com>
---
 src/plugins/platforms/xcb/qxcbscreen.cpp | 25 +++++++++++++++++-------
 src/plugins/platforms/xcb/qxcbscreen.h   |  1 +
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index a0d6d88d115..c14ec0bb3f7 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -108,10 +108,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
     }
 
     const int dpr = int(devicePixelRatio());
-    // On VNC, it can be that physical size is unknown while
-    // virtual size is known (probably back-calculated from DPI and resolution)
-    if (m_sizeMillimeters.isEmpty())
-        m_sizeMillimeters = m_virtualSizeMillimeters;
     if (m_geometry.isEmpty()) {
         m_geometry = QRect(QPoint(), m_virtualSize/dpr);
         m_nativeGeometry = QRect(QPoint(), m_virtualSize);
@@ -353,6 +349,12 @@ QImage::Format QXcbScreen::format() const
     return QImage::Format_RGB32;
 }
 
+QDpi QXcbScreen::virtualDpi() const
+{
+    return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(),
+                Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height());
+}
+
 QDpi QXcbScreen::logicalDpi() const
 {
     static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI");
@@ -363,8 +365,7 @@ QDpi QXcbScreen::logicalDpi() const
         int primaryDpr = int(connection()->screens().at(0)->devicePixelRatio());
         return QDpi(m_forcedDpi/primaryDpr, m_forcedDpi/primaryDpr);
     }
-    return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(),
-                Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height());
+    return virtualDpi();
 }
 
 
@@ -415,7 +416,6 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan
         return;
 
     m_rotation = change_event->rotation;
-    updateGeometry(change_event->timestamp);
     switch (m_rotation) {
     case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
         m_orientation = Qt::LandscapeOrientation;
@@ -451,6 +451,8 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan
     case XCB_RANDR_ROTATION_REFLECT_Y: break;
     }
 
+    updateGeometry(change_event->timestamp);
+
     QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry());
     QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation);
 
@@ -504,6 +506,15 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation)
         break;
     }
 
+    // It can be that physical size is unknown while virtual size
+    // is known (probably back-calculated from DPI and resolution),
+    // e.g. on VNC or with some hardware.
+    if (m_sizeMillimeters.isEmpty()) {
+        QDpi dpi = virtualDpi();
+        m_sizeMillimeters = QSizeF(Q_MM_PER_INCH * xGeometry.width() / dpi.first,
+                                   Q_MM_PER_INCH * xGeometry.width() / dpi.second);
+    }
+
     xcb_get_property_reply_t * workArea =
         xcb_get_property_reply(xcb_connection(),
             xcb_get_property_unchecked(xcb_connection(), false, screen()->root,
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index a29efc1e799..ec05e3bb25c 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -94,6 +94,7 @@ public:
     QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_sizeMillimeters; }
     QSize virtualSize() const { return m_virtualSize; }
     QSizeF physicalVirtualSize() const { return m_virtualSizeMillimeters; }
+    QDpi virtualDpi() const;
     QDpi logicalDpi() const Q_DECL_OVERRIDE;
     qreal devicePixelRatio() const Q_DECL_OVERRIDE;
     QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
-- 
GitLab