mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-24 05:47:36 +00:00
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.
This commit is contained in:
parent
7f2ef27f49
commit
d168decab4
1 changed files with 45 additions and 10 deletions
55
src/xterm.c
55
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue