95b646a
From a91e9dd202640598d8dec091c67ec94536390e7f Mon Sep 17 00:00:00 2001
95b646a
From: "Owen W. Taylor" <otaylor@fishsoup.net>
95b646a
Date: Mon, 17 Oct 2011 17:27:43 -0400
95b646a
Subject: [PATCH] Fix logic for figuring out what ConfigureNotify positions
95b646a
 can be trusted
95b646a
95b646a
When reading ahead in the queue for ConfigureNotify events, it's necessary
95b646a
to look for intermediate ReparentNotify events as well, since they will
95b646a
determine whether the position in the event can be trusted or not.
95b646a
---
95b646a
 src/gui/kernel/qapplication_x11.cpp |   47 ++++++++++++++++++++++++++++++----
95b646a
 1 files changed, 41 insertions(+), 6 deletions(-)
95b646a
95b646a
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
95b646a
index 408e9ac..3a1d3eb 100644
95b646a
--- a/src/gui/kernel/qapplication_x11.cpp
95b646a
+++ b/src/gui/kernel/qapplication_x11.cpp
95b646a
@@ -816,6 +816,27 @@ static Bool qt_sync_request_scanner(Display*, XEvent *event, XPointer arg)
95b646a
 #endif
95b646a
 #endif // QT_NO_XSYNC
95b646a
 
95b646a
+struct qt_configure_event_data
95b646a
+{
95b646a
+    WId window;
95b646a
+    WId parent;
95b646a
+};
95b646a
+
95b646a
+static Bool qt_configure_event_scanner(Display*, XEvent *event, XPointer arg)
95b646a
+{
95b646a
+    qt_configure_event_data *data =
95b646a
+        reinterpret_cast<qt_configure_event_data*>(arg);
95b646a
+    if (event->type == ConfigureNotify &&
95b646a
+        event->xconfigure.window == data->window) {
95b646a
+        return true;
95b646a
+    } else if (event->type == ReparentNotify &&
95b646a
+               event->xreparent.window == data->window) {
95b646a
+        data->parent = event->xreparent.parent;
95b646a
+    }
95b646a
+
95b646a
+    return false;
95b646a
+}
95b646a
+
95b646a
 static void qt_x11_create_intern_atoms()
95b646a
 {
95b646a
     const char *names[QX11Data::NAtoms];
95b646a
@@ -5273,8 +5294,11 @@ bool QETWidget::translateConfigEvent(const XEvent *event)
95b646a
         if (d->extra->compress_events) {
95b646a
             // ConfigureNotify compression for faster opaque resizing
95b646a
             XEvent otherEvent;
95b646a
-            while (XCheckTypedWindowEvent(X11->display, internalWinId(), ConfigureNotify,
95b646a
-                                          &otherEvent)) {
95b646a
+            qt_configure_event_data configureData;
95b646a
+            configureData.window = internalWinId();
95b646a
+            configureData.parent = d->topData()->parentWinId;
95b646a
+            while (XCheckIfEvent(X11->display, &otherEvent,
95b646a
+                                 &qt_configure_event_scanner, (XPointer)&configureData)) {
95b646a
                 if (qt_x11EventFilter(&otherEvent))
95b646a
                     continue;
95b646a
 
95b646a
@@ -5287,13 +5311,19 @@ bool QETWidget::translateConfigEvent(const XEvent *event)
95b646a
                 newSize.setWidth(otherEvent.xconfigure.width);
95b646a
                 newSize.setHeight(otherEvent.xconfigure.height);
95b646a
 
95b646a
+                trust = isVisible()
95b646a
+                        && (configureData.parent == XNone ||
95b646a
+                            configureData.parent == QX11Info::appRootWindow());
95b646a
+
95b646a
                 if (otherEvent.xconfigure.send_event || trust) {
95b646a
                     newCPos.rx() = otherEvent.xconfigure.x +
95b646a
                                    otherEvent.xconfigure.border_width;
95b646a
                     newCPos.ry() = otherEvent.xconfigure.y +
95b646a
                                    otherEvent.xconfigure.border_width;
95b646a
                     isCPos = true;
95b646a
-                }
95b646a
+                } else {
95b646a
+                    isCPos = false;
95b646a
+               }
95b646a
             }
95b646a
 #ifndef QT_NO_XSYNC
95b646a
             qt_sync_request_event_data sync_event;
95b646a
@@ -5306,9 +5336,14 @@ bool QETWidget::translateConfigEvent(const XEvent *event)
95b646a
         }
95b646a
 
95b646a
         if (!isCPos) {
95b646a
-            // we didn't get an updated position of the toplevel.
95b646a
-            // either we haven't moved or there is a bug in the window manager.
95b646a
-            // anyway, let's query the position to be certain.
95b646a
+            // If the last configure event didn't have a trustable position,
95b646a
+            // it's necessary to query, see ICCCM 4.24:
95b646a
+            //
95b646a
+            //  Any real ConfigureNotify event on a top-level window implies
95b646a
+            //  that the window’s position on the root may have changed, even
95b646a
+            //  though the event reports that the window’s position in its
95b646a
+            //  parent is unchanged because the window may have been reparented.
95b646a
+
95b646a
             int x, y;
95b646a
             Window child;
95b646a
             XTranslateCoordinates(X11->display, internalWinId(),
95b646a
-- 
95b646a
1.7.6.4
95b646a