diff options
| author | Po Lu | 2022-07-07 21:12:49 +0800 |
|---|---|---|
| committer | Po Lu | 2022-07-07 21:15:29 +0800 |
| commit | 1fa5f0428fc9f141d7ae9973a9cc92c3e6a2b623 (patch) | |
| tree | 4e5cfb99c20d424b4f33abbbf9a1a30c1421ebd1 /src/pgtkselect.c | |
| parent | 0aa0dac799d692bac36a379c40bd178cff6cb80b (diff) | |
| download | emacs-1fa5f0428fc9f141d7ae9973a9cc92c3e6a2b623.tar.gz emacs-1fa5f0428fc9f141d7ae9973a9cc92c3e6a2b623.zip | |
Fix selection disowning upon frame deletion on Wayland
* src/pgtkselect.c (pgtk_clear_frame_selections): Manually
disown cleared selections. (bug#56434)
Diffstat (limited to 'src/pgtkselect.c')
| -rw-r--r-- | src/pgtkselect.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/src/pgtkselect.c b/src/pgtkselect.c index fff163c92a7..e0230003b3a 100644 --- a/src/pgtkselect.c +++ b/src/pgtkselect.c | |||
| @@ -790,8 +790,8 @@ pgtk_handle_selection_event (struct selection_input_event *event) | |||
| 790 | void | 790 | void |
| 791 | pgtk_clear_frame_selections (struct frame *f) | 791 | pgtk_clear_frame_selections (struct frame *f) |
| 792 | { | 792 | { |
| 793 | Lisp_Object frame; | 793 | Lisp_Object frame, rest, timestamp, symbol; |
| 794 | Lisp_Object rest; | 794 | guint32 time; |
| 795 | struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | 795 | struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); |
| 796 | struct terminal *t = dpyinfo->terminal; | 796 | struct terminal *t = dpyinfo->terminal; |
| 797 | 797 | ||
| @@ -801,9 +801,22 @@ pgtk_clear_frame_selections (struct frame *f) | |||
| 801 | while (CONSP (t->Vselection_alist) | 801 | while (CONSP (t->Vselection_alist) |
| 802 | && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (t->Vselection_alist))))))) | 802 | && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (t->Vselection_alist))))))) |
| 803 | { | 803 | { |
| 804 | symbol = Fcar (Fcar (t->Vselection_alist)); | ||
| 805 | |||
| 804 | /* Run the `pgtk-lost-selection-functions' abnormal hook. */ | 806 | /* Run the `pgtk-lost-selection-functions' abnormal hook. */ |
| 805 | CALLN (Frun_hook_with_args, Qpgtk_lost_selection_functions, | 807 | CALLN (Frun_hook_with_args, Qpgtk_lost_selection_functions, |
| 806 | Fcar (Fcar (t->Vselection_alist))); | 808 | symbol); |
| 809 | |||
| 810 | timestamp = Fcar (Fcdr (Fcdr (Fcar (t->Vselection_alist)))); | ||
| 811 | CONS_TO_INTEGER (timestamp, guint32, time); | ||
| 812 | |||
| 813 | /* On Wayland, GDK will still ask the (now non-existent) frame for | ||
| 814 | selection data, even though we no longer think the selection is | ||
| 815 | owned by us. Manually relinquish ownership of the selection. */ | ||
| 816 | gdk_selection_owner_set_for_display (dpyinfo->display, | ||
| 817 | NULL, | ||
| 818 | symbol_to_gdk_atom (symbol), | ||
| 819 | time, TRUE); | ||
| 807 | 820 | ||
| 808 | tset_selection_alist (t, XCDR (t->Vselection_alist)); | 821 | tset_selection_alist (t, XCDR (t->Vselection_alist)); |
| 809 | } | 822 | } |
| @@ -813,8 +826,18 @@ pgtk_clear_frame_selections (struct frame *f) | |||
| 813 | if (CONSP (XCDR (rest)) | 826 | if (CONSP (XCDR (rest)) |
| 814 | && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest)))))))) | 827 | && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest)))))))) |
| 815 | { | 828 | { |
| 829 | symbol = XCAR (XCAR (XCDR (rest))); | ||
| 816 | CALLN (Frun_hook_with_args, Qpgtk_lost_selection_functions, | 830 | CALLN (Frun_hook_with_args, Qpgtk_lost_selection_functions, |
| 817 | XCAR (XCAR (XCDR (rest)))); | 831 | symbol); |
| 832 | |||
| 833 | timestamp = XCAR (XCDR (XCDR (XCAR (XCDR (rest))))); | ||
| 834 | CONS_TO_INTEGER (timestamp, guint32, time); | ||
| 835 | |||
| 836 | gdk_selection_owner_set_for_display (dpyinfo->display, | ||
| 837 | NULL, | ||
| 838 | symbol_to_gdk_atom (symbol), | ||
| 839 | time, TRUE); | ||
| 840 | |||
| 818 | XSETCDR (rest, XCDR (XCDR (rest))); | 841 | XSETCDR (rest, XCDR (XCDR (rest))); |
| 819 | break; | 842 | break; |
| 820 | } | 843 | } |