emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 7a9f8ed6fb: Fix quitting out of selection converters during drag


From: Po Lu
Subject: master 7a9f8ed6fb: Fix quitting out of selection converters during drag and drop
Date: Thu, 7 Jul 2022 06:40:01 -0400 (EDT)

branch: master
commit 7a9f8ed6fba0d6728cbf185696bdc1a95b1acfea
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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.
---
 src/xterm.c | 110 +++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 65 insertions(+), 45 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index a21daa2dfc..98a5beed17 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -11362,6 +11362,57 @@ x_dnd_lose_ownership (Lisp_Object timestamp_and_frame)
                                  XCDR (timestamp_and_frame));
 }
 
+/* Clean up an existing drag-and-drop operation in preparation for its
+   sudden termination.  */
+
+static void
+x_dnd_process_quit (struct frame *f, Time timestamp)
+{
+  xm_drop_start_message dmsg;
+
+  if (x_dnd_in_progress)
+    {
+      if (x_dnd_last_seen_window != None
+         && x_dnd_last_protocol_version != -1)
+       x_dnd_send_leave (f, x_dnd_last_seen_window);
+      else if (x_dnd_last_seen_window != None
+              && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
+              && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
+              && x_dnd_motif_setup_p)
+       {
+         dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
+                                       XM_DRAG_REASON_DROP_START);
+         dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
+         dmsg.timestamp = timestamp;
+         dmsg.side_effects
+           = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action 
(FRAME_DISPLAY_INFO (f),
+                                                              
x_dnd_wanted_action),
+                                  XM_DROP_SITE_VALID, x_dnd_motif_operations,
+                                  XM_DROP_ACTION_DROP_CANCEL);
+         dmsg.x = 0;
+         dmsg.y = 0;
+         dmsg.index_atom = x_dnd_motif_atom;
+         dmsg.source_window = FRAME_X_WINDOW (f);
+
+         x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
+                                       x_dnd_last_seen_window,
+                                       timestamp);
+         xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
+                               x_dnd_last_seen_window, &dmsg);
+       }
+
+      x_dnd_end_window = x_dnd_last_seen_window;
+      x_dnd_last_seen_window = None;
+      x_dnd_last_seen_toplevel = None;
+      x_dnd_in_progress = false;
+      x_dnd_frame = NULL;
+    }
+
+  x_dnd_waiting_for_finish = false;
+  x_dnd_return_frame_object = NULL;
+  x_dnd_movement_frame = NULL;
+}
+
 /* This function is defined far away from the rest of the XDND code so
    it can utilize `x_any_window_to_frame'.  */
 
@@ -11398,7 +11449,6 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, 
Atom xaction,
   specpdl_ref ref, count, base;
   ptrdiff_t i, end, fill;
   XTextProperty prop;
-  xm_drop_start_message dmsg;
   Lisp_Object frame_object, x, y, frame, local_value;
   bool signals_were_pending, need_sync;
 #ifdef HAVE_XKB
@@ -11750,50 +11800,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, 
Atom xaction,
 
          if (hold_quit.kind != NO_EVENT)
            {
-             if (x_dnd_in_progress)
-               {
-                 if (x_dnd_last_seen_window != None
-                     && x_dnd_last_protocol_version != -1)
-                   x_dnd_send_leave (f, x_dnd_last_seen_window);
-                 else if (x_dnd_last_seen_window != None
-                          && !XM_DRAG_STYLE_IS_DROP_ONLY 
(x_dnd_last_motif_style)
-                          && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
-                          && x_dnd_motif_setup_p)
-                   {
-                     dmsg.reason = XM_DRAG_REASON 
(XM_DRAG_ORIGINATOR_INITIATOR,
-                                                   XM_DRAG_REASON_DROP_START);
-                     dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
-                     dmsg.timestamp = hold_quit.timestamp;
-                     dmsg.side_effects
-                       = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action 
(FRAME_DISPLAY_INFO (f),
-                                                                          
x_dnd_wanted_action),
-                                              XM_DROP_SITE_VALID, 
x_dnd_motif_operations,
-                                              XM_DROP_ACTION_DROP_CANCEL);
-                     dmsg.x = 0;
-                     dmsg.y = 0;
-                     dmsg.index_atom = x_dnd_motif_atom;
-                     dmsg.source_window = FRAME_X_WINDOW (f);
-
-                     x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
-                                                   x_dnd_last_seen_window,
-                                                   hold_quit.timestamp);
-                     xm_send_drop_message (FRAME_DISPLAY_INFO (f), 
FRAME_X_WINDOW (f),
-                                           x_dnd_last_seen_window, &dmsg);
-                   }
-
-                 x_dnd_end_window = x_dnd_last_seen_window;
-                 x_dnd_last_seen_window = None;
-                 x_dnd_last_seen_toplevel = None;
-                 x_dnd_in_progress = false;
-                 x_dnd_frame = NULL;
-               }
-
-             x_dnd_waiting_for_finish = false;
-             x_dnd_return_frame_object = NULL;
-             x_dnd_movement_frame = NULL;
-
-             /* Don't clear dpyinfo->grabbed if we're quitting.  */
-
+             x_dnd_process_quit (f, hold_quit.timestamp);
 #ifdef USE_GTK
              current_hold_quit = NULL;
 #endif
@@ -11821,6 +11828,19 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, 
Atom xaction,
              unbind_to (ref, Qnil);
            }
 
+         /* Sometimes C-g can be pressed inside a selection
+            converter, where quitting is inhibited.  We want
+            to quit after the converter exits.  */
+         if (!NILP (Vquit_flag) && !NILP (Vinhibit_quit))
+           {
+             x_dnd_process_quit (f, FRAME_DISPLAY_INFO (f)->last_user_time);
+#ifdef USE_GTK
+             current_hold_quit = NULL;
+#endif
+             x_restore_events_after_dnd (f, &root_window_attrs);
+             quit ();
+           }
+
          if (x_dnd_run_unsupported_drop_function
              && x_dnd_waiting_for_finish)
            {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]