Fix middle button emulation for Logitech Marble Mouse (#1421439)

This commit is contained in:
Peter Hutterer 2017-02-22 08:29:13 +10:00
parent 06a61d17a3
commit 1c0f18fa34
3 changed files with 212 additions and 1 deletions

View File

@ -0,0 +1,70 @@
From 153269d2f5c28f5af51b5e4019f621162508299a Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Fri, 17 Feb 2017 08:39:51 +1000
Subject: [PATCH libinput] evdev: add quirk for Logitech Marble Mouse
Device needs BTN_MIDDLE disabled, this way middle button emulation is present
by default.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit f7f849e576a5481751a8c3d086fc1b1b752fecc4)
---
src/evdev.c | 5 +++++
src/evdev.h | 1 +
udev/90-libinput-model-quirks.hwdb | 4 ++++
3 files changed, 10 insertions(+)
diff --git a/src/evdev.c b/src/evdev.c
index 17b28ec..73df74f 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -2225,6 +2225,7 @@ evdev_read_model_flags(struct evdev_device *device)
MODEL(HP_ZBOOK_STUDIO_G3),
MODEL(HP_PAVILION_DM4_TOUCHPAD),
MODEL(APPLE_TOUCHPAD_ONEBUTTON),
+ MODEL(LOGITECH_MARBLE_MOUSE),
#undef MODEL
{ "ID_INPUT_TRACKBALL", EVDEV_MODEL_TRACKBALL },
{ NULL, EVDEV_MODEL_DEFAULT },
@@ -2810,6 +2811,10 @@ evdev_pre_configure_model_quirks(struct evdev_device *device)
* https://bugs.freedesktop.org/show_bug.cgi?id=98100 */
if (device->model_flags & EVDEV_MODEL_HP_ZBOOK_STUDIO_G3)
libevdev_set_abs_maximum(device->evdev, ABS_MT_SLOT, 1);
+
+ /* Logitech Marble Mouse claims to have a middle button */
+ if (device->model_flags & EVDEV_MODEL_LOGITECH_MARBLE_MOUSE)
+ libevdev_disable_event_code(device->evdev, EV_KEY, BTN_MIDDLE);
}
struct evdev_device *
diff --git a/src/evdev.h b/src/evdev.h
index 5ae250f..1c25dc5 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -124,6 +124,7 @@ enum evdev_device_model {
EVDEV_MODEL_HP_ZBOOK_STUDIO_G3 = (1 << 23),
EVDEV_MODEL_HP_PAVILION_DM4_TOUCHPAD = (1 << 24),
EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON = (1 << 25),
+ EVDEV_MODEL_LOGITECH_MARBLE_MOUSE = (1 << 26),
};
struct mt_slot {
diff --git a/udev/90-libinput-model-quirks.hwdb b/udev/90-libinput-model-quirks.hwdb
index 10cb8ce..fafacb5 100644
--- a/udev/90-libinput-model-quirks.hwdb
+++ b/udev/90-libinput-model-quirks.hwdb
@@ -153,6 +153,10 @@ libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadX1Carbon3rd
libinput:name:*Logitech M570*:dmi:*
LIBINPUT_MODEL_TRACKBALL=1
+# Logitech Marble Mouse trackball
+libinput:mouse:input:b0003v046DpC408*
+ LIBINPUT_MODEL_LOGITECH_MARBLE_MOUSE=1
+
##########################################
# Synaptics
##########################################
--
2.9.3

View File

@ -0,0 +1,135 @@
From e238154dd36255d33b56fd6aebc1f591e40d84dd Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Mon, 20 Feb 2017 09:14:42 +1000
Subject: [PATCH libinput] 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>
(cherry picked from commit e43f9da9ecea6d17100c0012a89f5d162b2d7d7b)
---
src/evdev.c | 20 ++++++++++++++++++--
src/timer.c | 22 ++++++++++++++++------
src/timer.h | 10 ++++++++++
3 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/src/evdev.c b/src/evdev.c
index 29ebadd..17b28ec 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -229,8 +229,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);
diff --git a/src/timer.c b/src/timer.c
index c924794..362d81d 100644
--- a/src/timer.c
+++ b/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);
@@ -92,6 +96,12 @@ libinput_timer_set(struct libinput_timer *timer, uint64_t expire)
}
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)
{
if (!timer->expire)
diff --git a/src/timer.h b/src/timer.h
index f8315cf..93d684a 100644
--- a/src/timer.h
+++ b/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);
--
2.9.3

View File

@ -5,7 +5,7 @@
Name: libinput
Version: 1.6.2
Release: 1%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
Release: 2%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
Summary: Input device library
License: MIT
@ -18,6 +18,9 @@ Source2: commitid
Source0: http://www.freedesktop.org/software/libinput/libinput-%{version}.tar.xz
%endif
Patch01: 0001-evdev-allow-button-scrolling-on-the-L-R-button-with-.patch
Patch02: 0001-evdev-add-quirk-for-Logitech-Marble-Mouse.patch
BuildRequires: git
BuildRequires: autoconf automake libtool pkgconfig
BuildRequires: libevdev-devel
@ -94,6 +97,9 @@ find $RPM_BUILD_ROOT -name '*.la' -delete
%changelog
* Wed Feb 22 2017 Peter Hutterer <peter.hutterer@redhat.com> 1.6.2-2
- Fix middle button emulation for Logitech Marble Mouse (#1421439)
* Tue Feb 21 2017 Peter Hutterer <peter.hutterer@redhat.com> 1.6.2-1
- libinput 1.6.2