From 32fbda5c37d7c11201df8232c1cc6e2b5d88791e Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 14 Feb 2022 13:13:13 +0800 Subject: [PATCH] Ensure bad values don't leak into scroll valuators after DeviceChange * src/xterm.c (xi_reset_scroll_valuators_for_device_id): New argument `pending_only'. (handle_one_xevent): Reset pending scroll valuators on XI_Enter and mark valuators updated via DeviceChanged events as pending. * src/xterm.h (struct xi_scroll_valuator_t): New field `pending_enter_reset'. --- src/xterm.c | 23 +++++++++++++++++++++-- src/xterm.h | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index 98c8a224080..9cde6c9a683 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -791,7 +791,8 @@ xi_find_touch_point (struct xi_device_t *device, int detail) #endif /* XI_TouchBegin */ static void -xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id) +xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id, + bool pending_only) { struct xi_device_t *device = xi_device_from_id (dpyinfo, id); struct xi_scroll_valuator_t *valuator; @@ -805,6 +806,11 @@ xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id) for (int i = 0; i < device->scroll_valuator_count; ++i) { valuator = &device->valuators[i]; + + if (pending_only && !valuator->pending_enter_reset) + continue; + + valuator->pending_enter_reset = false; valuator->invalid_p = true; valuator->emacs_value = 0.0; } @@ -10853,6 +10859,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!any) any = x_any_window_to_frame (dpyinfo, enter->event); + xi_reset_scroll_valuators_for_device_id (dpyinfo, enter->deviceid, + true); + { #ifdef HAVE_XWIDGETS struct xwidget_view *xwidget_view = xwidget_view_from_window (enter->event); @@ -10916,7 +10925,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, moves out of a frame (and not into one of its children, which we know about). */ if (leave->detail != XINotifyInferior && any) - xi_reset_scroll_valuators_for_device_id (dpyinfo, enter->deviceid); + xi_reset_scroll_valuators_for_device_id (dpyinfo, + enter->deviceid, false); #ifdef HAVE_XWIDGETS { @@ -11937,6 +11947,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, { device->valuators[i].invalid_p = false; device->valuators[i].current_value = info->value; + + /* Make sure that this is reset if the + pointer moves into a window of ours. + + Otherwise the valuator state could be + left invalid if the DeviceChange + event happened with the pointer + outside any Emacs frame. */ + device->valuators[i].pending_enter_reset = true; } } } diff --git a/src/xterm.h b/src/xterm.h index 99c86ced56c..f58fa0fe54d 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -184,6 +184,7 @@ struct color_name_cache_entry struct xi_scroll_valuator_t { bool invalid_p; + bool pending_enter_reset; double current_value; double emacs_value; double increment; -- 2.39.5