From 4b98a79a508ebdc719abfcf51ee6de32e46d0e1c Mon Sep 17 00:00:00 2001 From: Daniel Colascione Date: Sat, 6 Aug 2022 23:42:36 -0400 Subject: Improve X event timestamp tracking Fix two problems with our handling of X timestamps 1) We're not properly updating the X interaction timestamp after receiving certain input events, and 2) X events sent in response to emacsclient commands get stale timestamps because the timestamp tracking doesn't take into account that interactions with the user can occur outside the X input event channel. * src/xterm.c: (x_display_set_last_user_time_1): New function. (x_display_set_last_user_time): Call it. (x_ewmh_activate_frame): Refactor. (x_focus_frame): Don't call XSetInputFocus if we can use EWMH activation. (server_timestamp_predicate): New function. (x_get_server_time): New function. (x_note_oob_interaction): New function. (x_create_terminal): Register new function as terminal hook. * src/termhooks.h: New hook: note_oob_interaction_hook. * src/gtkutil.h: (xg_set_user_timestamp): Declare. * src/gtkutil.c: (xg_set_user_timestamp): New function. * src/frame.c: (Fframe_note_oob_interaction): New function. (syms_of_frame): Register it. * lisp/server.el: (server-switch-buffer): Call frame-note-oob-interaction when user requests frame be raised. --- src/frame.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/frame.c') diff --git a/src/frame.c b/src/frame.c index 25d71e0769f..084df8ef216 100644 --- a/src/frame.c +++ b/src/frame.c @@ -5942,6 +5942,25 @@ This function is for internal use only. */) return f->was_invisible ? Qt : Qnil; } + +DEFUN ("frame-note-oob-interaction", + Fframe_note_oob_interaction, + Sframe_note_oob_interaction, 0, 1, 0, + doc: /* Note that the user has interacted with a frame. +This function is useful when the user interacts with Emacs out-of-band +(e.g., via the server) and we want to pretend for purposes of Emacs +interacting with the window system that the last interaction time was +the time of that out-of-band interaction, not the time of the last +window system input event delivered to that frame. */) + (Lisp_Object frame) +{ + struct frame *f = decode_any_frame (frame); + if (FRAME_LIVE_P (f) && + FRAME_TERMINAL (f)->note_oob_interaction_hook) + FRAME_TERMINAL (f)->note_oob_interaction_hook (f); + return Qnil; +} + /*********************************************************************** Multimonitor data @@ -6626,6 +6645,7 @@ iconify the top level frame instead. */); defsubr (&Sframe_window_state_change); defsubr (&Sset_frame_window_state_change); defsubr (&Sframe_scale_factor); + defsubr (&Sframe_note_oob_interaction); #ifdef HAVE_WINDOW_SYSTEM defsubr (&Sx_get_resource); -- cgit v1.2.3