From 06576d6a16fa61f6f1d5031754145a92ab41aa9b Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 18 Jun 2022 11:19:01 +0800 Subject: [PATCH] Prevent Lisp code or synthetic events from ruining the user time * src/xterm.c (x_display_set_last_user_time): New parameter `send_event'. Make sure user time is newer unless !send_event. (x_set_last_user_time_from_lisp): Remove redundant check. (XTmouse_position): (handle_one_xevent): Pass `send_event' whenever appropriate. --- src/xterm.c | 59 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index 67bb2651727..885344229a6 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -6919,8 +6919,15 @@ static void x_scroll_bar_clear (struct frame *); static void x_check_font (struct frame *, struct font *); #endif +/* If SEND_EVENT, make sure that TIME is larger than the current last + user time. We don't sanitize timestamps from events sent by the X + server itself because some Lisp might have set the user time to a + ridiculously large value, and this way a more reasonable timestamp + can be obtained upon the next event. */ + static void -x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time) +x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time, + bool send_event) { #ifndef USE_GTK struct frame *focus_frame = dpyinfo->x_focus_frame; @@ -6930,7 +6937,8 @@ x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time) eassert (time <= X_ULONG_MAX); #endif - dpyinfo->last_user_time = time; + if (!send_event || time > dpyinfo->last_user_time) + dpyinfo->last_user_time = time; #ifndef USE_GTK if (focus_frame) @@ -7003,8 +7011,7 @@ void x_set_last_user_time_from_lisp (struct x_display_info *dpyinfo, Time time) { - if (dpyinfo->last_user_time > time) - x_display_set_last_user_time (dpyinfo, time); + x_display_set_last_user_time (dpyinfo, time, true); } @@ -12625,7 +12632,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, && (dpyinfo->last_user_time < dpyinfo->last_mouse_movement_time)) x_display_set_last_user_time (dpyinfo, - dpyinfo->last_mouse_movement_time); + dpyinfo->last_mouse_movement_time, false); if ((!f1 || FRAME_TOOLTIP_P (f1)) && (EQ (track_mouse, Qdropping) @@ -17315,7 +17322,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto OTHER; case KeyPress: - x_display_set_last_user_time (dpyinfo, event->xkey.time); + x_display_set_last_user_time (dpyinfo, event->xkey.time, + event->xkey.send_event); ignore_next_mouse_click_timeout = 0; coding = Qlatin_1; @@ -17766,7 +17774,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif case EnterNotify: - x_display_set_last_user_time (dpyinfo, event->xcrossing.time); + x_display_set_last_user_time (dpyinfo, event->xcrossing.time, + event->xcrossing.send_event); if (x_top_window_to_frame (dpyinfo, event->xcrossing.window)) x_detect_focus_change (dpyinfo, any, event, &inev.ie); @@ -17851,7 +17860,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto OTHER; case LeaveNotify: - x_display_set_last_user_time (dpyinfo, event->xcrossing.time); + x_display_set_last_user_time (dpyinfo, event->xcrossing.time, + event->xcrossing.send_event); #ifdef HAVE_XWIDGETS { @@ -18575,7 +18585,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, case ButtonPress: { if (event->xbutton.type == ButtonPress) - x_display_set_last_user_time (dpyinfo, event->xbutton.time); + x_display_set_last_user_time (dpyinfo, event->xbutton.time, + event->xbutton.send_event); #ifdef HAVE_XWIDGETS struct xwidget_view *xvw = xwidget_view_from_window (event->xbutton.window); @@ -19124,7 +19135,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, ev.window = enter->event; ev.time = enter->time; - x_display_set_last_user_time (dpyinfo, enter->time); + x_display_set_last_user_time (dpyinfo, enter->time, + enter->send_event); #ifdef USE_MOTIF use_copy = true; @@ -19273,7 +19285,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, leave->deviceid, false); #endif - x_display_set_last_user_time (dpyinfo, leave->time); + x_display_set_last_user_time (dpyinfo, leave->time, + leave->send_event); #ifdef HAVE_XWIDGETS { @@ -19527,7 +19540,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (xv) { uint state = xev->mods.effective; - x_display_set_last_user_time (dpyinfo, xev->time); + x_display_set_last_user_time (dpyinfo, xev->time, + xev->send_event); if (xev->buttons.mask_len) { @@ -19556,7 +19570,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif if (found_valuator) { - x_display_set_last_user_time (dpyinfo, xev->time); + x_display_set_last_user_time (dpyinfo, xev->time, + xev->send_event); #if defined USE_GTK && !defined HAVE_GTK3 /* Unlike on Motif, we can't select for XI @@ -20274,7 +20289,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif if (xev->evtype == XI_ButtonPress) - x_display_set_last_user_time (dpyinfo, xev->time); + x_display_set_last_user_time (dpyinfo, xev->time, + xev->send_event); source = xi_device_from_id (dpyinfo, xev->sourceid); @@ -20624,7 +20640,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, } #endif - x_display_set_last_user_time (dpyinfo, xev->time); + x_display_set_last_user_time (dpyinfo, xev->time, + xev->send_event); ignore_next_mouse_click_timeout = 0; f = x_any_window_to_frame (dpyinfo, xev->event); @@ -21418,7 +21435,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif device = xi_device_from_id (dpyinfo, xev->deviceid); source = xi_device_from_id (dpyinfo, xev->sourceid); - x_display_set_last_user_time (dpyinfo, xev->time); + x_display_set_last_user_time (dpyinfo, xev->time, + xev->send_event); if (!device) goto XI_OTHER; @@ -21504,7 +21522,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, device = xi_device_from_id (dpyinfo, xev->deviceid); source = xi_device_from_id (dpyinfo, xev->sourceid); - x_display_set_last_user_time (dpyinfo, xev->time); + x_display_set_last_user_time (dpyinfo, xev->time, + xev->send_event); if (!device) goto XI_OTHER; @@ -21550,7 +21569,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, device = xi_device_from_id (dpyinfo, xev->deviceid); source = xi_device_from_id (dpyinfo, xev->sourceid); - x_display_set_last_user_time (dpyinfo, xev->time); + x_display_set_last_user_time (dpyinfo, xev->time, + xev->send_event); if (!device) goto XI_OTHER; @@ -21590,7 +21610,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, device = xi_device_from_id (dpyinfo, pev->deviceid); source = xi_device_from_id (dpyinfo, pev->sourceid); - x_display_set_last_user_time (dpyinfo, pev->time); + x_display_set_last_user_time (dpyinfo, pev->time, + pev->send_event); if (!device) goto XI_OTHER; -- 2.39.2