mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-07 04:10:27 -08:00
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.
This commit is contained in:
parent
824d31e3bf
commit
673eadaeb5
1 changed files with 42 additions and 1 deletions
43
src/xterm.c
43
src/xterm.c
|
|
@ -372,6 +372,29 @@ x_free_xi_devices (struct x_display_info *dpyinfo)
|
|||
unblock_input ();
|
||||
}
|
||||
|
||||
/* The code below handles the tracking of scroll valuators on XInput
|
||||
2, in order to support scroll wheels that report information more
|
||||
granular than a screen line.
|
||||
|
||||
On X, when the XInput 2 extension is being utilized, the states of
|
||||
the mouse wheels in each axis are stored as absolute values inside
|
||||
"valuators" attached to each mouse device. To obtain the delta of
|
||||
the scroll wheel from a motion event (which is used to report that
|
||||
some valuator has changed), it is necessary to iterate over every
|
||||
valuator that changed, and compare its previous value to the
|
||||
current value of the valuator.
|
||||
|
||||
Each individual valuator also has an "interval", which is the
|
||||
amount you must divide that delta by in order to obtain a delta in
|
||||
the terms of scroll units.
|
||||
|
||||
This delta however is still intermediate, to make driver
|
||||
implementations easier. The XInput developers recommend (and most
|
||||
programs use) the following algorithm to convert from scroll unit
|
||||
deltas to pixel deltas:
|
||||
|
||||
pixels_scrolled = pow (window_height, 2.0 / 3.0) * delta; */
|
||||
|
||||
/* Setup valuator tracking for XI2 master devices on
|
||||
DPYINFO->display. */
|
||||
|
||||
|
|
@ -9874,6 +9897,19 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
x_display_set_last_user_time (dpyinfo, xi_event->time);
|
||||
x_detect_focus_change (dpyinfo, any, event, &inev.ie);
|
||||
|
||||
/* One problem behind the design of XInput 2 scrolling is
|
||||
that valuators are not unique to each window, but only
|
||||
the window that has grabbed the valuator's device or
|
||||
the window that the device's pointer is on top of can
|
||||
receive motion events. There is also no way to
|
||||
retrieve the value of a valuator outside of each motion
|
||||
event.
|
||||
|
||||
As such, to prevent wildly inaccurate results when the
|
||||
valuators have changed outside Emacs, we reset our
|
||||
records of each valuator's value whenever the pointer
|
||||
re-enters a frame after its valuators have potentially
|
||||
been changed elsewhere. */
|
||||
if (enter->detail != XINotifyInferior
|
||||
&& enter->mode != XINotifyPassiveUngrab
|
||||
&& enter->mode != XINotifyUngrab && any)
|
||||
|
|
@ -9947,6 +9983,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
struct xi_scroll_valuator_t *val;
|
||||
double delta, scroll_unit;
|
||||
|
||||
|
||||
/* See the comment on top of
|
||||
x_init_master_valuators for more details on how
|
||||
scroll wheel movement is reported on XInput 2. */
|
||||
delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid,
|
||||
i, *values, &val);
|
||||
|
||||
|
|
@ -9972,7 +10012,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
goto XI_OTHER;
|
||||
}
|
||||
|
||||
scroll_unit = pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0);
|
||||
found_valuator = true;
|
||||
|
||||
if (signbit (delta) != signbit (val->emacs_value))
|
||||
|
|
@ -9999,6 +10038,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
|= x_x_to_emacs_modifiers (dpyinfo,
|
||||
xev->mods.effective);
|
||||
|
||||
scroll_unit = pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0);
|
||||
|
||||
if (val->horizontal)
|
||||
{
|
||||
inev.ie.arg
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue