diff options
| author | Po Lu | 2022-07-07 18:36:56 +0800 |
|---|---|---|
| committer | Po Lu | 2022-07-07 18:39:51 +0800 |
| commit | 7a9f8ed6fba0d6728cbf185696bdc1a95b1acfea (patch) | |
| tree | 2033d43b4cd6d48568acd42918821793406dd4ef /src | |
| parent | a40a4d3a0964f0428033744f77b67376700e963f (diff) | |
| download | emacs-7a9f8ed6fba0d6728cbf185696bdc1a95b1acfea.tar.gz emacs-7a9f8ed6fba0d6728cbf185696bdc1a95b1acfea.zip | |
Fix quitting out of selection converters during drag and drop
* src/xterm.c (x_dnd_process_quit): New function.
(x_dnd_begin_drag_and_drop): Use it instead. Also quit if
quit-flag is true immediately after a selection converter is
run.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 110 |
1 files changed, 65 insertions, 45 deletions
diff --git a/src/xterm.c b/src/xterm.c index a21daa2dfc0..98a5beed178 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -11362,6 +11362,57 @@ x_dnd_lose_ownership (Lisp_Object timestamp_and_frame) | |||
| 11362 | XCDR (timestamp_and_frame)); | 11362 | XCDR (timestamp_and_frame)); |
| 11363 | } | 11363 | } |
| 11364 | 11364 | ||
| 11365 | /* Clean up an existing drag-and-drop operation in preparation for its | ||
| 11366 | sudden termination. */ | ||
| 11367 | |||
| 11368 | static void | ||
| 11369 | x_dnd_process_quit (struct frame *f, Time timestamp) | ||
| 11370 | { | ||
| 11371 | xm_drop_start_message dmsg; | ||
| 11372 | |||
| 11373 | if (x_dnd_in_progress) | ||
| 11374 | { | ||
| 11375 | if (x_dnd_last_seen_window != None | ||
| 11376 | && x_dnd_last_protocol_version != -1) | ||
| 11377 | x_dnd_send_leave (f, x_dnd_last_seen_window); | ||
| 11378 | else if (x_dnd_last_seen_window != None | ||
| 11379 | && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style) | ||
| 11380 | && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE | ||
| 11381 | && x_dnd_motif_setup_p) | ||
| 11382 | { | ||
| 11383 | dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR, | ||
| 11384 | XM_DRAG_REASON_DROP_START); | ||
| 11385 | dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST; | ||
| 11386 | dmsg.timestamp = timestamp; | ||
| 11387 | dmsg.side_effects | ||
| 11388 | = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), | ||
| 11389 | x_dnd_wanted_action), | ||
| 11390 | XM_DROP_SITE_VALID, x_dnd_motif_operations, | ||
| 11391 | XM_DROP_ACTION_DROP_CANCEL); | ||
| 11392 | dmsg.x = 0; | ||
| 11393 | dmsg.y = 0; | ||
| 11394 | dmsg.index_atom = x_dnd_motif_atom; | ||
| 11395 | dmsg.source_window = FRAME_X_WINDOW (f); | ||
| 11396 | |||
| 11397 | x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f, | ||
| 11398 | x_dnd_last_seen_window, | ||
| 11399 | timestamp); | ||
| 11400 | xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f), | ||
| 11401 | x_dnd_last_seen_window, &dmsg); | ||
| 11402 | } | ||
| 11403 | |||
| 11404 | x_dnd_end_window = x_dnd_last_seen_window; | ||
| 11405 | x_dnd_last_seen_window = None; | ||
| 11406 | x_dnd_last_seen_toplevel = None; | ||
| 11407 | x_dnd_in_progress = false; | ||
| 11408 | x_dnd_frame = NULL; | ||
| 11409 | } | ||
| 11410 | |||
| 11411 | x_dnd_waiting_for_finish = false; | ||
| 11412 | x_dnd_return_frame_object = NULL; | ||
| 11413 | x_dnd_movement_frame = NULL; | ||
| 11414 | } | ||
| 11415 | |||
| 11365 | /* This function is defined far away from the rest of the XDND code so | 11416 | /* This function is defined far away from the rest of the XDND code so |
| 11366 | it can utilize `x_any_window_to_frame'. */ | 11417 | it can utilize `x_any_window_to_frame'. */ |
| 11367 | 11418 | ||
| @@ -11398,7 +11449,6 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 11398 | specpdl_ref ref, count, base; | 11449 | specpdl_ref ref, count, base; |
| 11399 | ptrdiff_t i, end, fill; | 11450 | ptrdiff_t i, end, fill; |
| 11400 | XTextProperty prop; | 11451 | XTextProperty prop; |
| 11401 | xm_drop_start_message dmsg; | ||
| 11402 | Lisp_Object frame_object, x, y, frame, local_value; | 11452 | Lisp_Object frame_object, x, y, frame, local_value; |
| 11403 | bool signals_were_pending, need_sync; | 11453 | bool signals_were_pending, need_sync; |
| 11404 | #ifdef HAVE_XKB | 11454 | #ifdef HAVE_XKB |
| @@ -11750,50 +11800,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 11750 | 11800 | ||
| 11751 | if (hold_quit.kind != NO_EVENT) | 11801 | if (hold_quit.kind != NO_EVENT) |
| 11752 | { | 11802 | { |
| 11753 | if (x_dnd_in_progress) | 11803 | x_dnd_process_quit (f, hold_quit.timestamp); |
| 11754 | { | ||
| 11755 | if (x_dnd_last_seen_window != None | ||
| 11756 | && x_dnd_last_protocol_version != -1) | ||
| 11757 | x_dnd_send_leave (f, x_dnd_last_seen_window); | ||
| 11758 | else if (x_dnd_last_seen_window != None | ||
| 11759 | && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style) | ||
| 11760 | && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE | ||
| 11761 | && x_dnd_motif_setup_p) | ||
| 11762 | { | ||
| 11763 | dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR, | ||
| 11764 | XM_DRAG_REASON_DROP_START); | ||
| 11765 | dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST; | ||
| 11766 | dmsg.timestamp = hold_quit.timestamp; | ||
| 11767 | dmsg.side_effects | ||
| 11768 | = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), | ||
| 11769 | x_dnd_wanted_action), | ||
| 11770 | XM_DROP_SITE_VALID, x_dnd_motif_operations, | ||
| 11771 | XM_DROP_ACTION_DROP_CANCEL); | ||
| 11772 | dmsg.x = 0; | ||
| 11773 | dmsg.y = 0; | ||
| 11774 | dmsg.index_atom = x_dnd_motif_atom; | ||
| 11775 | dmsg.source_window = FRAME_X_WINDOW (f); | ||
| 11776 | |||
| 11777 | x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f, | ||
| 11778 | x_dnd_last_seen_window, | ||
| 11779 | hold_quit.timestamp); | ||
| 11780 | xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f), | ||
| 11781 | x_dnd_last_seen_window, &dmsg); | ||
| 11782 | } | ||
| 11783 | |||
| 11784 | x_dnd_end_window = x_dnd_last_seen_window; | ||
| 11785 | x_dnd_last_seen_window = None; | ||
| 11786 | x_dnd_last_seen_toplevel = None; | ||
| 11787 | x_dnd_in_progress = false; | ||
| 11788 | x_dnd_frame = NULL; | ||
| 11789 | } | ||
| 11790 | |||
| 11791 | x_dnd_waiting_for_finish = false; | ||
| 11792 | x_dnd_return_frame_object = NULL; | ||
| 11793 | x_dnd_movement_frame = NULL; | ||
| 11794 | |||
| 11795 | /* Don't clear dpyinfo->grabbed if we're quitting. */ | ||
| 11796 | |||
| 11797 | #ifdef USE_GTK | 11804 | #ifdef USE_GTK |
| 11798 | current_hold_quit = NULL; | 11805 | current_hold_quit = NULL; |
| 11799 | #endif | 11806 | #endif |
| @@ -11821,6 +11828,19 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 11821 | unbind_to (ref, Qnil); | 11828 | unbind_to (ref, Qnil); |
| 11822 | } | 11829 | } |
| 11823 | 11830 | ||
| 11831 | /* Sometimes C-g can be pressed inside a selection | ||
| 11832 | converter, where quitting is inhibited. We want | ||
| 11833 | to quit after the converter exits. */ | ||
| 11834 | if (!NILP (Vquit_flag) && !NILP (Vinhibit_quit)) | ||
| 11835 | { | ||
| 11836 | x_dnd_process_quit (f, FRAME_DISPLAY_INFO (f)->last_user_time); | ||
| 11837 | #ifdef USE_GTK | ||
| 11838 | current_hold_quit = NULL; | ||
| 11839 | #endif | ||
| 11840 | x_restore_events_after_dnd (f, &root_window_attrs); | ||
| 11841 | quit (); | ||
| 11842 | } | ||
| 11843 | |||
| 11824 | if (x_dnd_run_unsupported_drop_function | 11844 | if (x_dnd_run_unsupported_drop_function |
| 11825 | && x_dnd_waiting_for_finish) | 11845 | && x_dnd_waiting_for_finish) |
| 11826 | { | 11846 | { |