mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-05-09 03:38:01 +02:00
touchpad: require minimum scroll distance and lock scroll direction
This is a fairly rough approach, but can be handled more fine-grained later. Require a minimum of 1 unit to start scrolling and lock the scrolling in the initial direction, so further scroll events are limited to that direction only. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
0d759edc3f
commit
c1a9b24a0a
2 changed files with 79 additions and 13 deletions
|
|
@ -310,16 +310,64 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint32_t time)
|
||||||
|
|
||||||
tp_filter_motion(tp, &dx, &dy, time);
|
tp_filter_motion(tp, &dx, &dy, time);
|
||||||
|
|
||||||
if (dx != 0.0)
|
if (tp->scroll.state == SCROLL_STATE_NONE) {
|
||||||
pointer_notify_axis(&tp->device->base,
|
/* Require at least one px scrolling to start */
|
||||||
time,
|
if (dx <= -1.0 || dx >= 1.0) {
|
||||||
LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL,
|
tp->scroll.state = SCROLL_STATE_SCROLLING;
|
||||||
li_fixed_from_double(dx));
|
tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL);
|
||||||
if (dy != 0.0)
|
}
|
||||||
|
|
||||||
|
if (dy <= -1.0 || dy >= 1.0) {
|
||||||
|
tp->scroll.state = SCROLL_STATE_SCROLLING;
|
||||||
|
tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp->scroll.state == SCROLL_STATE_NONE)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dy != 0.0 &&
|
||||||
|
(tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL))) {
|
||||||
pointer_notify_axis(&tp->device->base,
|
pointer_notify_axis(&tp->device->base,
|
||||||
time,
|
time,
|
||||||
LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL,
|
LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL,
|
||||||
li_fixed_from_double(dy));
|
li_fixed_from_double(dy));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dx != 0.0 &&
|
||||||
|
(tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL))) {
|
||||||
|
pointer_notify_axis(&tp->device->base,
|
||||||
|
time,
|
||||||
|
LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL,
|
||||||
|
li_fixed_from_double(dx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tp_post_scroll_events(struct tp_dispatch *tp, uint32_t time)
|
||||||
|
{
|
||||||
|
if (tp->nfingers_down != 2) {
|
||||||
|
/* terminate scrolling with a zero scroll event to notify
|
||||||
|
* caller that it really ended now */
|
||||||
|
if (tp->scroll.state != SCROLL_STATE_NONE) {
|
||||||
|
tp->scroll.state = SCROLL_STATE_NONE;
|
||||||
|
tp->scroll.direction = 0;
|
||||||
|
if (tp->scroll.direction & LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL)
|
||||||
|
pointer_notify_axis(&tp->device->base,
|
||||||
|
time,
|
||||||
|
LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL,
|
||||||
|
0);
|
||||||
|
if (tp->scroll.direction & LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL)
|
||||||
|
pointer_notify_axis(&tp->device->base,
|
||||||
|
time,
|
||||||
|
LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tp_post_twofinger_scroll(tp, time);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -362,16 +410,12 @@ tp_post_events(struct tp_dispatch *tp, uint32_t time)
|
||||||
struct tp_touch *t = tp_current_touch(tp);
|
struct tp_touch *t = tp_current_touch(tp);
|
||||||
double dx, dy;
|
double dx, dy;
|
||||||
|
|
||||||
if (tp->nfingers_down > 2) {
|
|
||||||
return;
|
|
||||||
} else if (tp->nfingers_down == 2) {
|
|
||||||
tp_post_twofinger_scroll(tp, time);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tp_tap_handle_state(tp, time) != 0)
|
if (tp_tap_handle_state(tp, time) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (tp_post_scroll_events(tp, time) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (t->history.count >= TOUCHPAD_MIN_SAMPLES) {
|
if (t->history.count >= TOUCHPAD_MIN_SAMPLES) {
|
||||||
tp_get_delta(t, &dx, &dy);
|
tp_get_delta(t, &dx, &dy);
|
||||||
tp_filter_motion(tp, &dx, &dy, time);
|
tp_filter_motion(tp, &dx, &dy, time);
|
||||||
|
|
@ -463,6 +507,15 @@ tp_init_accel(struct tp_dispatch *touchpad, double diagonal)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tp_init_scroll(struct tp_dispatch *tp)
|
||||||
|
{
|
||||||
|
tp->scroll.direction = 0;
|
||||||
|
tp->scroll.state = SCROLL_STATE_NONE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tp_init(struct tp_dispatch *tp,
|
tp_init(struct tp_dispatch *tp,
|
||||||
struct evdev_device *device)
|
struct evdev_device *device)
|
||||||
|
|
@ -485,6 +538,9 @@ tp_init(struct tp_dispatch *tp,
|
||||||
tp->hysteresis.margin_y =
|
tp->hysteresis.margin_y =
|
||||||
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
|
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
|
||||||
|
|
||||||
|
if (tp_init_scroll(tp) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (tp_init_accel(tp, diagonal) != 0)
|
if (tp_init_accel(tp, diagonal) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,11 @@ enum touch_state {
|
||||||
TOUCH_END
|
TOUCH_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum scroll_state {
|
||||||
|
SCROLL_STATE_NONE,
|
||||||
|
SCROLL_STATE_SCROLLING
|
||||||
|
};
|
||||||
|
|
||||||
enum tp_tap_state {
|
enum tp_tap_state {
|
||||||
TAP_STATE_IDLE = 4,
|
TAP_STATE_IDLE = 4,
|
||||||
TAP_STATE_TOUCH,
|
TAP_STATE_TOUCH,
|
||||||
|
|
@ -113,6 +118,11 @@ struct tp_dispatch {
|
||||||
uint32_t old_state;
|
uint32_t old_state;
|
||||||
} buttons; /* physical buttons */
|
} buttons; /* physical buttons */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
enum scroll_state state;
|
||||||
|
enum libinput_pointer_axis direction;
|
||||||
|
} scroll;
|
||||||
|
|
||||||
enum touchpad_event queued;
|
enum touchpad_event queued;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue