aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-04-19 15:47:34 +0800
committerPo Lu2022-04-19 15:49:27 +0800
commitd168decab4a03cd48b8b96257c36ffa575c720e6 (patch)
tree8e01b34a7d1d486b2ae2f4a23cfc07616e4fcacb /src
parent7f2ef27f49e2ea22cf38b84efc8e927c0240f16d (diff)
downloademacs-d168decab4a03cd48b8b96257c36ffa575c720e6.tar.gz
emacs-d168decab4a03cd48b8b96257c36ffa575c720e6.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c55
1 files changed, 45 insertions, 10 deletions
diff --git a/src/xterm.c b/src/xterm.c
index c4652c19c66..3eecd5e204b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1366,10 +1366,16 @@ xm_write_drag_initiator_info (Display *dpy, Window wdesc,
1366 PropModeReplace, (unsigned char *) buf, 8); 1366 PropModeReplace, (unsigned char *) buf, 8);
1367} 1367}
1368 1368
1369static int
1370xm_drag_window_error_handler (Display *display, XErrorEvent *event)
1371{
1372 return 0;
1373}
1374
1369static Window 1375static Window
1370xm_get_drag_window (struct x_display_info *dpyinfo) 1376xm_get_drag_window (struct x_display_info *dpyinfo)
1371{ 1377{
1372 Atom actual_type; 1378 Atom actual_type, _MOTIF_DRAG_WINDOW;
1373 int rc, actual_format; 1379 int rc, actual_format;
1374 unsigned long nitems, bytes_remaining; 1380 unsigned long nitems, bytes_remaining;
1375 unsigned char *tmp_data = NULL; 1381 unsigned char *tmp_data = NULL;
@@ -1377,6 +1383,7 @@ xm_get_drag_window (struct x_display_info *dpyinfo)
1377 XSetWindowAttributes attrs; 1383 XSetWindowAttributes attrs;
1378 XWindowAttributes wattrs; 1384 XWindowAttributes wattrs;
1379 Display *temp_display; 1385 Display *temp_display;
1386 void *old_handler;
1380 1387
1381 drag_window = None; 1388 drag_window = None;
1382 rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window, 1389 rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
@@ -1420,16 +1427,44 @@ xm_get_drag_window (struct x_display_info *dpyinfo)
1420 1427
1421 XGrabServer (temp_display); 1428 XGrabServer (temp_display);
1422 XSetCloseDownMode (temp_display, RetainPermanent); 1429 XSetCloseDownMode (temp_display, RetainPermanent);
1423 attrs.override_redirect = True; 1430
1424 drag_window = XCreateWindow (temp_display, DefaultRootWindow (temp_display), 1431 /* We can't use XErrorHandler since it's not in the Xlib
1425 -1, -1, 1, 1, 0, CopyFromParent, InputOnly, 1432 specification, and Emacs tries to be portable. */
1426 CopyFromParent, CWOverrideRedirect, &attrs); 1433 old_handler = (void *) XSetErrorHandler (xm_drag_window_error_handler);
1427 XChangeProperty (temp_display, DefaultRootWindow (temp_display), 1434
1428 XInternAtom (temp_display, 1435 _MOTIF_DRAG_WINDOW = XInternAtom (temp_display,
1429 "_MOTIF_DRAG_WINDOW", False), 1436 "_MOTIF_DRAG_WINDOW", False);
1430 XA_WINDOW, 32, PropModeReplace, 1437
1431 (unsigned char *) &drag_window, 1); 1438 /* Some other program might've created a drag window between now
1439 and when we first looked. Use that if it exists. */
1440
1441 tmp_data = NULL;
1442 rc = XGetWindowProperty (temp_display, DefaultRootWindow (temp_display),
1443 _MOTIF_DRAG_WINDOW, 0, 1, False, XA_WINDOW,
1444 &actual_type, &actual_format, &nitems,
1445 &bytes_remaining, &tmp_data) == Success;
1446
1447 if (rc && actual_type == XA_WINDOW
1448 && actual_format == 32 && nitems == 1
1449 && tmp_data)
1450 drag_window = *(Window *) tmp_data;
1451
1452 if (tmp_data)
1453 XFree (tmp_data);
1454
1455 if (drag_window == None)
1456 {
1457 attrs.override_redirect = True;
1458 drag_window = XCreateWindow (temp_display, DefaultRootWindow (temp_display),
1459 -1, -1, 1, 1, 0, CopyFromParent, InputOnly,
1460 CopyFromParent, CWOverrideRedirect, &attrs);
1461 XChangeProperty (temp_display, DefaultRootWindow (temp_display),
1462 _MOTIF_DRAG_WINDOW, XA_WINDOW, 32, PropModeReplace,
1463 (unsigned char *) &drag_window, 1);
1464 }
1465
1432 XCloseDisplay (temp_display); 1466 XCloseDisplay (temp_display);
1467 XSetErrorHandler (old_handler);
1433 1468
1434 /* Make sure the drag window created is actually valid for the 1469 /* Make sure the drag window created is actually valid for the
1435 current display, and the XOpenDisplay above didn't 1470 current display, and the XOpenDisplay above didn't