aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-03-26 10:15:53 +0800
committerPo Lu2022-03-26 10:15:53 +0800
commit5359062be603e22d1ee07c21b0840fdb98a704a3 (patch)
treef278bf1a27d04b21d19703d2995478c565db76ad /src
parent21ecf6b24d0549a9f27bcab51dbd8c8b1a37ef86 (diff)
downloademacs-5359062be603e22d1ee07c21b0840fdb98a704a3.tar.gz
emacs-5359062be603e22d1ee07c21b0840fdb98a704a3.zip
Avoid ClientMessage overhead when dragging stuff to other frames
* lisp/dired.el (dired-mouse-drag): Handle correctly dragging from dired buffers in nonselected windows. * lisp/x-dnd.el (x-dnd-handle-drag-n-drop-event): Understand new client message type. * src/xterm.c (x_dnd_send_enter, x_dnd_send_position) (x_dnd_send_leave): Ignore if window is the top window of a frame. (x_dnd_send_drop): Send special DND event in that case.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 6bd43511f8d..deb6d62a27e 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1396,6 +1396,9 @@ x_dnd_send_enter (struct frame *f, Window target, int supported)
1396 int i; 1396 int i;
1397 XEvent msg; 1397 XEvent msg;
1398 1398
1399 if (x_top_window_to_frame (dpyinfo, target))
1400 return;
1401
1399 msg.xclient.type = ClientMessage; 1402 msg.xclient.type = ClientMessage;
1400 msg.xclient.message_type = dpyinfo->Xatom_XdndEnter; 1403 msg.xclient.message_type = dpyinfo->Xatom_XdndEnter;
1401 msg.xclient.format = 32; 1404 msg.xclient.format = 32;
@@ -1443,6 +1446,9 @@ x_dnd_send_position (struct frame *f, Window target, int supported,
1443 return; 1446 return;
1444 } 1447 }
1445 1448
1449 if (x_top_window_to_frame (dpyinfo, target))
1450 return;
1451
1446 msg.xclient.type = ClientMessage; 1452 msg.xclient.type = ClientMessage;
1447 msg.xclient.message_type = dpyinfo->Xatom_XdndPosition; 1453 msg.xclient.message_type = dpyinfo->Xatom_XdndPosition;
1448 msg.xclient.format = 32; 1454 msg.xclient.format = 32;
@@ -1470,6 +1476,9 @@ x_dnd_send_leave (struct frame *f, Window target)
1470 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); 1476 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1471 XEvent msg; 1477 XEvent msg;
1472 1478
1479 if (x_top_window_to_frame (dpyinfo, target))
1480 return;
1481
1473 msg.xclient.type = ClientMessage; 1482 msg.xclient.type = ClientMessage;
1474 msg.xclient.message_type = dpyinfo->Xatom_XdndLeave; 1483 msg.xclient.message_type = dpyinfo->Xatom_XdndLeave;
1475 msg.xclient.format = 32; 1484 msg.xclient.format = 32;
@@ -1491,6 +1500,62 @@ x_dnd_send_drop (struct frame *f, Window target, Time timestamp,
1491{ 1500{
1492 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); 1501 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1493 XEvent msg; 1502 XEvent msg;
1503 struct input_event ie;
1504 struct frame *self_frame;
1505 int root_x, root_y, win_x, win_y, i;
1506 unsigned int mask;
1507 Window root, child;
1508 Lisp_Object lval;
1509 char **atom_names;
1510 char *name;
1511
1512 self_frame = x_top_window_to_frame (dpyinfo, target);
1513
1514 if (self_frame)
1515 {
1516 /* Send a special drag-and-drop event when dropping on top of an
1517 Emacs frame to avoid all the overhead involved with sending
1518 client events. */
1519 EVENT_INIT (ie);
1520
1521 if (XQueryPointer (dpyinfo->display, FRAME_X_WINDOW (self_frame),
1522 &root, &child, &root_x, &root_y, &win_x, &win_y,
1523 &mask))
1524 {
1525 ie.kind = DRAG_N_DROP_EVENT;
1526 XSETFRAME (ie.frame_or_window, self_frame);
1527
1528 lval = Qnil;
1529 atom_names = alloca (x_dnd_n_targets * sizeof *atom_names);
1530 name = XGetAtomName (dpyinfo->display, x_dnd_wanted_action);
1531
1532 if (!XGetAtomNames (dpyinfo->display, x_dnd_targets,
1533 x_dnd_n_targets, atom_names))
1534 {
1535 XFree (name);
1536 return;
1537 }
1538
1539 for (i = x_dnd_n_targets; i != 0; --i)
1540 {
1541 lval = Fcons (intern (atom_names[i - 1]), lval);
1542 XFree (atom_names[i - 1]);
1543 }
1544
1545 lval = Fcons (intern (name), lval);
1546 lval = Fcons (QXdndSelection, lval);
1547 ie.arg = lval;
1548 ie.timestamp = CurrentTime;
1549
1550 XSETINT (ie.x, win_x);
1551 XSETINT (ie.y, win_y);
1552
1553 XFree (name);
1554 kbd_buffer_store_event (&ie);
1555
1556 return;
1557 }
1558 }
1494 1559
1495 msg.xclient.type = ClientMessage; 1560 msg.xclient.type = ClientMessage;
1496 msg.xclient.message_type = dpyinfo->Xatom_XdndDrop; 1561 msg.xclient.message_type = dpyinfo->Xatom_XdndDrop;