aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-07-12 15:14:04 +0800
committerPo Lu2022-07-12 15:14:25 +0800
commit93b31707e97f8ddf11aa8acbf5c61bc29b5f7528 (patch)
treead450cc67fcd4c27938e754f1e62f53aaf416d35 /src
parenta837c59d9eca748e3895ae09e82373531222aef6 (diff)
downloademacs-93b31707e97f8ddf11aa8acbf5c61bc29b5f7528.tar.gz
emacs-93b31707e97f8ddf11aa8acbf5c61bc29b5f7528.zip
Fix preserving selections if `x-lost-selection-functions' signals
* src/xterm.c (x_preserve_selections): Get selection owner and run lost selection hook separately.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/src/xterm.c b/src/xterm.c
index f86e4708ec5..a13162d61be 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -27960,7 +27960,10 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost)
27960{ 27960{
27961 Lisp_Object tail, frame, new_owner, tem; 27961 Lisp_Object tail, frame, new_owner, tem;
27962 Time timestamp; 27962 Time timestamp;
27963 Window owner; 27963 Window *owners;
27964 Atom *names;
27965 ptrdiff_t nowners, counter;
27966 struct selection_input_event clear;
27964 27967
27965 new_owner = Qnil; 27968 new_owner = Qnil;
27966 27969
@@ -27975,10 +27978,12 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost)
27975 } 27978 }
27976 27979
27977 tail = lost; 27980 tail = lost;
27981 nowners = 0;
27978 27982
27979 FOR_EACH_TAIL_SAFE (tail) 27983 FOR_EACH_TAIL_SAFE (tail)
27980 { 27984 {
27981 tem = XCAR (tail); 27985 tem = XCAR (tail);
27986 ++nowners;
27982 27987
27983 /* The selection is really lost (since we cannot find a new 27988 /* The selection is really lost (since we cannot find a new
27984 owner), so run the appropriate hooks. */ 27989 owner), so run the appropriate hooks. */
@@ -27994,13 +27999,54 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost)
27994 x_own_selection (XCAR (tem), XCAR (XCDR (tem)), 27999 x_own_selection (XCAR (tem), XCAR (XCDR (tem)),
27995 new_owner, XCAR (XCDR (XCDR (XCDR (XCDR (tem))))), 28000 new_owner, XCAR (XCDR (XCDR (XCDR (XCDR (tem))))),
27996 timestamp); 28001 timestamp);
28002 }
28003 }
28004
28005 if (!NILP (new_owner))
28006 {
28007 owners = alloca (sizeof *owners * nowners);
28008 names = alloca (sizeof *names * nowners);
28009
28010 tail = lost;
28011 nowners = 0;
28012 counter = 0;
28013
28014 FOR_EACH_TAIL_SAFE (tail)
28015 {
28016 tem = XCAR (tail);
27997 28017
27998 /* Now check if we still don't own that selection, which can 28018 /* Now check if we still don't own that selection, which can
27999 happen if another program set itself as the owner. */ 28019 happen if another program set itself as the owner. */
28000 owner = XGetSelectionOwner (dpyinfo->display, 28020 names[counter++] = symbol_to_x_atom (dpyinfo, XCAR (tem));
28001 symbol_to_x_atom (dpyinfo, XCAR (tem))); 28021 owners[nowners++] = XGetSelectionOwner (dpyinfo->display,
28022 names[counter - 1]);
28023
28024 if (owners[nowners - 1] != FRAME_X_WINDOW (XFRAME (new_owner)))
28025 {
28026 /* Clear the local selection, since we know we don't own
28027 it any longer. */
28028 CONS_TO_INTEGER (XCAR (XCDR (XCDR (tem))), Time, timestamp);
28029
28030 clear.kind = SELECTION_CLEAR_EVENT;
28031
28032 SELECTION_EVENT_DPYINFO (&clear) = dpyinfo;
28033 SELECTION_EVENT_SELECTION (&clear) = names[nowners - 1];
28034 SELECTION_EVENT_TIME (&clear) = timestamp;
28035
28036 x_handle_selection_event (&clear);
28037 }
28038 }
28039
28040 tail = lost;
28041 nowners = 0;
28042
28043 FOR_EACH_TAIL_SAFE (tail)
28044 {
28045 tem = XCAR (tail);
28002 28046
28003 if (owner != FRAME_X_WINDOW (XFRAME (new_owner))) 28047 /* If the selection isn't owned by us anymore, note that the
28048 selection was lost. */
28049 if (owners[nowners++] != FRAME_X_WINDOW (XFRAME (new_owner)))
28004 CALLN (Frun_hook_with_args, Qx_lost_selection_functions, 28050 CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
28005 XCAR (tem)); 28051 XCAR (tem));
28006 } 28052 }