aboutsummaryrefslogtreecommitdiffstats
path: root/src/xselect.c
diff options
context:
space:
mode:
authorPo Lu2022-06-29 10:24:14 +0800
committerPo Lu2022-06-29 10:24:14 +0800
commit0e6516a1f022e18f4e32848331954deb0e850d4e (patch)
treeaaf82c350a8aee4ea7867587af7a6555ca6804af /src/xselect.c
parent9705609c0ef5e426606300da95fed4bec54923fb (diff)
downloademacs-0e6516a1f022e18f4e32848331954deb0e850d4e.tar.gz
emacs-0e6516a1f022e18f4e32848331954deb0e850d4e.zip
Fix reported problem with drag-and-drop inside VirtualBox
* lisp/x-dnd.el (x-dnd-handle-old-kde, x-dnd-handle-offix) (x-dnd-handle-motif): Select window before handling drop, like on Xdnd. (x-dnd-convert-to-offix, x-dnd-do-offix-drop) (x-dnd-handle-unsupported-drop): Accept local selection data and use that instead. * src/keyboard.c (kbd_buffer_get_event): Call unsupported drop function with local selection data as 8th arg. * src/xselect.c (x_get_local_selection): Accept new arg `local_value'. All callers changed. (Fx_get_local_selection): New function. (syms_of_xselect): Update defsubrs. * src/xterm.c (x_dnd_lose_ownership): New function. (x_dnd_begin_drag_and_drop): Unless new variable is true, disown XdndSelection after returning. This supposedly makes drag-and-drop from guest to host work in VirtualBox without causing pointer motion to become choppy afterwards. (syms_of_xterm): New variable `x_dnd_preserve_selection_data' and update doc string of `x-dnd-unsupported-drop-function'. * test/lisp/dnd-tests.el (dnd-tests-begin-text-drag) (dnd-tests-begin-file-drag, dnd-tests-begin-drag-files): Set new variable to nil during tests.
Diffstat (limited to 'src/xselect.c')
-rw-r--r--src/xselect.c74
1 files changed, 65 insertions, 9 deletions
diff --git a/src/xselect.c b/src/xselect.c
index d90916c6b63..a1f590632f8 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -307,18 +307,30 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
307 This function is used both for remote requests (LOCAL_REQUEST is zero) 307 This function is used both for remote requests (LOCAL_REQUEST is zero)
308 and for local x-get-selection-internal (LOCAL_REQUEST is nonzero). 308 and for local x-get-selection-internal (LOCAL_REQUEST is nonzero).
309 309
310 If LOCAL_VALUE is non-nil, use it as the local copy. Also allow
311 quitting in that case, and let DPYINFO be NULL.
312
310 This calls random Lisp code, and may signal or gc. */ 313 This calls random Lisp code, and may signal or gc. */
311 314
312static Lisp_Object 315static Lisp_Object
313x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, 316x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
314 bool local_request, struct x_display_info *dpyinfo) 317 bool local_request, struct x_display_info *dpyinfo,
318 Lisp_Object local_value)
315{ 319{
316 Lisp_Object local_value, tem; 320 Lisp_Object tem;
317 Lisp_Object handler_fn, value, check; 321 Lisp_Object handler_fn, value, check;
322 bool may_quit;
323 specpdl_ref count;
324
325 may_quit = false;
318 326
319 local_value = LOCAL_SELECTION (selection_symbol, dpyinfo); 327 if (NILP (local_value))
328 local_value = LOCAL_SELECTION (selection_symbol, dpyinfo);
329 else
330 may_quit = true;
320 331
321 if (NILP (local_value)) return Qnil; 332 if (NILP (local_value))
333 return Qnil;
322 334
323 /* TIMESTAMP is a special case. */ 335 /* TIMESTAMP is a special case. */
324 if (EQ (target_type, QTIMESTAMP)) 336 if (EQ (target_type, QTIMESTAMP))
@@ -331,8 +343,10 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
331 /* Don't allow a quit within the converter. 343 /* Don't allow a quit within the converter.
332 When the user types C-g, he would be surprised 344 When the user types C-g, he would be surprised
333 if by luck it came during a converter. */ 345 if by luck it came during a converter. */
334 specpdl_ref count = SPECPDL_INDEX (); 346 count = SPECPDL_INDEX ();
335 specbind (Qinhibit_quit, Qt); 347
348 if (!may_quit)
349 specbind (Qinhibit_quit, Qt);
336 350
337 CHECK_SYMBOL (target_type); 351 CHECK_SYMBOL (target_type);
338 handler_fn = Fcdr (Fassq (target_type, Vselection_converter_alist)); 352 handler_fn = Fcdr (Fassq (target_type, Vselection_converter_alist));
@@ -804,7 +818,9 @@ x_handle_selection_request (struct selection_input_event *event)
804 target that doesn't support XDND. */ 818 target that doesn't support XDND. */
805 if (SELECTION_EVENT_TIME (event) == pending_dnd_time + 1 819 if (SELECTION_EVENT_TIME (event) == pending_dnd_time + 1
806 || SELECTION_EVENT_TIME (event) == pending_dnd_time + 2) 820 || SELECTION_EVENT_TIME (event) == pending_dnd_time + 2)
807 selection_symbol = QXdndSelection; 821 /* Always reply with the contents of PRIMARY, since that's where
822 the selection data is. */
823 selection_symbol = QPRIMARY;
808 824
809 local_selection_data = LOCAL_SELECTION (selection_symbol, dpyinfo); 825 local_selection_data = LOCAL_SELECTION (selection_symbol, dpyinfo);
810 826
@@ -915,7 +931,7 @@ x_convert_selection (Lisp_Object selection_symbol,
915 931
916 lisp_selection 932 lisp_selection
917 = x_get_local_selection (selection_symbol, target_symbol, 933 = x_get_local_selection (selection_symbol, target_symbol,
918 false, dpyinfo); 934 false, dpyinfo, Qnil);
919 935
920 frame = selection_request_stack; 936 frame = selection_request_stack;
921 937
@@ -2131,7 +2147,7 @@ On Nextstep, TIME-STAMP and TERMINAL are unused. */)
2131 } 2147 }
2132 2148
2133 val = x_get_local_selection (selection_symbol, target_type, true, 2149 val = x_get_local_selection (selection_symbol, target_type, true,
2134 FRAME_DISPLAY_INFO (f)); 2150 FRAME_DISPLAY_INFO (f), Qnil);
2135 2151
2136 if (NILP (val) && FRAME_LIVE_P (f)) 2152 if (NILP (val) && FRAME_LIVE_P (f))
2137 { 2153 {
@@ -2273,6 +2289,45 @@ On Nextstep, TERMINAL is unused. */)
2273 return (owner ? Qt : Qnil); 2289 return (owner ? Qt : Qnil);
2274} 2290}
2275 2291
2292DEFUN ("x-get-local-selection", Fx_get_local_selection, Sx_get_local_selection,
2293 0, 2, 0,
2294 doc: /* Run selection converters for VALUE, and return the result.
2295TARGET is the selection target that is used to find a suitable
2296converter. VALUE is a list of 4 values NAME, SELECTION-VALUE,
2297TIMESTAMP and FRAME. NAME is the name of the selection that will be
2298passed to selection converters, SELECTION-VALUE is the value of the
2299selection used by the converter, TIMESTAMP is not meaningful (but must
2300be a number that fits in an X timestamp), and FRAME is the frame
2301describing the terminal for which the selection converter will be
2302run. */)
2303 (Lisp_Object value, Lisp_Object target)
2304{
2305 Time time;
2306 Lisp_Object name, timestamp, frame, result;
2307
2308 CHECK_SYMBOL (target);
2309 name = Fnth (make_fixnum (0), value);
2310 timestamp = Fnth (make_fixnum (2), value);
2311 frame = Fnth (make_fixnum (3), value);
2312
2313 CHECK_SYMBOL (name);
2314 CONS_TO_INTEGER (timestamp, Time, time);
2315 check_window_system (decode_live_frame (frame));
2316
2317 result = x_get_local_selection (name, target, true,
2318 NULL, value);
2319
2320 if (CONSP (result) && SYMBOLP (XCAR (result)))
2321 {
2322 result = XCDR (result);
2323
2324 if (CONSP (result) && NILP (XCDR (result)))
2325 result = XCAR (result);
2326 }
2327
2328 return clean_local_selection_data (result);
2329}
2330
2276 2331
2277/* Send clipboard manager a SAVE_TARGETS request with a UTF8_STRING 2332/* Send clipboard manager a SAVE_TARGETS request with a UTF8_STRING
2278 property (https://www.freedesktop.org/wiki/ClipboardManager/). */ 2333 property (https://www.freedesktop.org/wiki/ClipboardManager/). */
@@ -2809,6 +2864,7 @@ syms_of_xselect (void)
2809 defsubr (&Sx_get_atom_name); 2864 defsubr (&Sx_get_atom_name);
2810 defsubr (&Sx_send_client_message); 2865 defsubr (&Sx_send_client_message);
2811 defsubr (&Sx_register_dnd_atom); 2866 defsubr (&Sx_register_dnd_atom);
2867 defsubr (&Sx_get_local_selection);
2812 2868
2813 reading_selection_reply = Fcons (Qnil, Qnil); 2869 reading_selection_reply = Fcons (Qnil, Qnil);
2814 staticpro (&reading_selection_reply); 2870 staticpro (&reading_selection_reply);