Merge branch 'master' into tablet-support

This commit is contained in:
Peter Hutterer 2015-03-10 11:28:57 +10:00
commit d3fb0b1ea2
9 changed files with 102 additions and 43 deletions

View file

@ -34,8 +34,7 @@
avoid accidentally locking in scrolling mode when trying to use the entire
touchpad to move the pointer. The user can wait for the timeout to trigger
to do a small scroll. */
/* In mm for touchpads with valid resolution, see tp_init_accel() */
#define DEFAULT_SCROLL_THRESHOLD 10.0
#define DEFAULT_SCROLL_THRESHOLD TP_MM_TO_DPI_NORMALIZED(5)
enum scroll_event {
SCROLL_EVENT_TOUCH,
@ -74,15 +73,15 @@ tp_edge_scroll_set_state(struct tp_dispatch *tp,
switch (state) {
case EDGE_SCROLL_TOUCH_STATE_NONE:
t->scroll.edge = EDGE_NONE;
t->scroll.threshold = DEFAULT_SCROLL_THRESHOLD;
break;
case EDGE_SCROLL_TOUCH_STATE_EDGE_NEW:
t->scroll.edge = tp_touch_get_edge(tp, t);
t->scroll.initial_x = t->x;
t->scroll.initial_y = t->y;
libinput_timer_set(&t->scroll.timer,
t->millis + DEFAULT_SCROLL_LOCK_TIMEOUT);
break;
case EDGE_SCROLL_TOUCH_STATE_EDGE:
t->scroll.threshold = 0.01; /* Do not allow 0.0 events */
break;
case EDGE_SCROLL_TOUCH_STATE_AREA:
t->scroll.edge = EDGE_NONE;
@ -264,7 +263,6 @@ tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device)
tp_for_each_touch(tp, t) {
t->scroll.direction = -1;
t->scroll.threshold = DEFAULT_SCROLL_THRESHOLD;
libinput_timer_init(&t->scroll.timer,
device->base.seat->libinput,
tp_edge_scroll_handle_timeout, t);
@ -315,6 +313,7 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
struct tp_touch *t;
enum libinput_pointer_axis axis;
double dx, dy, *delta;
double initial_dx, initial_dy, *initial_delta;
if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_EDGE)
return 0;
@ -338,10 +337,12 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
case EDGE_RIGHT:
axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
delta = &dy;
initial_delta = &initial_dy;
break;
case EDGE_BOTTOM:
axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
delta = &dx;
initial_delta = &initial_dx;
break;
default: /* EDGE_RIGHT | EDGE_BOTTOM */
continue; /* Don't know direction yet, skip */
@ -350,7 +351,32 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
tp_get_delta(t, &dx, &dy);
tp_filter_motion(tp, &dx, &dy, NULL, NULL, time);
if (fabs(*delta) < t->scroll.threshold)
switch (t->scroll.edge_state) {
case EDGE_SCROLL_TOUCH_STATE_NONE:
case EDGE_SCROLL_TOUCH_STATE_AREA:
log_bug_libinput(device->seat->libinput,
"unexpected scroll state %d\n",
t->scroll.edge_state);
break;
case EDGE_SCROLL_TOUCH_STATE_EDGE_NEW:
initial_dx = t->x - t->scroll.initial_x;
initial_dy = t->y - t->scroll.initial_y;
tp_normalize_delta(tp,
&initial_dx,
&initial_dy);
if (fabs(*initial_delta) < DEFAULT_SCROLL_THRESHOLD) {
dx = 0.0;
dy = 0.0;
} else {
dx = initial_dx;
dy = initial_dy;
}
break;
case EDGE_SCROLL_TOUCH_STATE_EDGE:
break;
}
if (*delta == 0.0)
continue;
pointer_notify_axis(device, time,

View file

@ -37,7 +37,7 @@
#define CASE_RETURN_STRING(a) case a: return #a;
#define DEFAULT_TAP_TIMEOUT_PERIOD 180
#define DEFAULT_TAP_MOVE_THRESHOLD 30
#define DEFAULT_TAP_MOVE_THRESHOLD TP_MM_TO_DPI_NORMALIZED(3)
enum tap_event {
TAP_EVENT_TOUCH = 12,
@ -527,12 +527,15 @@ tp_tap_handle_event(struct tp_dispatch *tp,
}
static bool
tp_tap_exceeds_motion_threshold(struct tp_dispatch *tp, struct tp_touch *t)
tp_tap_exceeds_motion_threshold(struct tp_dispatch *tp,
struct tp_touch *t)
{
int threshold = DEFAULT_TAP_MOVE_THRESHOLD;
double dx, dy;
tp_get_delta(t, &dx, &dy);
dx = abs(t->tap.initial_x - t->x);
dy = abs(t->tap.initial_y - t->y);
tp_normalize_delta(tp, &dx, &dy);
return dx * dx + dy * dy > threshold * threshold;
}
@ -568,6 +571,8 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
if (t->state == TOUCH_BEGIN) {
t->tap.state = TAP_TOUCH_STATE_TOUCH;
t->tap.initial_x = t->x;
t->tap.initial_y = t->y;
tp_tap_handle_event(tp, t, TAP_EVENT_TOUCH, time);
} else if (t->state == TOUCH_END) {
tp_tap_handle_event(tp, t, TAP_EVENT_RELEASE, time);

View file

@ -64,8 +64,8 @@ tp_filter_motion(struct tp_dispatch *tp,
{
struct motion_params motion;
motion.dx = *dx * tp->accel.x_scale_coeff;
motion.dy = *dy * tp->accel.y_scale_coeff;
motion.dx = *dx;
motion.dy = *dy;
if (dx_unaccel)
*dx_unaccel = motion.dx;
@ -269,6 +269,7 @@ tp_get_delta(struct tp_touch *t, double *dx, double *dy)
tp_motion_history_offset(t, 1)->y,
tp_motion_history_offset(t, 2)->y,
tp_motion_history_offset(t, 3)->y);
tp_normalize_delta(t->tp, dx, dy);
}
static void
@ -994,9 +995,8 @@ tp_init_accel(struct tp_dispatch *tp, double diagonal)
fixed in the actual filter code.
*/
{
const double MAGIC = 0.4;
tp->accel.x_scale_coeff *= MAGIC;
tp->accel.y_scale_coeff *= MAGIC;
tp->accel.x_scale_coeff *= TP_MAGIC_SLOWDOWN;
tp->accel.y_scale_coeff *= TP_MAGIC_SLOWDOWN;
}
} else {
/*

View file

@ -34,6 +34,11 @@
#define VENDOR_ID_APPLE 0x5ac
/* Touchpad slowdown factor, see the FIXME in tp_init_accel() */
#define TP_MAGIC_SLOWDOWN 0.4
/* Convert mm to a distance normalized to DEFAULT_MOUSE_DPI */
#define TP_MM_TO_DPI_NORMALIZED(mm) (DEFAULT_MOUSE_DPI/25.4 * TP_MAGIC_SLOWDOWN * mm)
enum touchpad_event {
TOUCHPAD_EVENT_NONE = 0,
TOUCHPAD_EVENT_MOTION = (1 << 0),
@ -127,8 +132,8 @@ struct tp_touch {
enum touch_state state;
bool has_ended; /* TRACKING_ID == -1 */
bool dirty;
int32_t x;
int32_t y;
int32_t x; /* in device coordinates */
int32_t y; /* in device coordinates */
uint64_t millis;
struct {
@ -138,8 +143,8 @@ struct tp_touch {
} history;
struct {
int32_t center_x;
int32_t center_y;
int32_t center_x; /* in device coordinates */
int32_t center_y; /* in device coordinates */
} hysteresis;
/* A pinned touchpoint is the one that pressed the physical button
@ -148,8 +153,8 @@ struct tp_touch {
*/
struct {
bool is_pinned;
int32_t center_x;
int32_t center_y;
int32_t center_x; /* in device coordinates */
int32_t center_y; /* in device coordinates */
} pinned;
/* Software-button state and timeout if applicable */
@ -162,19 +167,22 @@ struct tp_touch {
struct {
enum tp_tap_touch_state state;
int32_t initial_x, initial_y; /* in device coordinates */
} tap;
struct {
enum tp_edge_scroll_touch_state edge_state;
uint32_t edge;
int direction;
double threshold;
struct libinput_timer timer;
int32_t initial_x; /* in device coordinates */
int32_t initial_y; /* in device coordinates */
} scroll;
struct {
bool is_palm;
int32_t x, y; /* first coordinates if is_palm == true */
int32_t x, y; /* first coordinates if is_palm == true,
in device coordinates */
uint32_t time; /* first timestamp if is_palm == true */
} palm;
};
@ -200,8 +208,8 @@ struct tp_dispatch {
unsigned int fake_touches;
struct {
int32_t margin_x;
int32_t margin_y;
int32_t margin_x; /* in device coordiantes */
int32_t margin_y; /* in device coordiantes */
} hysteresis;
struct {
@ -232,14 +240,14 @@ struct tp_dispatch {
* The buttons are split according to the edge settings.
*/
struct {
int32_t top_edge;
int32_t rightbutton_left_edge;
int32_t top_edge; /* in device coordinates */
int32_t rightbutton_left_edge; /* in device coordinates */
} bottom_area;
struct {
int32_t bottom_edge;
int32_t rightbutton_left_edge;
int32_t leftbutton_right_edge;
int32_t bottom_edge; /* in device coordinates */
int32_t rightbutton_left_edge; /* in device coordinates */
int32_t leftbutton_right_edge; /* in device coordinates */
} top_area;
struct evdev_device *trackpoint;
@ -251,8 +259,8 @@ struct tp_dispatch {
struct {
struct libinput_device_config_scroll_method config_method;
enum libinput_config_scroll_method method;
int32_t right_edge;
int32_t bottom_edge;
int32_t right_edge; /* in device coordinates */
int32_t bottom_edge; /* in device coordinates */
} scroll;
enum touchpad_event queued;
@ -267,8 +275,8 @@ struct tp_dispatch {
} tap;
struct {
int32_t right_edge;
int32_t left_edge;
int32_t right_edge; /* in device coordinates */
int32_t left_edge; /* in device coordinates */
} palm;
struct {
@ -283,6 +291,13 @@ struct tp_dispatch {
#define tp_for_each_touch(_tp, _t) \
for (unsigned int _i = 0; _i < (_tp)->ntouches && (_t = &(_tp)->touches[_i]); _i++)
static inline void
tp_normalize_delta(struct tp_dispatch *tp, double *dx, double *dy)
{
*dx = *dx * tp->accel.x_scale_coeff;
*dy = *dy * tp->accel.y_scale_coeff;
}
void
tp_get_delta(struct tp_touch *t, double *dx, double *dy);

View file

@ -33,6 +33,9 @@
#include "libinput-private.h"
#include "timer.h"
/* The HW DPI rate we normalize to before calculating pointer acceleration */
#define DEFAULT_MOUSE_DPI 1000
enum evdev_event_type {
EVDEV_NONE,
EVDEV_ABSOLUTE_TOUCH_DOWN,

View file

@ -28,9 +28,6 @@
#include <stdbool.h>
#include <stdint.h>
/* The HW DPI rate we normalize to before calculating pointer acceleration */
#define DEFAULT_MOUSE_DPI 1000
struct motion_params {
double dx, dy; /* in units/ms @ DEFAULT_MOUSE_DPI resolution */
};

View file

@ -1517,6 +1517,12 @@ litest_timeout_finger_switch(void)
msleep(120);
}
void
litest_timeout_edgescroll(void)
{
msleep(300);
}
void
litest_push_event_frame(struct litest_device *dev)
{

View file

@ -221,6 +221,7 @@ struct libevdev_uinput * litest_create_uinput_abs_device(const char *name,
void litest_timeout_tap(void);
void litest_timeout_softbuttons(void);
void litest_timeout_buttonscroll(void);
void litest_timeout_edgescroll(void);
void litest_timeout_finger_switch(void);
void litest_push_event_frame(struct litest_device *dev);

View file

@ -2057,7 +2057,7 @@ START_TEST(touchpad_edge_scroll)
}
END_TEST
START_TEST(touchpad_edge_scroll_slow_distance)
START_TEST(touchpad_edge_scroll_timeout)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
@ -2067,6 +2067,10 @@ START_TEST(touchpad_edge_scroll_slow_distance)
litest_drain_events(li);
litest_touch_down(dev, 0, 99, 20);
libinput_dispatch(li);
litest_timeout_edgescroll();
libinput_dispatch(li);
litest_touch_move_to(dev, 0, 99, 20, 99, 80, 60, 10);
litest_touch_up(dev, 0);
libinput_dispatch(li);
@ -2074,6 +2078,8 @@ START_TEST(touchpad_edge_scroll_slow_distance)
event = libinput_get_event(li);
ck_assert_notnull(event);
litest_wait_for_event_of_type(li, LIBINPUT_EVENT_POINTER_AXIS, -1);
while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) {
double axisval;
ck_assert_int_eq(libinput_event_get_type(event),
@ -2105,10 +2111,10 @@ START_TEST(touchpad_edge_scroll_no_motion)
litest_drain_events(li);
litest_touch_down(dev, 0, 99, 20);
litest_touch_move_to(dev, 0, 99, 20, 99, 60, 10, 0);
litest_touch_down(dev, 0, 99, 10);
litest_touch_move_to(dev, 0, 99, 10, 99, 70, 10, 0);
/* moving outside -> no motion event */
litest_touch_move_to(dev, 0, 99, 60, 20, 80, 10, 0);
litest_touch_move_to(dev, 0, 99, 70, 20, 80, 10, 0);
/* moving down outside edge once scrolling had started -> scroll */
litest_touch_move_to(dev, 0, 20, 80, 40, 99, 10, 0);
litest_touch_up(dev, 0);
@ -2570,8 +2576,8 @@ START_TEST(touchpad_left_handed_tapping_2fg)
litest_touch_down(dev, 0, 50, 50);
litest_touch_down(dev, 1, 70, 50);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_touch_up(dev, 0);
libinput_dispatch(li);
litest_timeout_tap();
@ -3356,7 +3362,7 @@ int main(int argc, char **argv) {
litest_add("touchpad:tap", touchpad_2fg_tap_n_drag, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:tap", touchpad_2fg_tap_n_drag_3fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_APPLE_CLICKPAD);
litest_add("touchpad:tap", touchpad_2fg_tap_n_drag_3fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:tap", touchpad_2fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:tap", touchpad_2fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("touchpad:tap", touchpad_2fg_tap_inverted, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:tap", touchpad_1fg_tap_click, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_CLICKPAD);
litest_add("touchpad:tap", touchpad_2fg_tap_click, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_SINGLE_TOUCH|LITEST_CLICKPAD);
@ -3427,7 +3433,7 @@ int main(int argc, char **argv) {
litest_add("touchpad:scroll", touchpad_edge_scroll, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
litest_add("touchpad:scroll", touchpad_edge_scroll_no_motion, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
litest_add("touchpad:scroll", touchpad_edge_scroll_no_edge_after_motion, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
litest_add("touchpad:scroll", touchpad_edge_scroll_slow_distance, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
litest_add("touchpad:scroll", touchpad_edge_scroll_timeout, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
litest_add("touchpad:scroll", touchpad_edge_scroll_source, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
litest_add("touchpad:palm", touchpad_palm_detect_at_edge, LITEST_TOUCHPAD, LITEST_ANY);