]> git.eshelyaron.com Git - emacs.git/commitdiff
Cache the Motif drag window to avoid fetching it every time
authorPo Lu <luangruo@yahoo.com>
Sun, 19 Jun 2022 03:35:12 +0000 (11:35 +0800)
committerPo Lu <luangruo@yahoo.com>
Sun, 19 Jun 2022 03:35:12 +0000 (11:35 +0800)
* src/xterm.c (xm_get_drag_window_1): New function.
(xm_get_drag_window): Cache the window.  If it already exists,
just return it.
(xm_setup_dnd_targets): If a BadWindow error occurs, re-create
the Motif drag window.

* src/xterm.h (struct x_display_info): New field
`motif_drag_window'.

src/xterm.c
src/xterm.h

index f9f3e938e095b31cdd328c321ab823ee8669f902..d83a56a6cba2be57a2a1facd719824dd3b6328af 100644 (file)
@@ -1805,7 +1805,7 @@ xm_drag_window_io_error_handler (Display *dpy)
 }
 
 static Window
-xm_get_drag_window (struct x_display_info *dpyinfo)
+xm_get_drag_window_1 (struct x_display_info *dpyinfo)
 {
   Atom actual_type, _MOTIF_DRAG_WINDOW;
   int rc, actual_format;
@@ -1975,6 +1975,16 @@ xm_get_drag_window (struct x_display_info *dpyinfo)
   return drag_window;
 }
 
+static Window
+xm_get_drag_window (struct x_display_info *dpyinfo)
+{
+  if (dpyinfo->motif_drag_window != None)
+    return dpyinfo->motif_drag_window;
+
+  dpyinfo->motif_drag_window = xm_get_drag_window_1 (dpyinfo);
+  return dpyinfo->motif_drag_window;
+}
+
 static int
 xm_setup_dnd_targets (struct x_display_info *dpyinfo,
                      Atom *targets, int ntargets)
@@ -1984,6 +1994,7 @@ xm_setup_dnd_targets (struct x_display_info *dpyinfo,
   unsigned char *tmp_data = NULL;
   unsigned long nitems, bytes_remaining;
   int rc, actual_format, idx;
+  bool had_errors;
   xm_targets_table_header header;
   xm_targets_table_rec **recs;
   xm_byte_order byteorder;
@@ -1991,6 +2002,8 @@ xm_setup_dnd_targets (struct x_display_info *dpyinfo,
   ptrdiff_t total_bytes, total_items, i;
   uint32_t size, target_count;
 
+ retry_drag_window:
+
   drag_window = xm_get_drag_window (dpyinfo);
 
   if (drag_window == None || ntargets > 64)
@@ -2003,12 +2016,26 @@ xm_setup_dnd_targets (struct x_display_info *dpyinfo,
         sizeof (Atom), x_atoms_compare);
 
   XGrabServer (dpyinfo->display);
+
+  x_catch_errors (dpyinfo->display);
   rc = XGetWindowProperty (dpyinfo->display, drag_window,
                           dpyinfo->Xatom_MOTIF_DRAG_TARGETS,
                           0L, LONG_MAX, False,
                           dpyinfo->Xatom_MOTIF_DRAG_TARGETS,
                           &actual_type, &actual_format, &nitems,
                           &bytes_remaining, &tmp_data) == Success;
+  had_errors = x_had_errors_p (dpyinfo->display);
+  x_uncatch_errors ();
+
+  /* The drag window is probably invalid, so remove our record of
+     it.  */
+  if (had_errors)
+    {
+      dpyinfo->motif_drag_window = None;
+      XUngrabServer (dpyinfo->display);
+
+      goto retry_drag_window;
+    }
 
   if (rc && tmp_data && !bytes_remaining
       && actual_type == dpyinfo->Xatom_MOTIF_DRAG_TARGETS
index 3ef523d7822523783d108601cdc08eadeecb25df..3d243f3eabff8cd50d6c4b9bfc9838bd4bc2327f 100644 (file)
@@ -578,6 +578,9 @@ struct x_display_info
   /* The frame that currently owns `motif_drag_atom'.  */
   struct frame *motif_drag_atom_owner;
 
+  /* The drag window for this display.  */
+  Window motif_drag_window;
+
   /* Extended window manager hints, Atoms supported by the window manager and
      atoms for setting the window type.  */
   Atom Xatom_net_supported, Xatom_net_supporting_wm_check;