emacs-diffs
[Top][All Lists]
Advanced

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

master 93b31707e9: Fix preserving selections if `x-lost-selection-functi


From: Po Lu
Subject: master 93b31707e9: Fix preserving selections if `x-lost-selection-functions' signals
Date: Tue, 12 Jul 2022 03:14:37 -0400 (EDT)

branch: master
commit 93b31707e97f8ddf11aa8acbf5c61bc29b5f7528
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Fix preserving selections if `x-lost-selection-functions' signals
    
    * src/xterm.c (x_preserve_selections): Get selection owner and
    run lost selection hook separately.
---
 src/xterm.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 50 insertions(+), 4 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index f86e4708ec..a13162d61b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -27960,7 +27960,10 @@ x_preserve_selections (struct x_display_info *dpyinfo, 
Lisp_Object lost)
 {
   Lisp_Object tail, frame, new_owner, tem;
   Time timestamp;
-  Window owner;
+  Window *owners;
+  Atom *names;
+  ptrdiff_t nowners, counter;
+  struct selection_input_event clear;
 
   new_owner = Qnil;
 
@@ -27975,10 +27978,12 @@ x_preserve_selections (struct x_display_info 
*dpyinfo, Lisp_Object lost)
     }
 
   tail = lost;
+  nowners = 0;
 
   FOR_EACH_TAIL_SAFE (tail)
     {
       tem = XCAR (tail);
+      ++nowners;
 
       /* The selection is really lost (since we cannot find a new
         owner), so run the appropriate hooks.  */
@@ -27994,13 +27999,54 @@ x_preserve_selections (struct x_display_info 
*dpyinfo, Lisp_Object lost)
          x_own_selection (XCAR (tem), XCAR (XCDR (tem)),
                           new_owner, XCAR (XCDR (XCDR (XCDR (XCDR (tem))))),
                           timestamp);
+       }
+    }
+
+  if (!NILP (new_owner))
+    {
+      owners = alloca (sizeof *owners * nowners);
+      names = alloca (sizeof *names * nowners);
+
+      tail = lost;
+      nowners = 0;
+      counter = 0;
+
+      FOR_EACH_TAIL_SAFE (tail)
+       {
+         tem = XCAR (tail);
 
          /* Now check if we still don't own that selection, which can
             happen if another program set itself as the owner.  */
-         owner = XGetSelectionOwner (dpyinfo->display,
-                                     symbol_to_x_atom (dpyinfo, XCAR (tem)));
+         names[counter++] = symbol_to_x_atom (dpyinfo, XCAR (tem));
+         owners[nowners++] = XGetSelectionOwner (dpyinfo->display,
+                                                 names[counter - 1]);
+
+         if (owners[nowners - 1] != FRAME_X_WINDOW (XFRAME (new_owner)))
+           {
+             /* Clear the local selection, since we know we don't own
+                it any longer.  */
+             CONS_TO_INTEGER (XCAR (XCDR (XCDR (tem))), Time, timestamp);
+
+             clear.kind = SELECTION_CLEAR_EVENT;
+
+             SELECTION_EVENT_DPYINFO (&clear) = dpyinfo;
+             SELECTION_EVENT_SELECTION (&clear) = names[nowners - 1];
+             SELECTION_EVENT_TIME (&clear) = timestamp;
+
+             x_handle_selection_event (&clear);
+           }
+       }
+
+      tail = lost;
+      nowners = 0;
+
+      FOR_EACH_TAIL_SAFE (tail)
+       {
+         tem = XCAR (tail);
 
-         if (owner != FRAME_X_WINDOW (XFRAME (new_owner)))
+         /* If the selection isn't owned by us anymore, note that the
+            selection was lost.  */
+         if (owners[nowners++] != FRAME_X_WINDOW (XFRAME (new_owner)))
            CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
                   XCAR (tem));
        }



reply via email to

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