A few devices have a keyboard/keypad which can be slid under the device,
leaving the device with only touch-based interaction. The corresponding kernel
event is reported as SW_KEYPAD_SLIDE [0]. Implement support in libinput.
Since the position of the switch varies across devices, it cannot always be
certain whether the keypad is usable when the switch is in the set position.
Therefore, do not automatically disable the keyboard.
[0] e68d80b13b/include/linux/linux/input-event-codes.h (L885)Closes: #1069
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1242>
Commit 94b7836456 ("filter: support accelerating high-resolution
scroll wheel events") introduced a regression where high-res scroll
wheel events were incorrectly normalized by DPI. Mice with non-default
DPI (e.g., Logitech G502 at 2400 DPI) had their scroll wheel speed
reduced by the DPI ratio (1000/2400), resulting in 2-3x slower
scrolling.
The "noop" filter functions were actually performing DPI normalization
or applying a constant acceleration factor, which is appropriate for
button scrolling but incorrect for scroll wheels that have their own
units.
Add a filter_scroll_type enum (CONTINOUS, WHEEL, FINGER to match the
public events) passed through the filter_scroll interface. Update all
filter implementations to skip acceleration and normalization for wheel
events while maintaining existing behavior for button scrolling and
touchpad scrolling.
The custom acceleration profile continues to accelerate high-res wheel
events as designed.
Fixes: 94b7836456 ("filter: support accelerating high-resolution scroll wheel events")
Closes: #1212
Signed-off-by: Yinon Burgansky <yinonburgansky@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1363>
Dispatch high-resolution scroll wheel events through filter_dispatch_scroll
so they can be accelerated using the custom acceleration profile.
Low-resolution scroll wheel events are not accelerated to avoid zero
delta-time in the filter.
Signed-off-by: Yinon Burgansky <yinonburgansky@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1316>
mtdev is used only for MT Protocol A device of which there are quite
few. But that protocol is also a perfect example for event frames in ->
different event frame out so let's move this into the plugin pipeline.
Because the plugin doesn't really have full access to the device's
internals we set up mtdev base on the libevdev information rather than
just handing it the fd and letting it extract the right info.
A minor functionality change: previously mtdev-backed devices returned
zero on libinput_device_touch_get_touch_count(). Now it is hardcoded to
10 - the number of callers that care about this is likely near zero.
Because it's now neatly factored out into a plugin we can also make
mtdev no longer a strict requirement.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1245>
No functional changes, all the actual interfaces now simply loop through
the frame instead of expecting the dispatcher to do so.
The mtdev code changed slightly since we can shortcut in the non-mtdev
case.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1245>
This provides both some type-safety but also better readability of what
the integer we're passing around is supposed to be. In particular the
pad buttons are numeric buttons while the normal buttons are evdev
codes.
Future extension of this could be to also check for (or against) the
valid BTN_* ranges for a button code or keycode.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
The key_count array for buttons records the logical button sent to the
client - for left-handed configurations that means a BTN_LEFT is
recorded as BTN_RIGHT.
When the device is suspended and we are releasing all keys we must thus
release the button code as-is without trying to map it again.
Fixes#881
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Adds a dedicated scroll movement type to the custom acceleration profile.
Supported by physical mouse and touchpad.
Other profiles remain the same by using the same unaccelerated filter for the scroll filter.
Signed-off-by: Yinon Burgansky <51504-Yinon@users.noreply.gitlab.freedesktop.org>
Previously we restricted rotation to trackballs only and to multiples
of 90 degrees. Update rotation allow angles other than multiples of 90.
Also enable rotation on all mice. The only devices without rotation
are now pointing sticks.
Fixes#827
Signed-off-by: Lucas Zampieri <lzampier@redhat.com>
Our pointer filter code has two functions - one for accelerated movement
and one for "constant" movement (i.e. no accel factor provided but same
conversions). Let's use that instead of a manual normalization.
This fixes an issue with button scrolling on high-dpi mice in the flat
pointer acceleration: normal pointer motion in the flat profile isn't
normalized but the button scrolling was - resulting in e.g. 5 times
slower motion for button scrolling on a 5000dpi mouse.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Since cd4f2f32b5 ("fallback: disable mouse scroll wheel while middle
button is pressed") the mouse wheel is inhibited while the mouse wheel
is pressed.
The original intention of this feature was to avoid unintended scroll
while pressing the scroll wheel. However, now that high-resolution
scroll is fully integrated in libinput we can improve this feature and
filter unintended scroll (below half a detent) and allow it when it is
intended (over half a detent).
Remove the "WHEEL_STATE_PRESSED" state from the wheel state machine and
let the general heuristics handle this case.
Also, remove the specific tests for this feature as now it is covered
by the general test cases.
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Mice with high-resolution support can generate deltas when the finger is
put on the wheel or when the user tries to click the wheel.
To avoid sending involuntary scroll events, add an extra state the the
wheel state machine to accumulate scroll deltas.
While the accumulated scroll is lower than a certain threshold, ignore
them until the threshold is reached.
Since no finish event is sent by the mouse, reset the state machine
after a period of scroll inactivity.
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Some devices might announce support for high-resolution scroll wheel
by enabling REL_WHEEL_HI_RES and/or REL_HWHEEL_HI_RES but never send
a high-resolution scroll event.
When the first low-resolution scroll event is received without any
previous high-resolution event, print a kernel bug warning and start
emulating high-resolution scroll events.
Fix#668
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Starting with kernel v5.0 two new axes are available for high-resolution wheel
scrolling: REL_WHEEL_HI_RES and REL_HWHEEL_HI_RES. Both axes send data in
fractions of 120 where each multiple of 120 amounts to one logical scroll
event. Fractions of 120 indicate a wheel movement less than one detent.
This commit adds a new API for scroll events. Three new event types that encode
the axis source in the event type name and a new API to get a normalized-to-120
value that also used by Windows and the kernel (each multiple of 120 represents
a logical scroll click).
This addresses a main shortcoming with the existing API - it was unreliable to
calculate the click angle based on the axis value+discrete events and thus any
caller using the axis value alone would be left with some ambiguity. With the
v120 API it's now possible to (usually) calculate the click angle, but more
importantly it provides the simplest hw-independent way of scrolling by a
click or a fraction of a click.
A new event type is required, the only way to integrate the v120 value
otherwise was to start sending events with a discrete value of 0. This
would break existing xf86-input-libinput (divide by zero, fixed in 0.28.2) and
weston (general confusion). mutter, kwin are unaffected.
With the new API, the old POINTER_AXIS event are deprecated - callers should use
the new API where available and discard any POINTER_AXIS events.
Notable: REL_WHEEL/REL_HWHEEL are emulated by the kernel but there's no
guarantee that they'll come every accumulated 120 values, e.g. Logitech mice
often send events that don't add up to 120 per detent.
We use the kernel's wheel click emulation instead of doing our own.
libinput guarantees high-resolution events even on pre-5.0 kernels.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
The device sends its own scroll events when its trackpoint is moved
while the middle button is pressed.
Because scroll events are inhibited while the middle button is pressed
a quirk is necessary for this device to not inhibit scroll events.
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
The current fallback_dispatch wheel struct, a device_coords, doesn't allow to
save extra information.
The new anonymous struct will allow to add a is_inhibited field to disable mouse
scroll while the middle button is pressed and, potentially, any required extra
state in the future.
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
This has never been supported through the stack. No device ever had the
required MOUSE_WHEEL_TILT_VERTICAL/HORIZONTAL udev property set, so
libinput never set the right axis source. Neither weston nor mutter
added the code for it. Even if we added wheel tilt for devices now, it
would break those devices. And the benefit we get from having those
separate is miniscule at best.
So let's do the long-term thing and just deprecate this axis source.
The wheel tilt mouse test device remains in the test suite, with the
udev properties set just to verify that we do indeed ignore those now.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Old-style field initialisation ignores the 64-bit time_t change in
Linux UAPI, which causes the structure to be incompletely initialised
on 32-bit systems with the 64-bit time_t kernel headers.
This patch uses the input_event_init helper from the original 64-bit
time_t enablement patch.
Signed-off-by: A. Wilcox <AWilcox@Wilcox-Tech.com>
Fixes: 5dc1a7ebd ("Adjust for 64bit time_t for 32bit architectures")
See-Also: libinput/libinput!346
Scroll button locking is an accessibility feature. When enabled, the scroll
button does not need to be held down, the first click holds it logically down,
to be released on the second click of that same button.
This is implemented as simple event filter, so we still get the same behavior
from the emulated logical button, i.e. a physical double click results in a
single logical click of that button provided no scrolling was triggered.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Any touch down event will also provide motion data, but we must not send a
motion event for those in the same frame as the down event.
Fixes#375
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Some versions [1] of the Lenovo ThinkPad Compact USB Keyboard with TrackPoint USB
have the pointing stick on an event node that has keys but is not a regular
keyboard. Thus the stick falls through the cracks and gets disabled on tablet
mode switch. Instead of adding more hacks let's do this properly: tag the
pointing stick as external and have the code in place to deal with that.
[1] This may be caused by recent kernel changes
Fixes#291
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Running libinput-test-suite with -fsanitize=undefined highlights the two
following errors. Force C to realize we want an unsigned result by making
the '1' literal unsigned.
../src/evdev-fallback.c:314:22 runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
../src/evdev-fallback.c:377:24 runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
v2: use bit() instead of manual shift 1U<<1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
When the touch arbitration is reset to ARBITRATION_NOT_ACTIVE, the proximity
timer is set for 90ms to avoid erroneous touches (see 2a378beab for the
reason).
If the device is removed within those 90ms, the timer is never cancelled,
leading to an assert on cleanup.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
If the tilt angle on tip down is not 0 set the touch arbitration to a
rectangle around the assumed position of the hand. This assumed position is
right of the tip for a rightwards tilt and left of the tip for a leftwards
tilt (i.e. left-handed mode). The rectangle is 200x200mm with a 20x50mm
NW of the tip or NE for left-handed. In other words, if the period below is
the tip, the rectangle looks like this:
+-----------+ +-----------+
| . | <- for rightwards tilt | . |
| | | |
| | | |
| | for leftwards tilt -> | |
+-----------+ +-----------+
Touches within that rectangle are canceled, new touches are ignored. As the
tip moves around the rectangle is updated but touches are only cancelled on
the original tip down. While the tip is down, new touches are ignored in the
exclusion area but pre-existing touches are not cancelled.
This is currently only implemented in the fallback interface, i.e. it will
only work for Cintiqs.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This enables us to specify the location that needs to be arbitrated, rather
than just disabling the whole device altogether. This patch just adds the
hooks, no implementation.
This is internal API only, one backend can specify an area in mm which gets
converted to device coordinates in the target device and arbitrated there.
Right now, everything simply passes NULL.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>