diff options
| author | Po Lu | 2022-07-12 15:14:04 +0800 |
|---|---|---|
| committer | Po Lu | 2022-07-12 15:14:25 +0800 |
| commit | 93b31707e97f8ddf11aa8acbf5c61bc29b5f7528 (patch) | |
| tree | ad450cc67fcd4c27938e754f1e62f53aaf416d35 /src | |
| parent | a837c59d9eca748e3895ae09e82373531222aef6 (diff) | |
| download | emacs-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.c | 54 |
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 | } |