Currently, the ConfigureWindow function will deliver a ConfigureNotify
event to the application before calling into the window's appropriate
function with the new size / position.  Hence, the application may
begin to process the event before some server-size data structures are
updated with the new information leading to a potentially inconsistent
state.

The issue has been causing problems with our OpenGL driver,
specifically when something like the following sequence of events
happens after a window resize:
1. [xserver]     send ConfigureNotify event to application
2. [application] call into client-side OpenGL code in response to resize
3. [driver] read shared memory variable (call it x) indicating whether
                 current window has been resized, see that it has not,
                 proceed without updating client side data structures
4. [xserver]     call pScreen->ResizeWindow(...), eventually calling into
                 server-side OpenGL code
5. [driver]      update server side data structures, and write to x
                 indicating that the window has changed

(2 -> 3) and (4 -> 5) occur asynchronously.  If they run in the order
described above, it can leave the client side and server side driver
components to disagree, causing problems later on.

This change will ensure the new configuration is fully processed by the
server before any event is sent to the application.

Signed-off-by: Erik Kurzinger <[email protected]>
---
 dix/window.c | 50 ++++++++++++++++++++++++++------------------------
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/dix/window.c b/dix/window.c
index ead4dc2..7177ae3 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -2368,6 +2368,32 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client)
     return Success;

  ActuallyDoSomething:
+    if (mask & CWBorderWidth) {
+        if (action == RESTACK_WIN) {
+            action = MOVE_WIN;
+            pWin->borderWidth = bw;
+        }
+        else if ((action == MOVE_WIN) &&
+                 (beforeX + wBorderWidth(pWin) == x + (int) bw) &&
+                 (beforeY + wBorderWidth(pWin) == y + (int) bw)) {
+            action = REBORDER_WIN;
+            (*pWin->drawable.pScreen->ChangeBorderWidth) (pWin, bw);
+        }
+        else
+            pWin->borderWidth = bw;
+    }
+    if (action == MOVE_WIN)
+        (*pWin->drawable.pScreen->MoveWindow) (pWin, x, y, pSib,
+ (mask & CWBorderWidth) ? VTOther
+                                               : VTMove);
+    else if (action == RESIZE_WIN)
+        (*pWin->drawable.pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
+    else if (mask & CWStackMode)
+        ReflectStackChange(pWin, pSib, VTOther);
+
+    if (action != RESTACK_WIN)
+        CheckCursorConfinement(pWin);
+
     if (pWin->drawable.pScreen->ConfigNotify) {
         int ret;

@@ -2400,31 +2426,7 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client)
 #endif
         DeliverEvents(pWin, &event, 1, NullWindow);
     }
-    if (mask & CWBorderWidth) {
-        if (action == RESTACK_WIN) {
-            action = MOVE_WIN;
-            pWin->borderWidth = bw;
-        }
-        else if ((action == MOVE_WIN) &&
-                 (beforeX + wBorderWidth(pWin) == x + (int) bw) &&
-                 (beforeY + wBorderWidth(pWin) == y + (int) bw)) {
-            action = REBORDER_WIN;
-            (*pWin->drawable.pScreen->ChangeBorderWidth) (pWin, bw);
-        }
-        else
-            pWin->borderWidth = bw;
-    }
-    if (action == MOVE_WIN)
-        (*pWin->drawable.pScreen->MoveWindow) (pWin, x, y, pSib,
- (mask & CWBorderWidth) ? VTOther
-                                               : VTMove);
-    else if (action == RESIZE_WIN)
-        (*pWin->drawable.pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
-    else if (mask & CWStackMode)
-        ReflectStackChange(pWin, pSib, VTOther);

-    if (action != RESTACK_WIN)
-        CheckCursorConfinement(pWin);
     return Success;
 #undef RESTACK_WIN
 #undef MOVE_WIN
--
2.7.4


_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to