Properly handle position in non-synthetic ConfigureNotify with xcb
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>
Sat, 5 Nov 2011 12:00:53 +0000 (14:00 +0200)
committerQt by Nokia <qt-info@nokia.com>
Tue, 15 Nov 2011 00:05:49 +0000 (01:05 +0100)
The received window position cannot be trusted blindly, e.g. in case
of resizing a window via the mouse or calling showMaximized() the
position is bogus (for our purposes). Instead, it needs to be queried.

Before 37f338e5edc6d7b70b5a4eaf63326f2a22d7bfbd an incomplete
workaround was in place however it got removed in that commit,
resulting in weird off-by-a-certain-amount mouse position issues in
certain use cases. This patch aims to fix the issue similarly to how
it was done in Qt4.

Change-Id: I2d2a69b81a2782117b700fe366fae4c102aca1f4
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
src/plugins/platforms/xcb/qxcbwindow.cpp

index 4f31e06..b8c0e5f 100644 (file)
@@ -1221,7 +1221,24 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
 
 void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event)
 {
-    QRect rect(event->x, event->y, event->width, event->height);
+    bool fromSendEvent = (event->response_type & 0x80);
+    QPoint pos(event->x, event->y);
+    if (!fromSendEvent) {
+        // Do not trust the position, query it instead.
+        xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcb_window(),
+                                                                              m_screen->root(), 0, 0);
+        xcb_generic_error_t *error;
+        xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, &error);
+        if (reply) {
+            pos.setX(reply->dst_x);
+            pos.setY(reply->dst_y);
+            free(reply);
+        } else if (error) {
+            free(error);
+        }
+    }
+
+    QRect rect(pos, QSize(event->width, event->height));
 
     QPlatformWindow::setGeometry(rect);
     QWindowSystemInterface::handleGeometryChange(window(), rect);