mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-01-03 06:50:10 +01:00
evdev: recover from a lost button count
If the kernel sends us a button press for a button that is thought to be down
we have lost track of the state of the button. Ignore the button press event,
in the hope that the next release makes things right again.
A release event may be masked if another process grabs the device for some
period of time, e.g. libinput debug-events --grab.
https://bugs.freedesktop.org/show_bug.cgi?id=101796
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 399c50dbeb)
This commit is contained in:
parent
2d8b79877f
commit
1e89ceb93c
3 changed files with 52 additions and 10 deletions
20
src/evdev.c
20
src/evdev.c
|
|
@ -836,16 +836,16 @@ fallback_process_key(struct fallback_dispatch *dispatch,
|
|||
type = get_key_type(e->code);
|
||||
|
||||
/* Ignore key release events from the kernel for keys that libinput
|
||||
* never got a pressed event for. */
|
||||
if (e->value == 0) {
|
||||
switch (type) {
|
||||
case EVDEV_KEY_TYPE_NONE:
|
||||
break;
|
||||
case EVDEV_KEY_TYPE_KEY:
|
||||
case EVDEV_KEY_TYPE_BUTTON:
|
||||
if (!hw_is_key_down(dispatch, e->code))
|
||||
return;
|
||||
}
|
||||
* never got a pressed event for or key presses for keys that we
|
||||
* think are still down */
|
||||
switch (type) {
|
||||
case EVDEV_KEY_TYPE_NONE:
|
||||
break;
|
||||
case EVDEV_KEY_TYPE_KEY:
|
||||
case EVDEV_KEY_TYPE_BUTTON:
|
||||
if ((e->value && hw_is_key_down(dispatch, e->code)) ||
|
||||
(e->value == 0 && !hw_is_key_down(dispatch, e->code)))
|
||||
return;
|
||||
}
|
||||
|
||||
hw_set_key_down(dispatch, e->code, e->value);
|
||||
|
|
|
|||
|
|
@ -490,6 +490,40 @@ START_TEST(pointer_button_has_no_button)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(pointer_recover_from_lost_button_count)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libevdev *evdev = dev->evdev;
|
||||
|
||||
disable_button_scrolling(dev);
|
||||
|
||||
litest_drain_events(dev->libinput);
|
||||
|
||||
litest_button_click(dev, BTN_LEFT, 1);
|
||||
|
||||
litest_assert_button_event(li,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
|
||||
/* Grab for the release to make libinput lose count */
|
||||
libevdev_grab(evdev, LIBEVDEV_GRAB);
|
||||
litest_button_click(dev, BTN_LEFT, 0);
|
||||
libevdev_grab(evdev, LIBEVDEV_UNGRAB);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_button_click(dev, BTN_LEFT, 1);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_button_click(dev, BTN_LEFT, 0);
|
||||
litest_assert_button_event(li,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static inline double
|
||||
wheel_click_count(struct litest_device *dev, int which)
|
||||
{
|
||||
|
|
@ -2088,6 +2122,7 @@ litest_setup_tests_pointer(void)
|
|||
litest_add_no_device("pointer:button", pointer_button_auto_release);
|
||||
litest_add_no_device("pointer:button", pointer_seat_button_count);
|
||||
litest_add_for_device("pointer:button", pointer_button_has_no_button, LITEST_KEYBOARD);
|
||||
litest_add("pointer:button", pointer_recover_from_lost_button_count, LITEST_BUTTON, LITEST_CLICKPAD);
|
||||
litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_TABLET);
|
||||
litest_add("pointer:scroll", pointer_scroll_button, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
|
||||
litest_add("pointer:scroll", pointer_scroll_button_noscroll, LITEST_ABSOLUTE|LITEST_BUTTON, LITEST_RELATIVE);
|
||||
|
|
|
|||
|
|
@ -45,3 +45,10 @@
|
|||
...
|
||||
obj:/usr/lib*/libpython3*.so*
|
||||
}
|
||||
{
|
||||
libevdev:grab
|
||||
Memcheck:Param
|
||||
ioctl(generic)
|
||||
fun:ioctl
|
||||
fun:libevdev_grab
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue