mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-20 04:30:06 +01:00
evdev: Add middle button scrolling for trackpoints
Most trackpoint users want to be able to scroll using the trackpoint with the middle button pressed, add support for this. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
0f112646ce
commit
7e932ed33f
5 changed files with 67 additions and 1 deletions
|
|
@ -163,6 +163,7 @@ struct input_keymap_entry {
|
|||
#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */
|
||||
#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
|
||||
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
||||
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
||||
|
||||
#define INPUT_PROP_MAX 0x1f
|
||||
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
||||
|
|
|
|||
56
src/evdev.c
56
src/evdev.c
|
|
@ -41,6 +41,7 @@
|
|||
#include "libinput-private.h"
|
||||
|
||||
#define DEFAULT_AXIS_STEP_DISTANCE 10
|
||||
#define DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT 200
|
||||
|
||||
enum evdev_key_type {
|
||||
EVDEV_KEY_TYPE_NONE,
|
||||
|
|
@ -203,6 +204,15 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
|
|||
device->rel.dx = 0;
|
||||
device->rel.dy = 0;
|
||||
|
||||
/* Use unaccelerated deltas for pointing stick scroll */
|
||||
if (device->scroll.has_middle_button_scroll &&
|
||||
hw_is_key_down(device, BTN_MIDDLE)) {
|
||||
if (device->scroll.middle_button_scroll_active)
|
||||
evdev_post_scroll(device, time,
|
||||
motion.dx, motion.dy);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Apply pointer acceleration. */
|
||||
filter_dispatch(device->pointer.filter, &motion, device, time);
|
||||
|
||||
|
|
@ -345,6 +355,37 @@ get_key_type(uint16_t code)
|
|||
return EVDEV_KEY_TYPE_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
evdev_middle_button_scroll_timeout(uint64_t time, void *data)
|
||||
{
|
||||
struct evdev_device *device = data;
|
||||
|
||||
device->scroll.middle_button_scroll_active = true;
|
||||
}
|
||||
|
||||
static void
|
||||
evdev_middle_button_scroll_button(struct evdev_device *device,
|
||||
uint64_t time, int is_press)
|
||||
{
|
||||
if (is_press) {
|
||||
libinput_timer_set(&device->scroll.timer,
|
||||
time + DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT);
|
||||
} else {
|
||||
libinput_timer_cancel(&device->scroll.timer);
|
||||
if (device->scroll.middle_button_scroll_active) {
|
||||
evdev_stop_scroll(device, time);
|
||||
device->scroll.middle_button_scroll_active = false;
|
||||
} else {
|
||||
/* If the button is released quickly enough emit the
|
||||
* button press/release events. */
|
||||
evdev_pointer_notify_button(device, time, BTN_MIDDLE,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
evdev_pointer_notify_button(device, time, BTN_MIDDLE,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
evdev_process_touch_button(struct evdev_device *device,
|
||||
uint64_t time, int value)
|
||||
|
|
@ -405,6 +446,12 @@ evdev_process_key(struct evdev_device *device,
|
|||
LIBINPUT_KEY_STATE_RELEASED);
|
||||
break;
|
||||
case EVDEV_KEY_TYPE_BUTTON:
|
||||
if (device->scroll.has_middle_button_scroll &&
|
||||
e->code == BTN_MIDDLE) {
|
||||
evdev_middle_button_scroll_button(device, time,
|
||||
e->value);
|
||||
break;
|
||||
}
|
||||
evdev_pointer_notify_button(
|
||||
device,
|
||||
time,
|
||||
|
|
@ -946,6 +993,15 @@ evdev_configure_device(struct evdev_device *device)
|
|||
device->mt.slot = active_slot;
|
||||
}
|
||||
}
|
||||
|
||||
if (libevdev_has_property(evdev, INPUT_PROP_POINTING_STICK)) {
|
||||
libinput_timer_init(&device->scroll.timer,
|
||||
device->base.seat->libinput,
|
||||
evdev_middle_button_scroll_timeout,
|
||||
device);
|
||||
device->scroll.has_middle_button_scroll = true;
|
||||
}
|
||||
|
||||
if (libevdev_has_event_code(evdev, EV_REL, REL_X) ||
|
||||
libevdev_has_event_code(evdev, EV_REL, REL_Y))
|
||||
has_rel = 1;
|
||||
|
|
|
|||
|
|
@ -26,10 +26,12 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "linux/input.h"
|
||||
#include <libevdev/libevdev.h>
|
||||
|
||||
#include "libinput-private.h"
|
||||
#include "timer.h"
|
||||
|
||||
enum evdev_event_type {
|
||||
EVDEV_NONE,
|
||||
|
|
@ -96,6 +98,9 @@ struct evdev_device {
|
|||
} rel;
|
||||
|
||||
struct {
|
||||
struct libinput_timer timer;
|
||||
bool has_middle_button_scroll;
|
||||
bool middle_button_scroll_active;
|
||||
double threshold;
|
||||
uint32_t direction;
|
||||
} scroll;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ static int events[] = {
|
|||
EV_KEY, BTN_MIDDLE,
|
||||
EV_REL, REL_X,
|
||||
EV_REL, REL_Y,
|
||||
INPUT_PROP_MAX, INPUT_PROP_POINTER,
|
||||
INPUT_PROP_MAX, INPUT_PROP_POINTING_STICK,
|
||||
-1, -1,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,9 @@ START_TEST(pointer_button)
|
|||
test_button_event(dev, BTN_RIGHT, 0);
|
||||
}
|
||||
|
||||
if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_MIDDLE)) {
|
||||
/* Skip middle button test on trackpoints (used for scrolling) */
|
||||
if (!libevdev_has_property(dev->evdev, INPUT_PROP_POINTING_STICK) &&
|
||||
libevdev_has_event_code(dev->evdev, EV_KEY, BTN_MIDDLE)) {
|
||||
test_button_event(dev, BTN_MIDDLE, 1);
|
||||
test_button_event(dev, BTN_MIDDLE, 0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue