emacs-diffs
[Top][All Lists]
Advanced

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

master 01834ba0c9: Remove selection requests on the keyboard buffer when


From: Po Lu
Subject: master 01834ba0c9: Remove selection requests on the keyboard buffer when closing display
Date: Mon, 20 Jun 2022 21:53:28 -0400 (EDT)

branch: master
commit 01834ba0c9c1ed5d6b25a1463b79b00e2fc7266b
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Remove selection requests on the keyboard buffer when closing display
    
    * src/xterm.c (X_NEXT_KBD_EVENT): New macro.
    (x_defer_selection_requests): Set input_pending if the kbd
    buffer was modified.
    (x_delete_selection_requests): New function.
    (x_delete_display): Call that.  Bug found when a display died
    while the clipboard manager was sending an unreasonably high
    number of requests.
---
 src/xterm.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 55 insertions(+), 4 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index b5543b873c..ee78da085e 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -802,6 +802,10 @@ static struct input_event *current_hold_quit;
    than 0.  */
 static int x_use_pending_selection_requests;
 
+/* Like `next_kbd_event', but for use in X code.  */
+#define X_NEXT_KBD_EVENT(ptr) \
+  ((ptr) == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : (ptr) + 1)
+
 static void x_push_selection_request (struct selection_input_event *);
 
 /* Defer selection requests.  Between this and
@@ -838,14 +842,12 @@ x_defer_selection_requests (void)
                 avoids exhausting the keyboard buffer with some
                 over-enthusiastic clipboard managers.  */
              if (!between)
-               kbd_fetch_ptr = (event == kbd_buffer + KBD_BUFFER_SIZE - 1
-                                ? kbd_buffer : event + 1);
+               kbd_fetch_ptr = X_NEXT_KBD_EVENT (event);
            }
          else
            between = true;
 
-         event = (event == kbd_buffer + KBD_BUFFER_SIZE - 1
-                  ? kbd_buffer : event + 1);
+         event = X_NEXT_KBD_EVENT (event);
        }
     }
 
@@ -26969,7 +26971,54 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
 
   return dpyinfo;
 }
+
 
+
+/* Remove all the selection input events on the keyboard buffer
+   intended for DPYINFO.  */
+
+static void
+x_delete_selection_requests (struct x_display_info *dpyinfo)
+{
+  union buffered_input_event *event;
+  int moved_events;
+
+  for (event = kbd_fetch_ptr; event != kbd_store_ptr;
+       event = X_NEXT_KBD_EVENT (event))
+    {
+      if (event->kind == SELECTION_REQUEST_EVENT
+         || event->kind == SELECTION_CLEAR_EVENT)
+       {
+         if (SELECTION_EVENT_DPYINFO (&event->sie) != dpyinfo)
+           continue;
+
+         /* Remove the event from the fifo buffer before processing;
+            otherwise swallow_events called recursively could see it
+            and process it again.  To do this, we move the events
+            between kbd_fetch_ptr and EVENT one slot to the right,
+            cyclically.  */
+
+         if (event < kbd_fetch_ptr)
+           {
+             memmove (kbd_buffer + 1, kbd_buffer,
+                      (event - kbd_buffer) * sizeof *kbd_buffer);
+             kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1];
+             moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr;
+           }
+         else
+           moved_events = event - kbd_fetch_ptr;
+
+         memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr,
+                  moved_events * sizeof *kbd_fetch_ptr);
+         kbd_fetch_ptr = X_NEXT_KBD_EVENT (kbd_fetch_ptr);
+
+         /* `detect_input_pending' will then recompute whether or not
+            pending input events exist.  */
+         input_pending = false;
+       }
+    }
+}
+
 /* Get rid of display DPYINFO, deleting all frames on it,
    and without sending any more commands to the X server.  */
 
@@ -27019,6 +27068,8 @@ x_delete_display (struct x_display_info *dpyinfo)
       last = ie;
     }
 
+  x_delete_selection_requests (dpyinfo);
+
   if (next_noop_dpyinfo == dpyinfo)
     next_noop_dpyinfo = dpyinfo->next;
 



reply via email to

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