diff options
| author | Po Lu | 2022-03-26 10:15:53 +0800 |
|---|---|---|
| committer | Po Lu | 2022-03-26 10:15:53 +0800 |
| commit | 5359062be603e22d1ee07c21b0840fdb98a704a3 (patch) | |
| tree | f278bf1a27d04b21d19703d2995478c565db76ad /src | |
| parent | 21ecf6b24d0549a9f27bcab51dbd8c8b1a37ef86 (diff) | |
| download | emacs-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.c | 65 |
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; |