From: Po Lu Date: Sun, 19 Jun 2022 03:35:12 +0000 (+0800) Subject: Cache the Motif drag window to avoid fetching it every time X-Git-Tag: emacs-29.0.90~1447^2~1628 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=fd853c71a958e3156014378fdd145e6e4d8c2717;p=emacs.git Cache the Motif drag window to avoid fetching it every time * 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'. --- diff --git a/src/xterm.c b/src/xterm.c index f9f3e938e09..d83a56a6cba 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -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 diff --git a/src/xterm.h b/src/xterm.h index 3ef523d7822..3d243f3eabf 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -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;