aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-06-13 15:01:06 +0800
committerPo Lu2022-06-13 15:02:41 +0800
commita1a435b3f6c7afa910da2256334471ba49010974 (patch)
treeadd823f06b7f05d4dd4a57d54854e8af2ccae67f /src
parent7cd1f432c62d5677fb2d44ed05ed9546c3c292dc (diff)
downloademacs-a1a435b3f6c7afa910da2256334471ba49010974.tar.gz
emacs-a1a435b3f6c7afa910da2256334471ba49010974.zip
Respect test function when performing local drag-and-drop
* lisp/x-dnd.el (x-dnd-test-function): Fix doc string to describe what is actually accepted. (x-dnd-known-types, x-dnd-targets-list): Fix coding style. (x-dnd-handle-native-drop): New function. * src/xselect.c (x_atom_to_symbol): Export. * src/xterm.c (x_dnd_note_self_drop): Call new variable to determine what action to return. (x_clear_dnd_action): New function. (x_dnd_begin_drag_and_drop): Respect new variable. (syms_of_xterm): New defvar `x-dnd-native-test-function'. * src/xterm.h: Update prototypes.
Diffstat (limited to 'src')
-rw-r--r--src/xselect.c4
-rw-r--r--src/xterm.c54
-rw-r--r--src/xterm.h1
3 files changed, 52 insertions, 7 deletions
diff --git a/src/xselect.c b/src/xselect.c
index bb5a1447df7..490a008dfcb 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -112,7 +112,7 @@ selection_quantum (Display *display)
112 : MAX_SELECTION_QUANTUM); 112 : MAX_SELECTION_QUANTUM);
113} 113}
114 114
115#define LOCAL_SELECTION(selection_symbol,dpyinfo) \ 115#define LOCAL_SELECTION(selection_symbol, dpyinfo) \
116 assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist) 116 assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist)
117 117
118 118
@@ -179,7 +179,7 @@ symbol_to_x_atom (struct x_display_info *dpyinfo, Lisp_Object sym)
179/* This converts a server Atom to a Lisp symbol, avoiding server roundtrips 179/* This converts a server Atom to a Lisp symbol, avoiding server roundtrips
180 and calls to intern whenever possible. */ 180 and calls to intern whenever possible. */
181 181
182static Lisp_Object 182Lisp_Object
183x_atom_to_symbol (struct x_display_info *dpyinfo, Atom atom) 183x_atom_to_symbol (struct x_display_info *dpyinfo, Atom atom)
184{ 184{
185 char *str; 185 char *str;
diff --git a/src/xterm.c b/src/xterm.c
index 81b3b5cbeff..d9dd29ca128 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1228,6 +1228,10 @@ static XRectangle x_dnd_mouse_rect;
1228 protocol, this is set to the atom XdndActionPrivate. */ 1228 protocol, this is set to the atom XdndActionPrivate. */
1229static Atom x_dnd_action; 1229static Atom x_dnd_action;
1230 1230
1231/* The symbol to return from `x-begin-drag' if non-nil. Takes
1232 precedence over `x_dnd_action`. */
1233static Lisp_Object x_dnd_action_symbol;
1234
1231/* The action we want the drop target to perform. The drop target may 1235/* The action we want the drop target to perform. The drop target may
1232 elect to perform some different action, which is guaranteed to be 1236 elect to perform some different action, which is guaranteed to be
1233 in `x_dnd_action' upon completion of a drop. */ 1237 in `x_dnd_action' upon completion of a drop. */
@@ -1242,7 +1246,7 @@ static uint8_t x_dnd_motif_operations;
1242static uint8_t x_dnd_first_motif_operation; 1246static uint8_t x_dnd_first_motif_operation;
1243 1247
1244/* Array of selection targets available to the drop target. */ 1248/* Array of selection targets available to the drop target. */
1245static Atom *x_dnd_targets = NULL; 1249static Atom *x_dnd_targets;
1246 1250
1247/* The number of elements in that array. */ 1251/* The number of elements in that array. */
1248static int x_dnd_n_targets; 1252static int x_dnd_n_targets;
@@ -4298,15 +4302,30 @@ x_dnd_note_self_drop (struct x_display_info *dpyinfo, Window target,
4298 if (!f) 4302 if (!f)
4299 return; 4303 return;
4300 4304
4305 if (NILP (Vx_dnd_native_test_function))
4306 return;
4307
4301 if (!XTranslateCoordinates (dpyinfo->display, dpyinfo->root_window, 4308 if (!XTranslateCoordinates (dpyinfo->display, dpyinfo->root_window,
4302 FRAME_X_WINDOW (f), root_x, root_y, 4309 FRAME_X_WINDOW (f), root_x, root_y,
4303 &win_x, &win_y, &dummy)) 4310 &win_x, &win_y, &dummy))
4304 return; 4311 return;
4305 4312
4306 /* Emacs can't respond to DND events inside the nested event 4313 /* Emacs can't respond to DND events inside the nested event loop,
4307 loop, so when dragging items to itself, always return 4314 so when dragging items to itself, call the test function
4308 XdndActionPrivate. */ 4315 manually. */
4309 x_dnd_action = dpyinfo->Xatom_XdndActionPrivate; 4316
4317 XSETFRAME (lval, f);
4318 x_dnd_action = None;
4319 x_dnd_action_symbol
4320 = safe_call2 (Vx_dnd_native_test_function,
4321 Fposn_at_x_y (make_fixnum (win_x),
4322 make_fixnum (win_y),
4323 lval, Qnil),
4324 x_atom_to_symbol (dpyinfo,
4325 x_dnd_wanted_action));
4326
4327 if (!SYMBOLP (x_dnd_action_symbol))
4328 return;
4310 4329
4311 EVENT_INIT (ie); 4330 EVENT_INIT (ie);
4312 4331
@@ -10779,6 +10798,12 @@ x_detect_pending_selection_requests (void)
10779 return pending_selection_requests; 10798 return pending_selection_requests;
10780} 10799}
10781 10800
10801static void
10802x_clear_dnd_action (void)
10803{
10804 x_dnd_action_symbol = Qnil;
10805}
10806
10782/* This function is defined far away from the rest of the XDND code so 10807/* This function is defined far away from the rest of the XDND code so
10783 it can utilize `x_any_window_to_frame'. */ 10808 it can utilize `x_any_window_to_frame'. */
10784 10809
@@ -10922,6 +10947,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
10922 10947
10923 x_set_dnd_targets (target_atoms, ntargets); 10948 x_set_dnd_targets (target_atoms, ntargets);
10924 record_unwind_protect_void (x_free_dnd_targets); 10949 record_unwind_protect_void (x_free_dnd_targets);
10950 record_unwind_protect_void (x_clear_dnd_action);
10925 10951
10926 ltimestamp = x_timestamp_for_selection (FRAME_DISPLAY_INFO (f), 10952 ltimestamp = x_timestamp_for_selection (FRAME_DISPLAY_INFO (f),
10927 QXdndSelection); 10953 QXdndSelection);
@@ -11042,6 +11068,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
11042 x_dnd_last_motif_style = XM_DRAG_STYLE_NONE; 11068 x_dnd_last_motif_style = XM_DRAG_STYLE_NONE;
11043 x_dnd_mouse_rect_target = None; 11069 x_dnd_mouse_rect_target = None;
11044 x_dnd_action = None; 11070 x_dnd_action = None;
11071 x_dnd_action_symbol = Qnil;
11045 x_dnd_wanted_action = xaction; 11072 x_dnd_wanted_action = xaction;
11046 x_dnd_return_frame = 0; 11073 x_dnd_return_frame = 0;
11047 x_dnd_waiting_for_finish = false; 11074 x_dnd_waiting_for_finish = false;
@@ -11435,6 +11462,9 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
11435 x_dnd_return_frame_object = NULL; 11462 x_dnd_return_frame_object = NULL;
11436 FRAME_DISPLAY_INFO (f)->grabbed = 0; 11463 FRAME_DISPLAY_INFO (f)->grabbed = 0;
11437 11464
11465 if (!NILP (x_dnd_action_symbol))
11466 return unbind_to (base, x_dnd_action_symbol);
11467
11438 if (x_dnd_action != None) 11468 if (x_dnd_action != None)
11439 { 11469 {
11440 block_input (); 11470 block_input ();
@@ -26942,6 +26972,9 @@ syms_of_xterm (void)
26942 x_dnd_monitors = Qnil; 26972 x_dnd_monitors = Qnil;
26943 staticpro (&x_dnd_monitors); 26973 staticpro (&x_dnd_monitors);
26944 26974
26975 x_dnd_action_symbol = Qnil;
26976 staticpro (&x_dnd_action_symbol);
26977
26945 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms"); 26978 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
26946 DEFSYM (Qlatin_1, "latin-1"); 26979 DEFSYM (Qlatin_1, "latin-1");
26947 DEFSYM (Qnow, "now"); 26980 DEFSYM (Qnow, "now");
@@ -27189,4 +27222,15 @@ This variable contains the list of drag-and-drop selection targets
27189during a drag-and-drop operation, in the same format as the TARGET 27222during a drag-and-drop operation, in the same format as the TARGET
27190argument to `x-begin-drag'. */); 27223argument to `x-begin-drag'. */);
27191 Vx_dnd_targets_list = Qnil; 27224 Vx_dnd_targets_list = Qnil;
27225
27226 DEFVAR_LISP ("x-dnd-native-test-function", Vx_dnd_native_test_function,
27227 doc: /* Function called to determine return when dropping on Emacs itself.
27228It should accept two arguments POS and ACTION, and return a symbol
27229describing what to return from `x-begin-drag'. POS is a mouse
27230position list detailing the location of the drop, and ACTION is the
27231action specified by the caller of `x-begin-drag'.
27232
27233If nil or a non-symbol value is returned, the drop will be
27234cancelled. */);
27235 Vx_dnd_native_test_function = Qnil;
27192} 27236}
diff --git a/src/xterm.h b/src/xterm.h
index 25d145c6c0a..25c2453ee78 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1535,6 +1535,7 @@ extern void x_handle_property_notify (const XPropertyEvent *);
1535extern void x_handle_selection_notify (const XSelectionEvent *); 1535extern void x_handle_selection_notify (const XSelectionEvent *);
1536extern void x_handle_selection_event (struct selection_input_event *); 1536extern void x_handle_selection_event (struct selection_input_event *);
1537extern void x_clear_frame_selections (struct frame *); 1537extern void x_clear_frame_selections (struct frame *);
1538extern Lisp_Object x_atom_to_symbol (struct x_display_info *, Atom);
1538 1539
1539extern bool x_handle_dnd_message (struct frame *, 1540extern bool x_handle_dnd_message (struct frame *,
1540 const XClientMessageEvent *, 1541 const XClientMessageEvent *,