emacs-diffs
[Top][All Lists]
Advanced

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

master ed02be04ae: More gracefully handle errors during Motif drag windo


From: Po Lu
Subject: master ed02be04ae: More gracefully handle errors during Motif drag window creation
Date: Thu, 2 Jun 2022 07:54:49 -0400 (EDT)

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

    More gracefully handle errors during Motif drag window creation
    
    * src/xterm.c (xm_drag_window_error_handler): Store whether or
    not an error happened.
    (xm_get_drag_window): Handle errors during XCreateWindow and
    XChangeProperty without leaking anything.
    (x_error_handler): Fix coding style.
---
 src/xterm.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 4 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index d0aa8874b6..f8b1f0db74 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1231,6 +1231,10 @@ static bool x_dnd_use_toplevels;
 
 /* Motif drag-and-drop protocol support.  */
 
+/* Pointer to a variable which stores whether or not an X error
+   occured while trying to create the Motif drag window.  */
+static volatile bool *xm_drag_window_error;
+
 typedef enum xm_byte_order
   {
     XM_BYTE_ORDER_LSB_FIRST = 'l',
@@ -1629,6 +1633,9 @@ xm_write_drag_initiator_info (Display *dpy, Window wdesc,
 static int
 xm_drag_window_error_handler (Display *display, XErrorEvent *event)
 {
+  if (xm_drag_window_error)
+    *xm_drag_window_error = true;
+
   return 0;
 }
 
@@ -1651,6 +1658,9 @@ xm_get_drag_window (struct x_display_info *dpyinfo)
   XSetWindowAttributes attrs;
   Display *temp_display;
   void *old_handler, *old_io_handler;
+  /* These are volatile because GCC mistakenly warns about them being
+     clobbered by longjmp.  */
+  volatile bool error, created;
 
   drag_window = None;
   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
@@ -1706,6 +1716,9 @@ xm_get_drag_window (struct x_display_info *dpyinfo)
          return None;
        }
 
+      error = false;
+      xm_drag_window_error = &error;
+
       XGrabServer (temp_display);
       XSetCloseDownMode (temp_display, RetainPermanent);
 
@@ -1716,6 +1729,9 @@ xm_get_drag_window (struct x_display_info *dpyinfo)
       _MOTIF_DRAG_WINDOW = XInternAtom (temp_display,
                                        "_MOTIF_DRAG_WINDOW", False);
 
+      if (error)
+       goto give_up;
+
       /* Some other program might've created a drag window between now
         and when we first looked.  Use that if it exists.  */
 
@@ -1733,8 +1749,12 @@ xm_get_drag_window (struct x_display_info *dpyinfo)
       if (tmp_data)
        XFree (tmp_data);
 
+      error = false;
+
       if (drag_window == None)
        {
+         created = true;
+
          attrs.override_redirect = True;
          drag_window = XCreateWindow (temp_display, DefaultRootWindow 
(temp_display),
                                       -1, -1, 1, 1, 0, CopyFromParent, 
InputOnly,
@@ -1743,6 +1763,34 @@ xm_get_drag_window (struct x_display_info *dpyinfo)
                           _MOTIF_DRAG_WINDOW, XA_WINDOW, 32, PropModeReplace,
                           (unsigned char *) &drag_window, 1);
        }
+      else
+       created = false;
+
+      /* Handle all errors now.   */
+      XSync (temp_display, False);
+
+    give_up:
+
+      /* Some part of the drag window creation process failed, so
+        punt.  */
+      if (error)
+       {
+         /* If the drag window was actually created, delete it now.
+            Probably, a BadAlloc happened during the XChangeProperty
+            request.  */
+         if (created)
+           {
+             if (drag_window != None)
+               XDestroyWindow (temp_display, drag_window);
+
+             XDeleteProperty (temp_display, DefaultRootWindow (temp_display),
+                              _MOTIF_DRAG_WINDOW);
+           }
+
+         drag_window = None;
+       }
+
+      xm_drag_window_error = NULL;
 
       /* FIXME: why does XCloseDisplay hang if SIGIO arrives and there
         are multiple displays? */
@@ -21854,11 +21902,10 @@ x_error_handler (Display *display, XErrorEvent *event)
 #endif
 
 #if defined USE_GTK && defined HAVE_GTK3
-  if ((event->error_code == BadMatch || event->error_code == BadWindow)
+  if ((event->error_code == BadMatch
+       || event->error_code == BadWindow)
       && event->request_code == X_SetInputFocus)
-    {
-      return 0;
-    }
+    return 0;
 #endif
 
   /* If we try to ungrab or grab a device that doesn't exist anymore



reply via email to

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