aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-03-16 12:33:15 +0800
committerPo Lu2022-03-16 12:33:15 +0800
commitf62a6acd00fa5045fbc537bcaa87756416e246a4 (patch)
treeff29580e4f687a5d5ec7841486cd1d62f002f27f /src
parent5ff13718a53c161c3a0d3e8795544a740c10064b (diff)
downloademacs-f62a6acd00fa5045fbc537bcaa87756416e246a4.tar.gz
emacs-f62a6acd00fa5045fbc537bcaa87756416e246a4.zip
Better handle drag-and-drop from one Emacs frame to another
* doc/lispref/frames.texi (Drag and Drop): Document new parameter `return-frame' to `x-begin-drag'. * lisp/mouse.el (mouse-drag-and-drop-region): Utilize new feature. * src/xfns.c (Fx_begin_drag): New parameter `return-frame'. * src/xterm.c (x_dnd_begin_drag_and_drop): New parameter return_frame_p. (handle_one_xevent): Set new flags and return frame whenever appropriate. * src/xterm.h: Update prototypes.
Diffstat (limited to 'src')
-rw-r--r--src/xfns.c11
-rw-r--r--src/xterm.c50
-rw-r--r--src/xterm.h3
3 files changed, 59 insertions, 5 deletions
diff --git a/src/xfns.c b/src/xfns.c
index 0d197c1dd7d..b5d0b2c54e8 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -6582,7 +6582,7 @@ The coordinates X and Y are interpreted in pixels relative to a position
6582 return Qnil; 6582 return Qnil;
6583} 6583}
6584 6584
6585DEFUN ("x-begin-drag", Fx_begin_drag, Sx_begin_drag, 1, 3, 0, 6585DEFUN ("x-begin-drag", Fx_begin_drag, Sx_begin_drag, 1, 4, 0,
6586 doc: /* Begin dragging contents on FRAME, with targets TARGETS. 6586 doc: /* Begin dragging contents on FRAME, with targets TARGETS.
6587TARGETS is a list of strings, which defines the X selection targets 6587TARGETS is a list of strings, which defines the X selection targets
6588that will be available to the drop target. Block until the mouse 6588that will be available to the drop target. Block until the mouse
@@ -6607,9 +6607,14 @@ Emacs. For that reason, they are not mentioned here. Consult
6607"Drag-and-Drop Protocol for the X Window System" for more details: 6607"Drag-and-Drop Protocol for the X Window System" for more details:
6608https://freedesktop.org/wiki/Specifications/XDND/. 6608https://freedesktop.org/wiki/Specifications/XDND/.
6609 6609
6610If RETURN-FRAME is non-nil, this function will return the frame if the
6611mouse pointer moves onto an Emacs frame, after first moving out of
6612FRAME.
6613
6610If ACTION is not specified or nil, `XdndActionCopy' is used 6614If ACTION is not specified or nil, `XdndActionCopy' is used
6611instead. */) 6615instead. */)
6612 (Lisp_Object targets, Lisp_Object action, Lisp_Object frame) 6616 (Lisp_Object targets, Lisp_Object action, Lisp_Object frame,
6617 Lisp_Object return_frame)
6613{ 6618{
6614 struct frame *f = decode_window_system_frame (frame); 6619 struct frame *f = decode_window_system_frame (frame);
6615 int ntargets = 0; 6620 int ntargets = 0;
@@ -6655,7 +6660,7 @@ instead. */)
6655 6660
6656 x_set_dnd_targets (target_atoms, ntargets); 6661 x_set_dnd_targets (target_atoms, ntargets);
6657 lval = x_dnd_begin_drag_and_drop (f, FRAME_DISPLAY_INFO (f)->last_user_time, 6662 lval = x_dnd_begin_drag_and_drop (f, FRAME_DISPLAY_INFO (f)->last_user_time,
6658 xaction); 6663 xaction, !NILP (return_frame));
6659 6664
6660 return lval; 6665 return lval;
6661} 6666}
diff --git a/src/xterm.c b/src/xterm.c
index 8a4344f2a4f..a3d20a9d226 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -771,6 +771,15 @@ static void x_scroll_bar_end_update (struct x_display_info *, struct scroll_bar
771#endif 771#endif
772 772
773static bool x_dnd_in_progress; 773static bool x_dnd_in_progress;
774
775/* Whether or not to return a frame from `x_dnd_begin_drag_and_drop'.
776
777 0 means to do nothing. 1 means to wait for the mouse to first exit
778 `x_dnd_frame'. 2 means to wait for the mouse to move onto a frame,
779 and 3 means to `x_dnd_return_frame_object'. */
780static int x_dnd_return_frame;
781static struct frame *x_dnd_return_frame_object;
782
774static Window x_dnd_last_seen_window; 783static Window x_dnd_last_seen_window;
775static int x_dnd_last_protocol_version; 784static int x_dnd_last_protocol_version;
776static Time x_dnd_selection_timestamp; 785static Time x_dnd_selection_timestamp;
@@ -1025,7 +1034,8 @@ x_set_dnd_targets (Atom *targets, int ntargets)
1025} 1034}
1026 1035
1027Lisp_Object 1036Lisp_Object
1028x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction) 1037x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
1038 bool return_frame_p)
1029{ 1039{
1030 XEvent next_event; 1040 XEvent next_event;
1031 struct input_event hold_quit; 1041 struct input_event hold_quit;
@@ -1054,6 +1064,10 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction)
1054 x_dnd_mouse_rect_target = None; 1064 x_dnd_mouse_rect_target = None;
1055 x_dnd_action = None; 1065 x_dnd_action = None;
1056 x_dnd_wanted_action = xaction; 1066 x_dnd_wanted_action = xaction;
1067 x_dnd_return_frame = 0;
1068
1069 if (return_frame_p)
1070 x_dnd_return_frame = 1;
1057 1071
1058 while (x_dnd_in_progress) 1072 while (x_dnd_in_progress)
1059 { 1073 {
@@ -1085,6 +1099,14 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction)
1085 } 1099 }
1086 } 1100 }
1087 1101
1102 if (x_dnd_return_frame == 3)
1103 {
1104 x_dnd_return_frame_object->mouse_moved = true;
1105
1106 XSETFRAME (action, x_dnd_return_frame_object);
1107 return action;
1108 }
1109
1088 FRAME_DISPLAY_INFO (f)->grabbed = 0; 1110 FRAME_DISPLAY_INFO (f)->grabbed = 0;
1089 1111
1090 if (x_dnd_wanted_action != None) 1112 if (x_dnd_wanted_action != None)
@@ -11606,6 +11628,19 @@ handle_one_xevent (struct x_display_info *dpyinfo,
11606 && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame)) 11628 && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame))
11607 x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); 11629 x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window);
11608 11630
11631 if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame)
11632 && x_dnd_return_frame == 1)
11633 x_dnd_return_frame = 2;
11634
11635 if (x_dnd_return_frame == 2
11636 && x_window_to_frame (dpyinfo, target))
11637 {
11638 x_dnd_in_progress = false;
11639 x_dnd_return_frame_object
11640 = x_window_to_frame (dpyinfo, target);
11641 x_dnd_return_frame = 3;
11642 }
11643
11609 x_dnd_wanted_action = None; 11644 x_dnd_wanted_action = None;
11610 x_dnd_last_seen_window = target; 11645 x_dnd_last_seen_window = target;
11611 x_dnd_last_protocol_version 11646 x_dnd_last_protocol_version
@@ -12825,6 +12860,19 @@ handle_one_xevent (struct x_display_info *dpyinfo,
12825 && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame)) 12860 && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame))
12826 x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); 12861 x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window);
12827 12862
12863 if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame)
12864 && x_dnd_return_frame == 1)
12865 x_dnd_return_frame = 2;
12866
12867 if (x_dnd_return_frame == 2
12868 && x_window_to_frame (dpyinfo, target))
12869 {
12870 x_dnd_in_progress = false;
12871 x_dnd_return_frame_object
12872 = x_window_to_frame (dpyinfo, target);
12873 x_dnd_return_frame = 3;
12874 }
12875
12828 x_dnd_last_seen_window = target; 12876 x_dnd_last_seen_window = target;
12829 x_dnd_last_protocol_version 12877 x_dnd_last_protocol_version
12830 = x_dnd_get_window_proto (dpyinfo, target); 12878 = x_dnd_get_window_proto (dpyinfo, target);
diff --git a/src/xterm.h b/src/xterm.h
index 225aaf4cad5..9665e92a9fb 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1367,7 +1367,8 @@ extern void x_scroll_bar_configure (GdkEvent *);
1367 1367
1368extern void x_display_set_last_user_time (struct x_display_info *, Time); 1368extern void x_display_set_last_user_time (struct x_display_info *, Time);
1369 1369
1370extern Lisp_Object x_dnd_begin_drag_and_drop (struct frame *, Time, Atom); 1370extern Lisp_Object x_dnd_begin_drag_and_drop (struct frame *, Time, Atom,
1371 bool);
1371extern void x_set_dnd_targets (Atom *, int); 1372extern void x_set_dnd_targets (Atom *, int);
1372 1373
1373INLINE int 1374INLINE int