From 32a6d52d43b4c3452687a11b01dfb51ba111fee2 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 21 Jun 2022 09:35:07 +0800 Subject: [PATCH] Move selection delayed message to a better location * lisp/term/x-win.el (gui-backend-get-selection): Remove `with-delayed-message' here. * src/xselect.c (x_display_selection_waiting_message) (x_cancel_atimer): New functions. (x_get_foreign_selection): Add an atimer that displays the message after a while. --- lisp/term/x-win.el | 5 ++--- src/xselect.c | 41 +++++++++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el index 6e083499df4..32675a07b1f 100644 --- a/lisp/term/x-win.el +++ b/lisp/term/x-win.el @@ -1366,9 +1366,8 @@ This returns an error if any Emacs frames are X frames." (cl-defmethod gui-backend-get-selection (selection-symbol target-type &context (window-system x) &optional time-stamp terminal) - (with-delayed-message (1 "Waiting for selection") - (x-get-selection-internal selection-symbol target-type - time-stamp terminal))) + (x-get-selection-internal selection-symbol target-type + time-stamp terminal)) ;; Initiate drag and drop (add-hook 'after-make-frame-functions 'x-dnd-init-frame) diff --git a/src/xselect.c b/src/xselect.c index fcf0ee944e2..d90916c6b63 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -36,6 +36,7 @@ along with GNU Emacs. If not, see . */ #include "termhooks.h" #include "keyboard.h" #include "pdumper.h" +#include "atimer.h" #include @@ -1198,6 +1199,20 @@ x_handle_property_notify (const XPropertyEvent *event) } } +static void +x_display_selection_waiting_message (struct atimer *timer) +{ + Lisp_Object val; + + val = build_string ("Waiting for reply from selection owner..."); + message3_nolog (val); +} + +static void +x_cancel_atimer (void *atimer) +{ + cancel_atimer (atimer); +} /* Variables for communication with x_handle_selection_notify. */ @@ -1223,9 +1238,14 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, Atom type_atom = (CONSP (target_type) ? symbol_to_x_atom (dpyinfo, XCAR (target_type)) : symbol_to_x_atom (dpyinfo, target_type)); + struct atimer *delayed_message; + struct timespec message_interval; + specpdl_ref count; + + count = SPECPDL_INDEX (); if (!FRAME_LIVE_P (f)) - return Qnil; + return unbind_to (count, Qnil); if (! NILP (time_stamp)) CONS_TO_INTEGER (time_stamp, Time, requestor_time); @@ -1257,6 +1277,12 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, unblock_input (); + message_interval = make_timespec (1, 0); + delayed_message = start_atimer (ATIMER_RELATIVE, message_interval, + x_display_selection_waiting_message, + NULL); + record_unwind_protect_ptr (x_cancel_atimer, delayed_message); + /* This allows quits. Also, don't wait forever. */ intmax_t timeout = max (0, x_selection_timeout); intmax_t secs = timeout / 1000; @@ -1288,13 +1314,16 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, if (NILP (XCAR (reading_selection_reply))) error ("Timed out waiting for reply from selection owner"); if (EQ (XCAR (reading_selection_reply), Qlambda)) - return Qnil; + return unbind_to (count, Qnil); /* Otherwise, the selection is waiting for us on the requested property. */ - return - x_get_window_property_as_lisp_data (dpyinfo, requestor_window, - target_property, target_type, - selection_atom, false); + return unbind_to (count, + x_get_window_property_as_lisp_data (dpyinfo, + requestor_window, + target_property, + target_type, + selection_atom, + false)); } /* Subroutines of x_get_window_property_as_lisp_data */ -- 2.39.2