emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master d168decab4: Deal with Motif drag window related races


From: Po Lu
Subject: master d168decab4: Deal with Motif drag window related races
Date: Tue, 19 Apr 2022 03:49:38 -0400 (EDT)

branch: master
commit d168decab4a03cd48b8b96257c36ffa575c720e6
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Deal with Motif drag window related races
    
    * src/xterm.c (xm_drag_window_error_handler): New function.
    (xm_get_drag_window): If a drag window was created and we have
    the temp display grabbed, use that instead.
---
 src/xterm.c | 55 +++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 45 insertions(+), 10 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index c4652c19c6..3eecd5e204 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1366,10 +1366,16 @@ xm_write_drag_initiator_info (Display *dpy, Window 
wdesc,
                   PropModeReplace, (unsigned char *) buf, 8);
 }
 
+static int
+xm_drag_window_error_handler (Display *display, XErrorEvent *event)
+{
+  return 0;
+}
+
 static Window
 xm_get_drag_window (struct x_display_info *dpyinfo)
 {
-  Atom actual_type;
+  Atom actual_type, _MOTIF_DRAG_WINDOW;
   int rc, actual_format;
   unsigned long nitems, bytes_remaining;
   unsigned char *tmp_data = NULL;
@@ -1377,6 +1383,7 @@ xm_get_drag_window (struct x_display_info *dpyinfo)
   XSetWindowAttributes attrs;
   XWindowAttributes wattrs;
   Display *temp_display;
+  void *old_handler;
 
   drag_window = None;
   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
@@ -1420,16 +1427,44 @@ xm_get_drag_window (struct x_display_info *dpyinfo)
 
       XGrabServer (temp_display);
       XSetCloseDownMode (temp_display, RetainPermanent);
-      attrs.override_redirect = True;
-      drag_window = XCreateWindow (temp_display, DefaultRootWindow 
(temp_display),
-                                  -1, -1, 1, 1, 0, CopyFromParent, InputOnly,
-                                  CopyFromParent, CWOverrideRedirect, &attrs);
-      XChangeProperty (temp_display, DefaultRootWindow (temp_display),
-                      XInternAtom (temp_display,
-                                   "_MOTIF_DRAG_WINDOW", False),
-                      XA_WINDOW, 32, PropModeReplace,
-                      (unsigned char *) &drag_window, 1);
+
+      /* We can't use XErrorHandler since it's not in the Xlib
+        specification, and Emacs tries to be portable.  */
+      old_handler = (void *) XSetErrorHandler (xm_drag_window_error_handler);
+
+      _MOTIF_DRAG_WINDOW = XInternAtom (temp_display,
+                                       "_MOTIF_DRAG_WINDOW", False);
+
+      /* Some other program might've created a drag window between now
+        and when we first looked.  Use that if it exists.  */
+
+      tmp_data = NULL;
+      rc = XGetWindowProperty (temp_display, DefaultRootWindow (temp_display),
+                              _MOTIF_DRAG_WINDOW, 0, 1, False, XA_WINDOW,
+                              &actual_type, &actual_format, &nitems,
+                              &bytes_remaining, &tmp_data) == Success;
+
+      if (rc && actual_type == XA_WINDOW
+         && actual_format == 32 && nitems == 1
+         && tmp_data)
+       drag_window = *(Window *) tmp_data;
+
+      if (tmp_data)
+       XFree (tmp_data);
+
+      if (drag_window == None)
+       {
+         attrs.override_redirect = True;
+         drag_window = XCreateWindow (temp_display, DefaultRootWindow 
(temp_display),
+                                      -1, -1, 1, 1, 0, CopyFromParent, 
InputOnly,
+                                      CopyFromParent, CWOverrideRedirect, 
&attrs);
+         XChangeProperty (temp_display, DefaultRootWindow (temp_display),
+                          _MOTIF_DRAG_WINDOW, XA_WINDOW, 32, PropModeReplace,
+                          (unsigned char *) &drag_window, 1);
+       }
+
       XCloseDisplay (temp_display);
+      XSetErrorHandler (old_handler);
 
       /* Make sure the drag window created is actually valid for the
         current display, and the XOpenDisplay above didn't



reply via email to

[Prev in Thread] Current Thread [Next in Thread]