aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-07-07 18:36:56 +0800
committerPo Lu2022-07-07 18:39:51 +0800
commit7a9f8ed6fba0d6728cbf185696bdc1a95b1acfea (patch)
tree2033d43b4cd6d48568acd42918821793406dd4ef /src
parenta40a4d3a0964f0428033744f77b67376700e963f (diff)
downloademacs-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.c110
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
11368static void
11369x_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 {