mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-20 09:10:04 +01:00
evdev: allow button scrolling on the L/R button with middle emulation active
This worked before, but triggered a negative timer bug. When one of the physical L/R buttons is pressed with middle button emulation enabled, the flow is: 1) phys left button down 2) middle button state machine discards events, sets timer 3) timer expires or button is released 4) middle button state machine sends button press with time from 1) 5) emulation code sees button press, sets timer for scroll emulation 6) timer logs bug because (original-button-time + timeout) is less than now() That log_bug_libinput() warning fails the tests but works otherwise. Allow this situation explicitly, on some devices we only have left and right buttons and no scroll wheel, so having middle button emulation *and* button-scroll working is useful. https://bugs.freedesktop.org/show_bug.cgi?id=99845 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
53e263fce7
commit
e43f9da9ec
3 changed files with 44 additions and 8 deletions
20
src/evdev.c
20
src/evdev.c
|
|
@ -231,8 +231,24 @@ evdev_button_scroll_button(struct evdev_device *device,
|
|||
device->scroll.button_scroll_btn_pressed = is_press;
|
||||
|
||||
if (is_press) {
|
||||
libinput_timer_set(&device->scroll.timer,
|
||||
time + DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT);
|
||||
enum timer_flags flags = TIMER_FLAG_NONE;
|
||||
|
||||
/* Special case: if middle button emulation is enabled and
|
||||
* our scroll button is the left or right button, we only
|
||||
* get here *after* the middle button timeout has expired
|
||||
* for that button press. The time passed is the button-down
|
||||
* time though (which is in the past), so we have to allow
|
||||
* for a negative timer to be set.
|
||||
*/
|
||||
if (device->middlebutton.enabled &&
|
||||
(device->scroll.button == BTN_LEFT ||
|
||||
device->scroll.button == BTN_RIGHT)) {
|
||||
flags = TIMER_FLAG_ALLOW_NEGATIVE;
|
||||
}
|
||||
|
||||
libinput_timer_set_flags(&device->scroll.timer,
|
||||
time + DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT,
|
||||
flags);
|
||||
device->scroll.button_down_time = time;
|
||||
} else {
|
||||
libinput_timer_cancel(&device->scroll.timer);
|
||||
|
|
|
|||
22
src/timer.c
22
src/timer.c
|
|
@ -67,19 +67,23 @@ libinput_timer_arm_timer_fd(struct libinput *libinput)
|
|||
}
|
||||
|
||||
void
|
||||
libinput_timer_set(struct libinput_timer *timer, uint64_t expire)
|
||||
libinput_timer_set_flags(struct libinput_timer *timer,
|
||||
uint64_t expire,
|
||||
uint32_t flags)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
uint64_t now = libinput_now(timer->libinput);
|
||||
if (expire < now)
|
||||
log_bug_libinput(timer->libinput,
|
||||
"timer offset negative (-%" PRIu64 ")\n",
|
||||
now - expire);
|
||||
else if ((expire - now) > ms2us(5000))
|
||||
if (expire < now) {
|
||||
if ((flags & TIMER_FLAG_ALLOW_NEGATIVE) == 0)
|
||||
log_bug_libinput(timer->libinput,
|
||||
"timer offset negative (-%" PRIu64 ")\n",
|
||||
now - expire);
|
||||
} else if ((expire - now) > ms2us(5000)) {
|
||||
log_bug_libinput(timer->libinput,
|
||||
"timer offset more than 5s, now %"
|
||||
PRIu64 " expire %" PRIu64 "\n",
|
||||
now, expire);
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(expire);
|
||||
|
|
@ -91,6 +95,12 @@ libinput_timer_set(struct libinput_timer *timer, uint64_t expire)
|
|||
libinput_timer_arm_timer_fd(timer->libinput);
|
||||
}
|
||||
|
||||
void
|
||||
libinput_timer_set(struct libinput_timer *timer, uint64_t expire)
|
||||
{
|
||||
libinput_timer_set_flags(timer, expire, TIMER_FLAG_NONE);
|
||||
}
|
||||
|
||||
void
|
||||
libinput_timer_cancel(struct libinput_timer *timer)
|
||||
{
|
||||
|
|
|
|||
10
src/timer.h
10
src/timer.h
|
|
@ -47,6 +47,16 @@ libinput_timer_init(struct libinput_timer *timer, struct libinput *libinput,
|
|||
void
|
||||
libinput_timer_set(struct libinput_timer *timer, uint64_t expire);
|
||||
|
||||
enum timer_flags {
|
||||
TIMER_FLAG_NONE = 0,
|
||||
TIMER_FLAG_ALLOW_NEGATIVE = (1 << 0),
|
||||
};
|
||||
|
||||
void
|
||||
libinput_timer_set_flags(struct libinput_timer *timer,
|
||||
uint64_t expire,
|
||||
uint32_t flags);
|
||||
|
||||
void
|
||||
libinput_timer_cancel(struct libinput_timer *timer);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue