summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@theqtcompany.com>2015-01-07 15:44:12 +0100
committerPaul Olav Tvete <paul.tvete@theqtcompany.com>2015-01-12 09:48:11 +0100
commit075ae987c48ce732e6a22c1eba71023fa0ea1775 (patch)
tree2012048dc9e6bb3ad41f59fe039e564b03ee3ca6
parent3ba1b989a6c7e22e8f0b92c59c5bbb52cdcab638 (diff)
X11 devicePixelRatio screen mapping fix
Fix screen detection and window geometry when screens have different displayPixelRatios. We must use the native coordinate system to figure out which screen a window belongs to. Also, when a window moves to a screen with a different devicePixelRatio, we must recalculate the Qt geometry. Task-number: QTBUG-43713 Change-Id: I93063e37354ff88f3c8a13320b76dfb272e43a9c Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp29
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h2
4 files changed, 35 insertions, 3 deletions
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 73f27c7117..f8d68c68f0 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -77,8 +77,10 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
// virtual size is known (probably back-calculated from DPI and resolution)
if (m_sizeMillimeters.isEmpty())
m_sizeMillimeters = m_virtualSizeMillimeters;
- if (m_geometry.isEmpty())
+ if (m_geometry.isEmpty()) {
m_geometry = QRect(QPoint(), m_virtualSize/dpr);
+ m_nativeGeometry = QRect(QPoint(), m_virtualSize);
+ }
if (m_availableGeometry.isEmpty())
m_availableGeometry = m_geometry;
@@ -461,6 +463,7 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
m_devicePixelRatio = qRound(dpi/96);
const int dpr = int(devicePixelRatio()); // we may override m_devicePixelRatio
m_geometry = QRect(xGeometry.topLeft()/dpr, xGeometry.size()/dpr);
+ m_nativeGeometry = QRect(xGeometry.topLeft(), xGeometry.size());
m_availableGeometry = QRect(xAvailableGeometry.topLeft()/dpr, xAvailableGeometry.size()/dpr);
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index b9ee331104..4675b12d9c 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -62,6 +62,7 @@ public:
QWindow *topLevelAt(const QPoint &point) const;
QRect geometry() const { return m_geometry; }
+ QRect nativeGeometry() const { return m_nativeGeometry; }
QRect availableGeometry() const {return m_availableGeometry;}
int depth() const { return m_screen->root_depth; }
QImage::Format format() const;
@@ -114,6 +115,7 @@ private:
QSizeF m_outputSizeMillimeters;
QSizeF m_sizeMillimeters;
QRect m_geometry;
+ QRect m_nativeGeometry;
QRect m_availableGeometry;
QSize m_virtualSize;
QSizeF m_virtualSizeMillimeters;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index e1ccc3f086..590e296f61 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1831,6 +1831,23 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
}
}
+// Temporary workaround for bug in QPlatformScreen::screenForNativeGeometry
+// we need the native geometries to detect our screen, but that's not
+// available in cross-platform code. Will be fixed properly when highDPI
+// support is refactored to expose the native coordinate system.
+
+QPlatformScreen *QXcbWindow::screenForNativeGeometry(const QRect &newGeometry) const
+{
+ QXcbScreen *currentScreen = static_cast<QXcbScreen*>(screen());
+ if (!parent() && !currentScreen->nativeGeometry().intersects(newGeometry)) {
+ Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) {
+ if (static_cast<QXcbScreen*>(screen)->nativeGeometry().intersects(newGeometry))
+ return screen;
+ }
+ }
+ return currentScreen;
+}
+
void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event)
{
bool fromSendEvent = (event->response_type & 0x80);
@@ -1847,15 +1864,23 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
}
}
- QRect rect = mapFromNative(QRect(pos, QSize(event->width, event->height)), int(devicePixelRatio()));
+ const int dpr = devicePixelRatio();
+ const QRect nativeRect = QRect(pos, QSize(event->width, event->height));
+ const QRect rect = mapFromNative(nativeRect, dpr);
QPlatformWindow::setGeometry(rect);
QWindowSystemInterface::handleGeometryChange(window(), rect);
- QPlatformScreen *newScreen = screenForGeometry(rect);
+ QPlatformScreen *newScreen = screenForNativeGeometry(nativeRect);
if (newScreen != m_screen) {
m_screen = static_cast<QXcbScreen*>(newScreen);
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
+ int newDpr = devicePixelRatio();
+ if (newDpr != dpr) {
+ QRect newRect = mapFromNative(nativeRect, newDpr);
+ QPlatformWindow::setGeometry(newRect);
+ QWindowSystemInterface::handleGeometryChange(window(), newRect);
+ }
}
m_configureNotifyPending = false;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 12d20d004d..254421e57d 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -154,6 +154,8 @@ public:
qreal devicePixelRatio() const;
+ QPlatformScreen *screenForNativeGeometry(const QRect &newGeometry) const;
+
public Q_SLOTS:
void updateSyncRequestCounter();