From c96a6a0c9fc44be846834ab1d7d8d527dc8dc5e9 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 15 Jul 2022 21:46:55 +0800 Subject: [PATCH] Only preserve PRIMARY and CLIPBOARD selection ownership by default * lisp/cus-start.el (standard): Update defcustom type. * src/xselect.c (x_should_preserve_selection): New function. (x_clear_frame_selections): Use it to determine whether or not to preserve a selection. * src/xterm.c (x_preserve_selections): Fix tail initialization. (syms_of_xterm): Update doc string of `x-auto-preserve-selections'. --- lisp/cus-start.el | 5 ++++- src/xselect.c | 36 ++++++++++++++++++++++++++++++------ src/xterm.c | 10 +++++++--- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/lisp/cus-start.el b/lisp/cus-start.el index df919fd7155..0e1cb4589da 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -834,7 +834,10 @@ since it could result in memory overflow and make Emacs crash." (x-scroll-event-delta-factor mouse float "29.1") (x-gtk-use-native-input keyboard boolean "29.1") (x-dnd-disable-motif-drag dnd boolean "29.1") - (x-auto-preserve-selections x boolean "29.1") + (x-auto-preserve-selections x + (choice (const :tag "Always preserve selections" t) + (repeat symbol)) + "29.1") ;; xselect.c (x-select-enable-clipboard-manager killing boolean "24.1") ;; xsettings.c diff --git a/src/xselect.c b/src/xselect.c index 1750cfb8bd8..d6e6d0c30b8 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -1084,6 +1084,26 @@ x_handle_selection_event (struct selection_input_event *event) x_handle_selection_request (event); } +static bool +x_should_preserve_selection (Lisp_Object selection) +{ + Lisp_Object tem; + + tem = Vx_auto_preserve_selections; + + if (CONSP (Vx_auto_preserve_selections)) + { + FOR_EACH_TAIL_SAFE (tem) + { + if (EQ (XCAR (tem), selection)) + return true; + } + + return false; + } + + return !NILP (tem); +} /* Clear all selections that were made from frame F. We do this when about to delete a frame. */ @@ -1091,7 +1111,7 @@ x_handle_selection_event (struct selection_input_event *event) void x_clear_frame_selections (struct frame *f) { - Lisp_Object frame, rest, lost; + Lisp_Object frame, rest, lost, selection; struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); struct terminal *t = dpyinfo->terminal; @@ -1102,10 +1122,12 @@ x_clear_frame_selections (struct frame *f) while (CONSP (t->Vselection_alist) && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (t->Vselection_alist))))))) { - if (!x_auto_preserve_selections) + selection = Fcar (Fcar (t->Vselection_alist)); + + if (!x_should_preserve_selection (selection)) /* Run the `x-lost-selection-functions' abnormal hook. */ CALLN (Frun_hook_with_args, Qx_lost_selection_functions, - Fcar (Fcar (t->Vselection_alist))); + selection); else lost = Fcons (Fcar (t->Vselection_alist), lost); @@ -1117,9 +1139,11 @@ x_clear_frame_selections (struct frame *f) if (CONSP (XCDR (rest)) && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest)))))))) { - if (!x_auto_preserve_selections) + selection = XCAR (XCAR (XCDR (rest))); + + if (!x_should_preserve_selection (selection)) CALLN (Frun_hook_with_args, Qx_lost_selection_functions, - XCAR (XCAR (XCDR (rest)))); + selection); else lost = Fcons (XCAR (XCDR (rest)), lost); @@ -1127,7 +1151,7 @@ x_clear_frame_selections (struct frame *f) break; } - if (x_auto_preserve_selections) + if (!NILP (lost)) x_preserve_selections (dpyinfo, lost, frame); } diff --git a/src/xterm.c b/src/xterm.c index 63b625f3837..c0a01d0d732 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -28096,6 +28096,7 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost, } nowners = 0; + tail = lost; FOR_EACH_TAIL_SAFE (tail) { @@ -28458,10 +28459,13 @@ executing the protocol request. Otherwise, errors will be silently ignored without waiting, which is generally faster. */); x_fast_protocol_requests = false; - DEFVAR_BOOL ("x-auto-preserve-selections", x_auto_preserve_selections, + DEFVAR_LISP ("x-auto-preserve-selections", Vx_auto_preserve_selections, doc: /* Whether or not to transfer selection ownership when deleting a frame. When non-nil, deleting a frame that is currently the owner of a selection will cause its ownership to be transferred to another frame -on the same display. */); - x_auto_preserve_selections = true; +on the same display. + +In addition, when this variable is a list, only preserve the +selections whose names are contained within. */); + Vx_auto_preserve_selections = list2 (QCLIPBOARD, QPRIMARY); } -- 2.39.2