aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2021-11-26 19:59:54 +0800
committerPo Lu2021-11-26 21:06:22 +0800
commit673eadaeb55de71016fab371613d8e930f6d7c04 (patch)
tree71223245090fdf3bc6a3ab8b2c0d50287aedbc21 /src
parent824d31e3bf22d57bc8f8011e6719b15059bea55b (diff)
downloademacs-673eadaeb55de71016fab371613d8e930f6d7c04.tar.gz
emacs-673eadaeb55de71016fab371613d8e930f6d7c04.zip
Explain confusing aspects of XInput 2 scroll wheel reporting
* src/xterm.c (x_init_master_valuators): Explain how XInput 2 reports scroll wheel movement. (handle_one_xevent): Explain why XI2 scroll valuators are reset after each enter events.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 821c92c4dda..c7950c6f9fc 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -372,6 +372,29 @@ x_free_xi_devices (struct x_display_info *dpyinfo)
372 unblock_input (); 372 unblock_input ();
373} 373}
374 374
375/* The code below handles the tracking of scroll valuators on XInput
376 2, in order to support scroll wheels that report information more
377 granular than a screen line.
378
379 On X, when the XInput 2 extension is being utilized, the states of
380 the mouse wheels in each axis are stored as absolute values inside
381 "valuators" attached to each mouse device. To obtain the delta of
382 the scroll wheel from a motion event (which is used to report that
383 some valuator has changed), it is necessary to iterate over every
384 valuator that changed, and compare its previous value to the
385 current value of the valuator.
386
387 Each individual valuator also has an "interval", which is the
388 amount you must divide that delta by in order to obtain a delta in
389 the terms of scroll units.
390
391 This delta however is still intermediate, to make driver
392 implementations easier. The XInput developers recommend (and most
393 programs use) the following algorithm to convert from scroll unit
394 deltas to pixel deltas:
395
396 pixels_scrolled = pow (window_height, 2.0 / 3.0) * delta; */
397
375/* Setup valuator tracking for XI2 master devices on 398/* Setup valuator tracking for XI2 master devices on
376 DPYINFO->display. */ 399 DPYINFO->display. */
377 400
@@ -9874,6 +9897,19 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9874 x_display_set_last_user_time (dpyinfo, xi_event->time); 9897 x_display_set_last_user_time (dpyinfo, xi_event->time);
9875 x_detect_focus_change (dpyinfo, any, event, &inev.ie); 9898 x_detect_focus_change (dpyinfo, any, event, &inev.ie);
9876 9899
9900 /* One problem behind the design of XInput 2 scrolling is
9901 that valuators are not unique to each window, but only
9902 the window that has grabbed the valuator's device or
9903 the window that the device's pointer is on top of can
9904 receive motion events. There is also no way to
9905 retrieve the value of a valuator outside of each motion
9906 event.
9907
9908 As such, to prevent wildly inaccurate results when the
9909 valuators have changed outside Emacs, we reset our
9910 records of each valuator's value whenever the pointer
9911 re-enters a frame after its valuators have potentially
9912 been changed elsewhere. */
9877 if (enter->detail != XINotifyInferior 9913 if (enter->detail != XINotifyInferior
9878 && enter->mode != XINotifyPassiveUngrab 9914 && enter->mode != XINotifyPassiveUngrab
9879 && enter->mode != XINotifyUngrab && any) 9915 && enter->mode != XINotifyUngrab && any)
@@ -9947,6 +9983,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9947 struct xi_scroll_valuator_t *val; 9983 struct xi_scroll_valuator_t *val;
9948 double delta, scroll_unit; 9984 double delta, scroll_unit;
9949 9985
9986
9987 /* See the comment on top of
9988 x_init_master_valuators for more details on how
9989 scroll wheel movement is reported on XInput 2. */
9950 delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid, 9990 delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid,
9951 i, *values, &val); 9991 i, *values, &val);
9952 9992
@@ -9972,7 +10012,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9972 goto XI_OTHER; 10012 goto XI_OTHER;
9973 } 10013 }
9974 10014
9975 scroll_unit = pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0);
9976 found_valuator = true; 10015 found_valuator = true;
9977 10016
9978 if (signbit (delta) != signbit (val->emacs_value)) 10017 if (signbit (delta) != signbit (val->emacs_value))
@@ -9999,6 +10038,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9999 |= x_x_to_emacs_modifiers (dpyinfo, 10038 |= x_x_to_emacs_modifiers (dpyinfo,
10000 xev->mods.effective); 10039 xev->mods.effective);
10001 10040
10041 scroll_unit = pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0);
10042
10002 if (val->horizontal) 10043 if (val->horizontal)
10003 { 10044 {
10004 inev.ie.arg 10045 inev.ie.arg