mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-03-24 12:30:47 +01:00
Compare commits
42 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c95300758 | ||
|
|
d16cbccee6 | ||
|
|
0ef5e3f167 | ||
|
|
a391e89041 | ||
|
|
1ea91b212b | ||
|
|
6c7adee8b0 | ||
|
|
8b338f0b5f | ||
|
|
e4f0ee9677 | ||
|
|
201eaf3a8b | ||
|
|
9585fe86ee | ||
|
|
bab4ca0274 | ||
|
|
579428cdf4 | ||
|
|
f36bb869ee | ||
|
|
75215aaf5e | ||
|
|
71191a88c2 | ||
|
|
f2cfd8a693 | ||
|
|
decfb09027 | ||
|
|
204820e4de | ||
|
|
42e8813a63 | ||
|
|
eeb967b650 | ||
|
|
b437b2f196 | ||
|
|
1c15e162b8 | ||
|
|
40750c26f8 | ||
|
|
dd85749e61 | ||
|
|
2496923585 | ||
|
|
0fec9c65e9 | ||
|
|
c4fc98731d | ||
|
|
3efd7c82aa | ||
|
|
5f4d975861 | ||
|
|
298b28d7f1 | ||
|
|
68949fc5c5 | ||
|
|
25d1fbbf00 | ||
|
|
5c86ba7580 | ||
|
|
c5c6cc13be | ||
|
|
70258657b0 | ||
|
|
596a03a0fa | ||
|
|
71fe2b6ef4 | ||
|
|
fc78cdc4bb | ||
|
|
0fcbb58d97 | ||
|
|
c726f37ebd | ||
|
|
3d4712d10a | ||
|
|
076c7b6c00 |
28 changed files with 777 additions and 861 deletions
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 78 KiB |
10
meson.build
10
meson.build
|
|
@ -1,5 +1,5 @@
|
|||
project('libinput', 'c', 'cpp',
|
||||
version : '1.10.0',
|
||||
version : '1.10.5',
|
||||
license : 'MIT/Expat',
|
||||
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
|
||||
meson_version : '>= 0.40.0')
|
||||
|
|
@ -234,7 +234,7 @@ pkgconfig.generate(
|
|||
# Restore the SELinux context for the libinput.so.a.b.c on install
|
||||
# meson bug https://github.com/mesonbuild/meson/issues/1967
|
||||
meson.add_install_script('src/libinput-restore-selinux-context.sh',
|
||||
get_option('libdir'),
|
||||
join_paths(get_option('prefix'), get_option('libdir')),
|
||||
lib_libinput.full_path())
|
||||
|
||||
############ documentation ############
|
||||
|
|
@ -496,7 +496,8 @@ configure_file(input : 'tools/libinput.man',
|
|||
install_dir : join_paths(get_option('mandir'), 'man1')
|
||||
)
|
||||
|
||||
meson.add_install_script('tools/install-compat-scripts.sh')
|
||||
meson.add_install_script('tools/install-compat-scripts.sh',
|
||||
join_paths(get_option('prefix'), get_option('bindir')))
|
||||
|
||||
ptraccel_debug_sources = [ 'tools/ptraccel-debug.c' ]
|
||||
executable('ptraccel-debug',
|
||||
|
|
@ -522,7 +523,7 @@ if get_option('tests')
|
|||
config_h.set10('HAVE_LIBUNWIND', dep_libunwind.found())
|
||||
|
||||
# for inhibit support during test run
|
||||
dep_libsystemd = dependency('libsystemd', required : false)
|
||||
dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false)
|
||||
config_h.set10('HAVE_LIBSYSTEMD', dep_libsystemd.found())
|
||||
|
||||
lib_litest_sources = [
|
||||
|
|
@ -563,6 +564,7 @@ if get_option('tests')
|
|||
'test/litest-device-mouse-low-dpi.c',
|
||||
'test/litest-device-mouse-wheel-click-angle.c',
|
||||
'test/litest-device-mouse-wheel-click-count.c',
|
||||
'test/litest-device-ms-nano-transceiver-mouse.c',
|
||||
'test/litest-device-ms-surface-cover.c',
|
||||
'test/litest-device-protocol-a-touch-screen.c',
|
||||
'test/litest-device-qemu-usb-tablet.c',
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ debounce_state_to_str(enum debounce_state state)
|
|||
CASE_RETURN_STRING(DEBOUNCE_STATE_MAYBE_SPURIOUS);
|
||||
CASE_RETURN_STRING(DEBOUNCE_STATE_RELEASED);
|
||||
CASE_RETURN_STRING(DEBOUNCE_STATE_PRESS_PENDING);
|
||||
CASE_RETURN_STRING(DEBOUNCE_STATE_DISABLED);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
@ -394,6 +395,31 @@ debounce_press_pending_event(struct fallback_dispatch *fallback, enum debounce_e
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
debounce_disabled_event(struct fallback_dispatch *fallback,
|
||||
enum debounce_event event,
|
||||
uint64_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case DEBOUNCE_EVENT_PRESS:
|
||||
fallback->debounce.button_time = time;
|
||||
debounce_notify_button(fallback,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
break;
|
||||
case DEBOUNCE_EVENT_RELEASE:
|
||||
fallback->debounce.button_time = time;
|
||||
debounce_notify_button(fallback,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
break;
|
||||
case DEBOUNCE_EVENT_TIMEOUT_SHORT:
|
||||
case DEBOUNCE_EVENT_TIMEOUT:
|
||||
log_debounce_bug(fallback, event);
|
||||
break;
|
||||
case DEBOUNCE_EVENT_OTHERBUTTON:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
debounce_handle_event(struct fallback_dispatch *fallback,
|
||||
enum debounce_event event,
|
||||
|
|
@ -434,6 +460,9 @@ debounce_handle_event(struct fallback_dispatch *fallback,
|
|||
case DEBOUNCE_STATE_PRESS_PENDING:
|
||||
debounce_press_pending_event(fallback, event, time);
|
||||
break;
|
||||
case DEBOUNCE_STATE_DISABLED:
|
||||
debounce_disabled_event(fallback, event, time);
|
||||
break;
|
||||
}
|
||||
|
||||
evdev_log_debug(fallback->device,
|
||||
|
|
@ -484,7 +513,8 @@ fallback_debounce_handle_state(struct fallback_dispatch *dispatch,
|
|||
for (size_t i = 0; i < nchanged; i++) {
|
||||
bool is_down = hw_is_key_down(dispatch, changed[i]);
|
||||
|
||||
if (flushed) {
|
||||
if (flushed &&
|
||||
dispatch->debounce.state != DEBOUNCE_STATE_DISABLED) {
|
||||
debounce_set_state(dispatch,
|
||||
!is_down ?
|
||||
DEBOUNCE_STATE_IS_DOWN :
|
||||
|
|
@ -538,6 +568,13 @@ fallback_init_debounce(struct fallback_dispatch *dispatch)
|
|||
struct evdev_device *device = dispatch->device;
|
||||
char timer_name[64];
|
||||
|
||||
if (device->model_flags &
|
||||
(EVDEV_MODEL_MS_NANO_TRANSCEIVER|EVDEV_MODEL_LOGITECH_K400)) {
|
||||
dispatch->debounce.state = DEBOUNCE_STATE_DISABLED;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
dispatch->debounce.state = DEBOUNCE_STATE_IS_UP;
|
||||
|
||||
snprintf(timer_name,
|
||||
|
|
|
|||
|
|
@ -127,12 +127,9 @@ fallback_filter_defuzz_touch(struct fallback_dispatch *dispatch,
|
|||
if (!dispatch->mt.want_hysteresis)
|
||||
return false;
|
||||
|
||||
point.x = evdev_hysteresis(slot->point.x,
|
||||
slot->hysteresis_center.x,
|
||||
dispatch->mt.hysteresis_margin.x);
|
||||
point.y = evdev_hysteresis(slot->point.y,
|
||||
slot->hysteresis_center.y,
|
||||
dispatch->mt.hysteresis_margin.y);
|
||||
point = evdev_hysteresis(&slot->point,
|
||||
&slot->hysteresis_center,
|
||||
&dispatch->mt.hysteresis_margin);
|
||||
|
||||
slot->hysteresis_center = slot->point;
|
||||
if (point.x == slot->point.x && point.y == slot->point.y)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ enum debounce_state {
|
|||
DEBOUNCE_STATE_MAYBE_SPURIOUS,
|
||||
DEBOUNCE_STATE_RELEASED,
|
||||
DEBOUNCE_STATE_PRESS_PENDING,
|
||||
|
||||
DEBOUNCE_STATE_DISABLED = 999,
|
||||
};
|
||||
|
||||
struct fallback_dispatch {
|
||||
|
|
|
|||
|
|
@ -362,6 +362,13 @@ tp_edge_scroll_handle_state(struct tp_dispatch *tp, uint64_t time)
|
|||
case TOUCH_UPDATE:
|
||||
tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_MOTION);
|
||||
break;
|
||||
case TOUCH_MAYBE_END:
|
||||
/* This shouldn't happen we transfer to TOUCH_END
|
||||
* before processing state */
|
||||
evdev_log_debug(tp->device,
|
||||
"touch unexpected state %d\n",
|
||||
t->state);
|
||||
/* fallthrough */
|
||||
case TOUCH_END:
|
||||
tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_RELEASE);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1025,6 +1025,7 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
|
|||
|
||||
} else if (t->state == TOUCH_END) {
|
||||
if (t->was_down) {
|
||||
assert(tp->tap.nfingers_down >= 1);
|
||||
tp->tap.nfingers_down--;
|
||||
tp_tap_handle_event(tp, t, TAP_EVENT_RELEASE, time);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,10 @@ tp_calculate_motion_speed(struct tp_dispatch *tp, struct tp_touch *t)
|
|||
double distance;
|
||||
double speed;
|
||||
|
||||
/* Don't do this on single-touch or semi-mt devices */
|
||||
if (!tp->has_mt || tp->semi_mt)
|
||||
return;
|
||||
|
||||
/* This doesn't kick in until we have at least 4 events in the
|
||||
* motion history. As a side-effect, this automatically handles the
|
||||
* 2fg scroll where a finger is down and moving fast before the
|
||||
|
|
@ -131,46 +135,75 @@ tp_motion_history_push(struct tp_touch *t)
|
|||
t->history.index = motion_index;
|
||||
}
|
||||
|
||||
/* Idea: if we got a tuple of *very* quick moves like {Left, Right,
|
||||
* Left}, or {Right, Left, Right}, it means touchpad jitters since no
|
||||
* human can move like that within thresholds.
|
||||
*
|
||||
* We encode left moves as zeroes, and right as ones. We also drop
|
||||
* the array to all zeroes when contraints are not satisfied. Then we
|
||||
* search for the pattern {1,0,1}. It can't match {Left, Right, Left},
|
||||
* but it does match {Left, Right, Left, Right}, so it's okay.
|
||||
*
|
||||
* This only looks at x changes, y changes are ignored.
|
||||
*/
|
||||
static inline void
|
||||
tp_maybe_disable_hysteresis(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_detect_wobbling(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
uint64_t time)
|
||||
{
|
||||
/* If the finger is down for 80ms without seeing motion events,
|
||||
the firmware filters and we don't need a software hysteresis */
|
||||
if (tp->nfingers_down >= 1 &&
|
||||
time - tp->hysteresis.last_motion_time > ms2us(80)) {
|
||||
tp->hysteresis.enabled = false;
|
||||
evdev_log_debug(tp->device, "hysteresis disabled\n");
|
||||
int dx, dy;
|
||||
uint64_t dtime;
|
||||
|
||||
if (!(tp->queued & TOUCHPAD_EVENT_MOTION) || tp->hysteresis.enabled)
|
||||
return;
|
||||
|
||||
if (t->last_point.x == 0) { /* first invocation */
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
} else {
|
||||
dx = t->last_point.x - t->point.x;
|
||||
dy = t->last_point.y - t->point.y;
|
||||
}
|
||||
|
||||
dtime = time - tp->hysteresis.last_motion_time;
|
||||
|
||||
tp->hysteresis.last_motion_time = time;
|
||||
t->last_point = t->point;
|
||||
|
||||
if (dx == 0 && dy != 0) /* ignore y-only changes */
|
||||
return;
|
||||
|
||||
if (dtime > ms2us(40)) {
|
||||
t->hysteresis.x_motion_history = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (tp->queued & TOUCHPAD_EVENT_MOTION)
|
||||
tp->hysteresis.last_motion_time = time;
|
||||
t->hysteresis.x_motion_history >>= 1;
|
||||
if (dx > 0) { /* right move */
|
||||
static const char r_l_r = 0x5; /* {Right, Left, Right} */
|
||||
|
||||
|
||||
t->hysteresis.x_motion_history |= (1 << 2);
|
||||
if (t->hysteresis.x_motion_history == r_l_r) {
|
||||
tp->hysteresis.enabled = true;
|
||||
evdev_log_debug(tp->device, "hysteresis enabled\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_motion_hysteresis(struct tp_dispatch *tp,
|
||||
struct tp_touch *t)
|
||||
{
|
||||
int x = t->point.x,
|
||||
y = t->point.y;
|
||||
|
||||
if (!tp->hysteresis.enabled)
|
||||
return;
|
||||
|
||||
if (t->history.count == 0) {
|
||||
t->hysteresis_center = t->point;
|
||||
} else {
|
||||
x = evdev_hysteresis(x,
|
||||
t->hysteresis_center.x,
|
||||
tp->hysteresis.margin.x);
|
||||
y = evdev_hysteresis(y,
|
||||
t->hysteresis_center.y,
|
||||
tp->hysteresis.margin.y);
|
||||
t->hysteresis_center.x = x;
|
||||
t->hysteresis_center.y = y;
|
||||
t->point.x = x;
|
||||
t->point.y = y;
|
||||
}
|
||||
if (t->history.count > 0)
|
||||
t->point = evdev_hysteresis(&t->point,
|
||||
&t->hysteresis.center,
|
||||
&tp->hysteresis.margin);
|
||||
|
||||
t->hysteresis.center = t->point;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -276,6 +309,7 @@ tp_new_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
t->time = time;
|
||||
t->speed.last_speed = 0;
|
||||
t->speed.exceeded_count = 0;
|
||||
t->hysteresis.x_motion_history = 0;
|
||||
tp->queued |= TOUCHPAD_EVENT_MOTION;
|
||||
}
|
||||
|
||||
|
|
@ -296,23 +330,69 @@ tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
tp->hysteresis.last_motion_time = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a touch to be ended, based on either the events or some
|
||||
* attributes of the touch (size, pressure). In some cases we need to
|
||||
* resurrect a touch that has ended, so this doesn't actually end the touch
|
||||
* yet. All the TOUCH_MAYBE_END touches get properly ended once the device
|
||||
* state has been processed once and we know how many zombie touches we
|
||||
* need.
|
||||
*/
|
||||
static inline void
|
||||
tp_maybe_end_touch(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
uint64_t time)
|
||||
{
|
||||
switch (t->state) {
|
||||
case TOUCH_NONE:
|
||||
case TOUCH_MAYBE_END:
|
||||
return;
|
||||
case TOUCH_END:
|
||||
evdev_log_bug_libinput(tp->device,
|
||||
"touch already in TOUCH_END\n");
|
||||
return;
|
||||
case TOUCH_HOVERING:
|
||||
case TOUCH_BEGIN:
|
||||
case TOUCH_UPDATE:
|
||||
break;
|
||||
}
|
||||
|
||||
if (t->state != TOUCH_HOVERING) {
|
||||
assert(tp->nfingers_down >= 1);
|
||||
tp->nfingers_down--;
|
||||
t->state = TOUCH_MAYBE_END;
|
||||
} else {
|
||||
t->state = TOUCH_NONE;
|
||||
}
|
||||
|
||||
t->dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverse to tp_maybe_end_touch(), restores a touch back to its previous
|
||||
* state.
|
||||
*/
|
||||
static inline void
|
||||
tp_recover_ended_touch(struct tp_dispatch *tp,
|
||||
struct tp_touch *t)
|
||||
{
|
||||
t->dirty = true;
|
||||
t->state = TOUCH_UPDATE;
|
||||
tp->nfingers_down++;
|
||||
}
|
||||
|
||||
/**
|
||||
* End a touch, even if the touch sequence is still active.
|
||||
* Use tp_maybe_end_touch() instead.
|
||||
*/
|
||||
static inline void
|
||||
tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
{
|
||||
switch (t->state) {
|
||||
case TOUCH_HOVERING:
|
||||
t->state = TOUCH_NONE;
|
||||
/* fallthough */
|
||||
case TOUCH_NONE:
|
||||
case TOUCH_END:
|
||||
if (t->state != TOUCH_MAYBE_END) {
|
||||
evdev_log_bug_libinput(tp->device,
|
||||
"touch should be MAYBE_END, is %d\n",
|
||||
t->state);
|
||||
return;
|
||||
case TOUCH_BEGIN:
|
||||
case TOUCH_UPDATE:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
t->dirty = true;
|
||||
|
|
@ -321,8 +401,6 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
t->pinned.is_pinned = false;
|
||||
t->time = time;
|
||||
t->palm.time = 0;
|
||||
assert(tp->nfingers_down >= 1);
|
||||
tp->nfingers_down--;
|
||||
tp->queued |= TOUCHPAD_EVENT_MOTION;
|
||||
}
|
||||
|
||||
|
|
@ -333,7 +411,7 @@ static inline void
|
|||
tp_end_sequence(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
{
|
||||
t->has_ended = true;
|
||||
tp_end_touch(tp, t, time);
|
||||
tp_maybe_end_touch(tp, t, time);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -480,13 +558,11 @@ tp_restore_synaptics_touches(struct tp_dispatch *tp,
|
|||
for (i = 0; i < tp->num_slots; i++) {
|
||||
struct tp_touch *t = tp_get_touch(tp, i);
|
||||
|
||||
if (t->state != TOUCH_END)
|
||||
if (t->state != TOUCH_MAYBE_END)
|
||||
continue;
|
||||
|
||||
/* new touch, move it through begin to update immediately */
|
||||
tp_new_touch(tp, t, time);
|
||||
tp_begin_touch(tp, t, time);
|
||||
t->state = TOUCH_UPDATE;
|
||||
tp_recover_ended_touch(tp, t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1070,11 +1146,17 @@ tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time)
|
|||
tp_motion_history_reset(t);
|
||||
tp_begin_touch(tp, t, time);
|
||||
}
|
||||
} else {
|
||||
/* don't unhover for pressure if we have too many
|
||||
* fake fingers down, see comment below. Except
|
||||
* for single-finger touches where the real touch
|
||||
* decides for the rest.
|
||||
*/
|
||||
} else if (nfake_touches <= tp->num_slots ||
|
||||
tp->num_slots == 1) {
|
||||
if (t->pressure < tp->pressure.low) {
|
||||
evdev_log_debug(tp->device,
|
||||
"pressure: end touch\n");
|
||||
tp_end_touch(tp, t, time);
|
||||
tp_maybe_end_touch(tp, t, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1092,14 +1174,16 @@ tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time)
|
|||
* _all_ fingers have enough pressure, even if some of the slotted
|
||||
* ones don't. Anything else gets insane quickly.
|
||||
*/
|
||||
tp_for_each_touch(tp, t) {
|
||||
if (t->state == TOUCH_HOVERING) {
|
||||
/* avoid jumps when landing a finger */
|
||||
tp_motion_history_reset(t);
|
||||
tp_begin_touch(tp, t, time);
|
||||
if (real_fingers_down > 0) {
|
||||
tp_for_each_touch(tp, t) {
|
||||
if (t->state == TOUCH_HOVERING) {
|
||||
/* avoid jumps when landing a finger */
|
||||
tp_motion_history_reset(t);
|
||||
tp_begin_touch(tp, t, time);
|
||||
|
||||
if (tp->nfingers_down >= nfake_touches)
|
||||
break;
|
||||
if (tp->nfingers_down >= nfake_touches)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1109,10 +1193,11 @@ tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time)
|
|||
t = tp_get_touch(tp, i);
|
||||
|
||||
if (t->state == TOUCH_HOVERING ||
|
||||
t->state == TOUCH_NONE)
|
||||
t->state == TOUCH_NONE ||
|
||||
t->state == TOUCH_MAYBE_END)
|
||||
continue;
|
||||
|
||||
tp_end_touch(tp, t, time);
|
||||
tp_maybe_end_touch(tp, t, time);
|
||||
|
||||
if (real_fingers_down > 0 &&
|
||||
tp->nfingers_down == nfake_touches)
|
||||
|
|
@ -1154,7 +1239,7 @@ tp_unhover_size(struct tp_dispatch *tp, uint64_t time)
|
|||
if (t->major < low || t->minor < low) {
|
||||
evdev_log_debug(tp->device,
|
||||
"touch-size: end touch\n");
|
||||
tp_end_touch(tp, t, time);
|
||||
tp_maybe_end_touch(tp, t, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1208,7 +1293,7 @@ tp_unhover_fake_touches(struct tp_dispatch *tp, uint64_t time)
|
|||
t->state == TOUCH_NONE)
|
||||
continue;
|
||||
|
||||
tp_end_touch(tp, t, time);
|
||||
tp_maybe_end_touch(tp, t, time);
|
||||
|
||||
if (tp_fake_finger_is_touching(tp) &&
|
||||
tp->nfingers_down == nfake_touches)
|
||||
|
|
@ -1375,6 +1460,21 @@ tp_detect_thumb_while_moving(struct tp_dispatch *tp)
|
|||
second->thumb.state = THUMB_STATE_YES;
|
||||
}
|
||||
|
||||
static void
|
||||
tp_pre_process_state(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
|
||||
tp_process_fake_touches(tp, time);
|
||||
tp_unhover_touches(tp, time);
|
||||
|
||||
tp_for_each_touch(tp, t) {
|
||||
if (t->state == TOUCH_MAYBE_END)
|
||||
tp_end_touch(tp, t, time);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
tp_process_state(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
|
|
@ -1384,13 +1484,14 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
|
|||
bool have_new_touch = false;
|
||||
unsigned int speed_exceeded_count = 0;
|
||||
|
||||
tp_process_fake_touches(tp, time);
|
||||
tp_unhover_touches(tp, time);
|
||||
tp_position_fake_touches(tp);
|
||||
|
||||
want_motion_reset = tp_need_motion_history_reset(tp);
|
||||
|
||||
tp_for_each_touch(tp, t) {
|
||||
if (t->state == TOUCH_NONE)
|
||||
continue;
|
||||
|
||||
if (want_motion_reset) {
|
||||
tp_motion_history_reset(t);
|
||||
t->quirks.reset_motion_history = true;
|
||||
|
|
@ -1420,7 +1521,7 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
|
|||
|
||||
tp_thumb_detect(tp, t, time);
|
||||
tp_palm_detect(tp, t, time);
|
||||
|
||||
tp_detect_wobbling(tp, t, time);
|
||||
tp_motion_hysteresis(tp, t);
|
||||
tp_motion_history_push(t);
|
||||
|
||||
|
|
@ -1544,9 +1645,7 @@ static void
|
|||
tp_handle_state(struct tp_dispatch *tp,
|
||||
uint64_t time)
|
||||
{
|
||||
if (tp->hysteresis.enabled)
|
||||
tp_maybe_disable_hysteresis(tp, time);
|
||||
|
||||
tp_pre_process_state(tp, time);
|
||||
tp_process_state(tp, time);
|
||||
tp_post_events(tp, time);
|
||||
tp_post_process_state(tp, time);
|
||||
|
|
@ -2690,7 +2789,7 @@ tp_init_palmdetect_edge(struct tp_dispatch *tp,
|
|||
edges = evdev_device_mm_to_units(device, &mm);
|
||||
tp->palm.right_edge = edges.x;
|
||||
|
||||
if (!tp->buttons.has_topbuttons) {
|
||||
if (!tp->buttons.has_topbuttons && height > 55) {
|
||||
/* top edge is 5% of the height */
|
||||
mm.y = height * 0.05;
|
||||
edges = evdev_device_mm_to_units(device, &mm);
|
||||
|
|
@ -2930,13 +3029,23 @@ tp_init_default_resolution(struct tp_dispatch *tp,
|
|||
static inline void
|
||||
tp_init_hysteresis(struct tp_dispatch *tp)
|
||||
{
|
||||
int res_x, res_y;
|
||||
int xmargin, ymargin;
|
||||
const struct input_absinfo *ax = tp->device->abs.absinfo_x,
|
||||
*ay = tp->device->abs.absinfo_y;
|
||||
|
||||
res_x = tp->device->abs.absinfo_x->resolution;
|
||||
res_y = tp->device->abs.absinfo_y->resolution;
|
||||
tp->hysteresis.margin.x = res_x/2;
|
||||
tp->hysteresis.margin.y = res_y/2;
|
||||
tp->hysteresis.enabled = true;
|
||||
if (ax->fuzz)
|
||||
xmargin = ax->fuzz;
|
||||
else
|
||||
xmargin = ax->resolution/4;
|
||||
|
||||
if (ay->fuzz)
|
||||
ymargin = ay->fuzz;
|
||||
else
|
||||
ymargin = ay->resolution/4;
|
||||
|
||||
tp->hysteresis.margin.x = xmargin;
|
||||
tp->hysteresis.margin.y = ymargin;
|
||||
tp->hysteresis.enabled = false;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2995,7 +3104,9 @@ tp_init_pressure(struct tp_dispatch *tp,
|
|||
tp->pressure.low = lo;
|
||||
|
||||
evdev_log_debug(device,
|
||||
"using pressure-based touch detection\n");
|
||||
"using pressure-based touch detection (%d:%d)\n",
|
||||
lo,
|
||||
hi);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
|||
|
|
@ -46,10 +46,11 @@ enum touchpad_event {
|
|||
|
||||
enum touch_state {
|
||||
TOUCH_NONE = 0,
|
||||
TOUCH_HOVERING,
|
||||
TOUCH_BEGIN,
|
||||
TOUCH_UPDATE,
|
||||
TOUCH_END
|
||||
TOUCH_HOVERING = 1,
|
||||
TOUCH_BEGIN = 2,
|
||||
TOUCH_UPDATE = 3,
|
||||
TOUCH_MAYBE_END = 4,
|
||||
TOUCH_END = 5,
|
||||
};
|
||||
|
||||
enum touch_palm_state {
|
||||
|
|
@ -147,6 +148,7 @@ struct tp_touch {
|
|||
bool has_ended; /* TRACKING_ID == -1 */
|
||||
bool dirty;
|
||||
struct device_coords point;
|
||||
struct device_coords last_point;
|
||||
uint64_t time;
|
||||
int pressure;
|
||||
bool is_tool_palm; /* MT_TOOL_PALM */
|
||||
|
|
@ -173,7 +175,10 @@ struct tp_touch {
|
|||
unsigned int count;
|
||||
} history;
|
||||
|
||||
struct device_coords hysteresis_center;
|
||||
struct {
|
||||
struct device_coords center;
|
||||
uint8_t x_motion_history;
|
||||
} hysteresis;
|
||||
|
||||
/* A pinned touchpoint is the one that pressed the physical button
|
||||
* on a clickpad. After the release, it won't move until the center
|
||||
|
|
|
|||
16
src/evdev.c
16
src/evdev.c
|
|
@ -1180,6 +1180,12 @@ evdev_get_trackpoint_range(struct evdev_device *device)
|
|||
goto out;
|
||||
}
|
||||
|
||||
evdev_log_info(device,
|
||||
"trackpoint does not have a specified range, "
|
||||
"guessing... see %strackpoints.html\n",
|
||||
HTTP_DOC_LINK);
|
||||
|
||||
|
||||
prop = udev_device_get_property_value(device->udev_device,
|
||||
"POINTINGSTICK_SENSITIVITY");
|
||||
if (prop) {
|
||||
|
|
@ -1251,6 +1257,7 @@ evdev_read_model_flags(struct evdev_device *device)
|
|||
MODEL(ALPS_TOUCHPAD),
|
||||
MODEL(SYNAPTICS_SERIAL_TOUCHPAD),
|
||||
MODEL(JUMPING_SEMI_MT),
|
||||
MODEL(LOGITECH_K400),
|
||||
MODEL(CYBORG_RAT),
|
||||
MODEL(HP_STREAM11_TOUCHPAD),
|
||||
MODEL(LENOVO_T450_TOUCHPAD),
|
||||
|
|
@ -1264,6 +1271,7 @@ evdev_read_model_flags(struct evdev_device *device)
|
|||
MODEL(APPLE_TOUCHPAD_ONEBUTTON),
|
||||
MODEL(LOGITECH_MARBLE_MOUSE),
|
||||
MODEL(TABLET_NO_PROXIMITY_OUT),
|
||||
MODEL(MS_NANO_TRANSCEIVER),
|
||||
#undef MODEL
|
||||
{ "ID_INPUT_TRACKBALL", EVDEV_MODEL_TRACKBALL },
|
||||
{ NULL, EVDEV_MODEL_DEFAULT },
|
||||
|
|
@ -1917,6 +1925,11 @@ evdev_device_create(struct libinput_seat *seat,
|
|||
const char *devnode = udev_device_get_devnode(udev_device);
|
||||
const char *sysname = udev_device_get_sysname(udev_device);
|
||||
|
||||
if (!devnode) {
|
||||
log_info(libinput, "%s: no device node associated\n", sysname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (udev_device_should_be_ignored(udev_device)) {
|
||||
log_debug(libinput, "%s: device is ignored\n", sysname);
|
||||
return NULL;
|
||||
|
|
@ -2434,6 +2447,9 @@ evdev_device_resume(struct evdev_device *device)
|
|||
return -ENODEV;
|
||||
|
||||
devnode = udev_device_get_devnode(device->udev_device);
|
||||
if (!devnode)
|
||||
return -ENODEV;
|
||||
|
||||
fd = open_restricted(libinput, devnode,
|
||||
O_RDWR | O_NONBLOCK | O_CLOEXEC);
|
||||
|
||||
|
|
|
|||
94
src/evdev.h
94
src/evdev.h
|
|
@ -110,6 +110,7 @@ enum evdev_device_model {
|
|||
EVDEV_MODEL_ALPS_TOUCHPAD = (1 << 8),
|
||||
EVDEV_MODEL_SYNAPTICS_SERIAL_TOUCHPAD = (1 << 9),
|
||||
EVDEV_MODEL_JUMPING_SEMI_MT = (1 << 10),
|
||||
EVDEV_MODEL_LOGITECH_K400 = (1 << 11),
|
||||
EVDEV_MODEL_LENOVO_X220_TOUCHPAD_FW81 = (1 << 12),
|
||||
EVDEV_MODEL_CYBORG_RAT = (1 << 14),
|
||||
EVDEV_MODEL_HP_STREAM11_TOUCHPAD = (1 << 16),
|
||||
|
|
@ -124,6 +125,7 @@ enum evdev_device_model {
|
|||
EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON = (1 << 25),
|
||||
EVDEV_MODEL_LOGITECH_MARBLE_MOUSE = (1 << 26),
|
||||
EVDEV_MODEL_TABLET_NO_PROXIMITY_OUT = (1 << 27),
|
||||
EVDEV_MODEL_MS_NANO_TRANSCEIVER = (1 << 28),
|
||||
};
|
||||
|
||||
enum evdev_button_scroll_state {
|
||||
|
|
@ -599,11 +601,11 @@ evdev_to_left_handed(struct evdev_device *device,
|
|||
* Apply a hysteresis filtering to the coordinate in, based on the current
|
||||
* hysteresis center and the margin. If 'in' is within 'margin' of center,
|
||||
* return the center (and thus filter the motion). If 'in' is outside,
|
||||
* return a point on the edge of the new margin. So for a point x in the
|
||||
* space outside c + margin we return r:
|
||||
* +---+ +---+
|
||||
* return a point on the edge of the new margin (which is an ellipse, usually
|
||||
* a circle). So for a point x in the space outside c + margin we return r:
|
||||
* ,---. ,---.
|
||||
* | c | x → | r x
|
||||
* +---+ +---+
|
||||
* `---' `---'
|
||||
*
|
||||
* The effect of this is that initial small motions are filtered. Once we
|
||||
* move into one direction we lag the real coordinates by 'margin' but any
|
||||
|
|
@ -616,41 +618,71 @@ evdev_to_left_handed(struct evdev_device *device,
|
|||
* Otherwise, the center has a dead zone of size margin around it and the
|
||||
* first reachable point is the margin edge.
|
||||
*
|
||||
* Hysteresis is handled separately per axis (and the window is thus
|
||||
* rectangular, not circular). It is unkown if that's an issue, but the
|
||||
* calculation to do circular hysteresis are nontrivial, especially since
|
||||
* many touchpads have uneven x/y resolutions.
|
||||
*
|
||||
* Given coordinates, 0, 1, 2, ... this is what we return for a margin of 3
|
||||
* and a center of 0:
|
||||
*
|
||||
* Input: 1 2 3 4 5 6 5 4 3 2 1 0 -1
|
||||
* Coord: 0 0 0 1 2 3 3 3 3 3 3 3 2
|
||||
* Center: 0 0 0 1 2 3 3 3 3 3 3 3 2
|
||||
*
|
||||
* Problem: viewed from a stationary finger that starts moving, the
|
||||
* hysteresis margin is M in both directions. Once we start moving
|
||||
* continuously though, the margin is 0 in the movement direction and 2*M to
|
||||
* change direction. That makes the finger less responsive to directional
|
||||
* changes than to the original movement.
|
||||
*
|
||||
* @param in The input coordinate
|
||||
* @param center Current center of the hysteresis
|
||||
* @param margin Hysteresis width (on each side)
|
||||
*
|
||||
* @return The new center of the hysteresis
|
||||
*/
|
||||
static inline int
|
||||
evdev_hysteresis(int in, int center, int margin)
|
||||
static inline struct device_coords
|
||||
evdev_hysteresis(const struct device_coords *in,
|
||||
const struct device_coords *center,
|
||||
const struct device_coords *margin)
|
||||
{
|
||||
int diff = in - center;
|
||||
if (abs(diff) <= margin)
|
||||
return center;
|
||||
int dx = in->x - center->x;
|
||||
int dy = in->y - center->y;
|
||||
int dx2 = dx * dx;
|
||||
int dy2 = dy * dy;
|
||||
int a = margin->x;
|
||||
int b = margin->y;
|
||||
double normalized_finger_distance, finger_distance, margin_distance;
|
||||
double lag_x, lag_y;
|
||||
struct device_coords result;
|
||||
|
||||
if (diff > 0)
|
||||
return in - margin;
|
||||
else
|
||||
return in + margin;
|
||||
if (!a || !b)
|
||||
return *in;
|
||||
|
||||
/*
|
||||
* Basic equation for an ellipse of radii a,b:
|
||||
* x²/a² + y²/b² = 1
|
||||
* But we start by making a scaled ellipse passing through the
|
||||
* relative finger location (dx,dy). So the scale of this ellipse is
|
||||
* the ratio of finger_distance to margin_distance:
|
||||
* dx²/a² + dy²/b² = normalized_finger_distance²
|
||||
*/
|
||||
normalized_finger_distance = sqrt((double)dx2 / (a * a) +
|
||||
(double)dy2 / (b * b));
|
||||
|
||||
/* Which means anything less than 1 is within the elliptical margin */
|
||||
if (normalized_finger_distance < 1.0)
|
||||
return *center;
|
||||
|
||||
finger_distance = sqrt(dx2 + dy2);
|
||||
margin_distance = finger_distance / normalized_finger_distance;
|
||||
|
||||
/*
|
||||
* Now calculate the x,y coordinates on the edge of the margin ellipse
|
||||
* where it intersects the finger vector. Shortcut: We achieve this by
|
||||
* finding the point with the same gradient as dy/dx.
|
||||
*/
|
||||
if (dx) {
|
||||
double gradient = (double)dy / dx;
|
||||
lag_x = margin_distance / sqrt(gradient * gradient + 1);
|
||||
lag_y = sqrt((margin_distance + lag_x) *
|
||||
(margin_distance - lag_x));
|
||||
} else { /* Infinite gradient */
|
||||
lag_x = 0.0;
|
||||
lag_y = margin_distance;
|
||||
}
|
||||
|
||||
/*
|
||||
* 'result' is the centre of an ellipse (radii a,b) which has been
|
||||
* dragged by the finger moving inside it to 'in'. The finger is now
|
||||
* touching the margin ellipse at some point: (±lag_x,±lag_y)
|
||||
*/
|
||||
result.x = (dx >= 0) ? in->x - lag_x : in->x + lag_x;
|
||||
result.y = (dy >= 0) ? in->y - lag_y : in->y + lag_y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline struct libinput *
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ libdir="$1"
|
|||
sofile=$(basename "$2")
|
||||
|
||||
if command -v restorecon >/dev/null; then
|
||||
echo "Restoring SELinux context on $MESON_INSTALL_DESTDIR_PREFIX/$libdir/$sofile"
|
||||
restorecon "$MESON_INSTALL_DESTDIR_PREFIX/$libdir/$sofile"
|
||||
echo "Restoring SELinux context on ${DESTDIR}${libdir}/${sofile}"
|
||||
restorecon "${DESTDIR}${libdir}/${sofile}"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -4325,7 +4325,7 @@ libinput_device_config_calibration_get_matrix(struct libinput_device *device,
|
|||
*
|
||||
* @see libinput_device_config_calibration_has_matrix
|
||||
* @see libinput_device_config_calibration_set_matrix
|
||||
* @see libinput_device_config_calibration_get_default_matrix
|
||||
* @see libinput_device_config_calibration_get_matrix
|
||||
*/
|
||||
int
|
||||
libinput_device_config_calibration_get_default_matrix(struct libinput_device *device,
|
||||
|
|
|
|||
|
|
@ -150,6 +150,17 @@ udev_input_add_devices(struct udev_input *input, struct udev *udev)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Skip unconfigured device. udev will send an event
|
||||
* when device is fully configured */
|
||||
if (!udev_device_get_is_initialized(device)) {
|
||||
log_debug(&input->base,
|
||||
"%-7s - skip unconfigured input device '%s'\n",
|
||||
sysname,
|
||||
udev_device_get_devnode(device));
|
||||
udev_device_unref(device);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (device_added(device, input, NULL) < 0) {
|
||||
udev_device_unref(device);
|
||||
udev_enumerate_unref(e);
|
||||
|
|
@ -229,7 +240,7 @@ udev_input_enable(struct libinput *libinput)
|
|||
struct udev *udev = input->udev;
|
||||
int fd;
|
||||
|
||||
if (input->udev_monitor)
|
||||
if (input->udev_monitor || !input->seat_id)
|
||||
return 0;
|
||||
|
||||
input->udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
|
||||
|
|
|
|||
59
test/litest-device-ms-nano-transceiver-mouse.c
Normal file
59
test/litest-device-ms-nano-transceiver-mouse.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright © 2018 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "litest.h"
|
||||
#include "litest-int.h"
|
||||
|
||||
static struct input_id input_id = {
|
||||
.bustype = 0x3,
|
||||
.vendor = 0x045e,
|
||||
.product = 0x0800,
|
||||
};
|
||||
|
||||
static int events[] = {
|
||||
EV_KEY, BTN_LEFT,
|
||||
EV_KEY, BTN_RIGHT,
|
||||
EV_KEY, BTN_MIDDLE,
|
||||
EV_KEY, BTN_SIDE,
|
||||
EV_KEY, BTN_EXTRA,
|
||||
EV_REL, REL_X,
|
||||
EV_REL, REL_Y,
|
||||
EV_REL, REL_WHEEL,
|
||||
EV_REL, REL_DIAL,
|
||||
EV_REL, REL_HWHEEL,
|
||||
-1 , -1,
|
||||
};
|
||||
|
||||
TEST_DEVICE("ms-nano-mouse",
|
||||
.type = LITEST_MS_NANO_TRANSCEIVER_MOUSE,
|
||||
.features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_WHEEL | LITEST_NO_DEBOUNCE,
|
||||
.interface = NULL,
|
||||
|
||||
.name = "Microsoft Microsoft® Nano Transceiver v2.0",
|
||||
.id = &input_id,
|
||||
.absinfo = NULL,
|
||||
.events = events,
|
||||
)
|
||||
|
||||
|
|
@ -270,6 +270,7 @@ enum litest_device_type {
|
|||
LITEST_WACOM_BAMBOO_2FG_PEN,
|
||||
LITEST_WACOM_BAMBOO_2FG_FINGER,
|
||||
LITEST_HP_WMI_HOTKEYS,
|
||||
LITEST_MS_NANO_TRANSCEIVER_MOUSE,
|
||||
};
|
||||
|
||||
enum litest_device_feature {
|
||||
|
|
@ -303,6 +304,7 @@ enum litest_device_feature {
|
|||
LITEST_LEDS = 1 << 25,
|
||||
LITEST_SWITCH = 1 << 26,
|
||||
LITEST_IGNORED = 1 << 27,
|
||||
LITEST_NO_DEBOUNCE = 1 << 28,
|
||||
};
|
||||
|
||||
/* this is a semi-mt device, so we keep track of the touches that the tests
|
||||
|
|
|
|||
|
|
@ -2602,11 +2602,11 @@ litest_setup_tests_pointer(void)
|
|||
|
||||
litest_add("pointer:time", pointer_time_usec, LITEST_RELATIVE, LITEST_ANY);
|
||||
|
||||
litest_add_ranged("pointer:debounce", debounce_bounce, LITEST_BUTTON, LITEST_TOUCHPAD, &buttons);
|
||||
litest_add("pointer:debounce", debounce_bounce_check_immediate, LITEST_BUTTON, LITEST_TOUCHPAD);
|
||||
litest_add_ranged("pointer:debounce", debounce_spurious, LITEST_BUTTON, LITEST_TOUCHPAD, &buttons);
|
||||
litest_add("pointer:debounce", debounce_spurious_multibounce, LITEST_BUTTON, LITEST_TOUCHPAD);
|
||||
litest_add("pointer:debounce_otherbutton", debounce_spurious_dont_enable_on_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD);
|
||||
litest_add("pointer:debounce_otherbutton", debounce_spurious_cancel_debounce_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD);
|
||||
litest_add("pointer:debounce_otherbutton", debounce_spurious_switch_to_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD);
|
||||
litest_add_ranged("pointer:debounce", debounce_bounce, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE, &buttons);
|
||||
litest_add("pointer:debounce", debounce_bounce_check_immediate, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
|
||||
litest_add_ranged("pointer:debounce", debounce_spurious, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE, &buttons);
|
||||
litest_add("pointer:debounce", debounce_spurious_multibounce, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
|
||||
litest_add("pointer:debounce_otherbutton", debounce_spurious_dont_enable_on_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
|
||||
litest_add("pointer:debounce_otherbutton", debounce_spurious_cancel_debounce_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
|
||||
litest_add("pointer:debounce_otherbutton", debounce_spurious_switch_to_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1591,6 +1591,117 @@ START_TEST(touchpad_3fg_tap_quickrelease)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_3fg_tap_pressure_btntool)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) >= 2)
|
||||
return;
|
||||
|
||||
/* libinput doesn't export when it uses pressure detection, so we
|
||||
* need to reconstruct this here. Specifically, semi-mt devices are
|
||||
* non-mt in libinput, so if they have ABS_PRESSURE, they'll use it.
|
||||
*/
|
||||
if (!libevdev_has_event_code(dev->evdev, EV_ABS, ABS_MT_PRESSURE))
|
||||
return;
|
||||
|
||||
litest_enable_tap(dev->libinput_device);
|
||||
litest_enable_edge_scroll(dev);
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
litest_touch_down(dev, 1, 70, 50);
|
||||
libinput_dispatch(li);
|
||||
|
||||
litest_touch_move_to(dev, 0, 50, 50, 50, 70, 10, 0);
|
||||
litest_touch_move_to(dev, 1, 70, 50, 50, 70, 10, 0);
|
||||
litest_drain_events(li);
|
||||
|
||||
/* drop below the pressure threshold in the same frame as starting a
|
||||
* third touch, see
|
||||
* E: 8713.954784 0001 014e 0001 # EV_KEY / BTN_TOOL_TRIPLETAP 1
|
||||
* in https://bugs.freedesktop.org/attachment.cgi?id=137672
|
||||
*/
|
||||
litest_event(dev, EV_ABS, ABS_MT_PRESSURE, 3);
|
||||
litest_event(dev, EV_ABS, ABS_PRESSURE, 3);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
libinput_dispatch(li);
|
||||
|
||||
litest_push_event_frame(dev);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
|
||||
litest_pop_event_frame(dev);
|
||||
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_up(dev, 1);
|
||||
libinput_dispatch(li);
|
||||
litest_timeout_tap();
|
||||
libinput_dispatch(li);
|
||||
|
||||
litest_assert_button_event(li,
|
||||
BTN_MIDDLE,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_button_event(li,
|
||||
BTN_MIDDLE,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_3fg_tap_hover_btntool)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) >= 2)
|
||||
return;
|
||||
|
||||
/* libinput doesn't export when it uses pressure detection, so we
|
||||
* need to reconstruct this here. Specifically, semi-mt devices are
|
||||
* non-mt in libinput, so if they have ABS_PRESSURE, they'll use it.
|
||||
*/
|
||||
if (libevdev_has_event_code(dev->evdev, EV_ABS, ABS_MT_PRESSURE))
|
||||
return;
|
||||
|
||||
if (libevdev_has_property(dev->evdev, INPUT_PROP_SEMI_MT) &&
|
||||
libevdev_has_event_code(dev->evdev, EV_ABS, ABS_PRESSURE))
|
||||
return;
|
||||
|
||||
litest_enable_tap(dev->libinput_device);
|
||||
litest_enable_edge_scroll(dev);
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
litest_touch_down(dev, 1, 70, 50);
|
||||
libinput_dispatch(li);
|
||||
|
||||
litest_touch_move_to(dev, 0, 50, 50, 50, 70, 10, 0);
|
||||
litest_touch_move_to(dev, 1, 70, 50, 50, 70, 10, 0);
|
||||
litest_drain_events(li);
|
||||
|
||||
/* drop below the pressure threshold in the same frame as starting a
|
||||
* third touch */
|
||||
litest_event(dev, EV_KEY, BTN_TOUCH, 0);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
libinput_dispatch(li);
|
||||
|
||||
litest_push_event_frame(dev);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
|
||||
litest_pop_event_frame(dev);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_up(dev, 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_3fg_tap_btntool)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
|
|
@ -3273,6 +3384,8 @@ litest_setup_tests_touchpad_tap(void)
|
|||
litest_add_ranged("tap-3fg:3fg", touchpad_3fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &tap_map_range);
|
||||
litest_add("tap-3fg:3fg", touchpad_3fg_tap_tap_again, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
|
||||
litest_add("tap-3fg:3fg", touchpad_3fg_tap_quickrelease, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
|
||||
litest_add("tap-3fg:3fg", touchpad_3fg_tap_hover_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
|
||||
litest_add("tap-3fg:3fg", touchpad_3fg_tap_pressure_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
|
||||
litest_add_for_device("tap-3fg:3fg", touchpad_3fg_tap_btntool_pointerjump, LITEST_SYNAPTICS_TOPBUTTONPAD);
|
||||
litest_add("tap-4fg:4fg", touchpad_4fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
|
||||
litest_add("tap-4fg:4fg", touchpad_4fg_tap_quickrelease, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
|
||||
|
|
|
|||
|
|
@ -953,7 +953,7 @@ START_TEST(touchpad_edge_scroll_into_area)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
static int
|
||||
static bool
|
||||
touchpad_has_palm_detect_size(struct litest_device *dev)
|
||||
{
|
||||
double width, height;
|
||||
|
|
@ -975,6 +975,20 @@ touchpad_has_palm_detect_size(struct litest_device *dev)
|
|||
return rc == 0 && width >= 70;
|
||||
}
|
||||
|
||||
static bool
|
||||
touchpad_has_top_palm_detect_size(struct litest_device *dev)
|
||||
{
|
||||
double width, height;
|
||||
int rc;
|
||||
|
||||
if (!touchpad_has_palm_detect_size(dev))
|
||||
return false;
|
||||
|
||||
rc = libinput_device_get_size(dev->libinput_device, &width, &height);
|
||||
|
||||
return rc == 0 && height > 55;
|
||||
}
|
||||
|
||||
START_TEST(touchpad_palm_detect_at_edge)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
|
|
@ -1009,7 +1023,7 @@ START_TEST(touchpad_palm_detect_at_top)
|
|||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
if (!touchpad_has_palm_detect_size(dev))
|
||||
if (!touchpad_has_top_palm_detect_size(dev))
|
||||
return;
|
||||
|
||||
litest_disable_tap(dev->libinput_device);
|
||||
|
|
@ -1131,7 +1145,7 @@ START_TEST(touchpad_palm_detect_top_palm_stays_palm)
|
|||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
if (!touchpad_has_palm_detect_size(dev))
|
||||
if (!touchpad_has_top_palm_detect_size(dev))
|
||||
return;
|
||||
|
||||
litest_disable_tap(dev->libinput_device);
|
||||
|
|
@ -1178,7 +1192,7 @@ START_TEST(touchpad_palm_detect_top_palm_becomes_pointer)
|
|||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
if (!touchpad_has_palm_detect_size(dev))
|
||||
if (!touchpad_has_top_palm_detect_size(dev))
|
||||
return;
|
||||
|
||||
litest_disable_tap(dev->libinput_device);
|
||||
|
|
@ -1231,7 +1245,7 @@ START_TEST(touchpad_palm_detect_no_palm_moving_into_top)
|
|||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
if (!touchpad_has_palm_detect_size(dev))
|
||||
if (!touchpad_has_top_palm_detect_size(dev))
|
||||
return;
|
||||
|
||||
litest_disable_tap(dev->libinput_device);
|
||||
|
|
@ -1260,7 +1274,7 @@ START_TEST(touchpad_palm_detect_no_tap_top_edge)
|
|||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
if (!touchpad_has_palm_detect_size(dev))
|
||||
if (!touchpad_has_top_palm_detect_size(dev))
|
||||
return;
|
||||
|
||||
litest_enable_tap(dev->libinput_device);
|
||||
|
|
@ -4473,6 +4487,43 @@ START_TEST(touchpad_thumb_moving)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_thumb_moving_empty_slots)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
litest_disable_tap(dev->libinput_device);
|
||||
litest_enable_2fg_scroll(dev);
|
||||
|
||||
if (libevdev_get_num_slots(dev->evdev) < 3)
|
||||
return;
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
/* exceed the speed movement threshold in slot 0 */
|
||||
litest_touch_down(dev, 0, 50, 20);
|
||||
litest_touch_move_to(dev, 0, 50, 20, 70, 99, 15, 0);
|
||||
litest_touch_up(dev, 0);
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
/* scroll in slots 1 and 2 */
|
||||
litest_touch_down(dev, 1, 50, 50);
|
||||
litest_touch_down(dev, 2, 90, 50);
|
||||
libinput_dispatch(li);
|
||||
for (int i = 0, y = 50; i < 10; i++, y++) {
|
||||
litest_touch_move_to(dev, 1, 50, y, 50, y + 1, 1, 0);
|
||||
litest_touch_move_to(dev, 2, 50, y, 50, y + 1, 1, 0);
|
||||
}
|
||||
libinput_dispatch(li);
|
||||
litest_touch_up(dev, 1);
|
||||
litest_touch_up(dev, 2);
|
||||
libinput_dispatch(li);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 2);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_thumb_clickfinger)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
|
|
@ -5423,6 +5474,111 @@ START_TEST(touchpad_pressure_tap_2fg_1fg_light)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_pressure_btntool)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct axis_replacement axes[] = {
|
||||
{ ABS_MT_PRESSURE, 5 },
|
||||
{ ABS_PRESSURE, 5 },
|
||||
{ -1, 0 }
|
||||
};
|
||||
|
||||
/* we only have tripletap, can't test 4 slots because nothing will
|
||||
* happen */
|
||||
if (libevdev_get_num_slots(dev->evdev) != 2)
|
||||
return;
|
||||
|
||||
if (!touchpad_has_pressure(dev))
|
||||
return;
|
||||
|
||||
litest_enable_tap(dev->libinput_device);
|
||||
litest_drain_events(li);
|
||||
|
||||
/* Two light touches down, doesn't count */
|
||||
litest_touch_down_extended(dev, 0, 40, 50, axes);
|
||||
litest_touch_down_extended(dev, 1, 45, 50, axes);
|
||||
libinput_dispatch(li);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
/* Tripletap but since no finger is logically down, it doesn't count */
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
/* back to two fingers */
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
libinput_dispatch(li);
|
||||
|
||||
/* make one finger real */
|
||||
litest_touch_move_to(dev, 0, 40, 50, 41, 52, 10, 10);
|
||||
litest_drain_events(li);
|
||||
|
||||
/* tripletap should now be 3 fingers tap */
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
libinput_dispatch(li);
|
||||
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
libinput_dispatch(li);
|
||||
|
||||
litest_timeout_tap();
|
||||
libinput_dispatch(li);
|
||||
|
||||
litest_assert_button_event(li,
|
||||
BTN_MIDDLE,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_button_event(li,
|
||||
BTN_MIDDLE,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_pressure_semi_mt_2fg_goes_light)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct axis_replacement axes[] = {
|
||||
{ ABS_PRESSURE, 2 },
|
||||
{ -1, 0 }
|
||||
};
|
||||
|
||||
litest_enable_2fg_scroll(dev);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 40, 50);
|
||||
litest_touch_down(dev, 1, 60, 50);
|
||||
litest_touch_move_two_touches(dev, 40, 50, 60, 50, 0, -20, 10, 0);
|
||||
|
||||
/* This should trigger a scroll end event */
|
||||
litest_push_event_frame(dev);
|
||||
litest_touch_move_extended(dev, 0, 40, 31, axes);
|
||||
litest_touch_move_extended(dev, 1, 60, 31, axes);
|
||||
litest_pop_event_frame(dev);
|
||||
libinput_dispatch(li);
|
||||
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 0);
|
||||
|
||||
litest_push_event_frame(dev);
|
||||
litest_touch_move_extended(dev, 0, 40, 35, axes);
|
||||
litest_touch_move_extended(dev, 1, 60, 35, axes);
|
||||
litest_pop_event_frame(dev);
|
||||
|
||||
litest_push_event_frame(dev);
|
||||
litest_touch_move_extended(dev, 0, 40, 40, axes);
|
||||
litest_touch_move_extended(dev, 1, 60, 40, axes);
|
||||
litest_pop_event_frame(dev);
|
||||
libinput_dispatch(li);
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static inline bool
|
||||
touchpad_has_touch_size(struct litest_device *dev)
|
||||
{
|
||||
|
|
@ -5779,6 +5935,7 @@ litest_setup_tests_touchpad(void)
|
|||
litest_add("touchpad:thumb", touchpad_thumb_begin_no_motion, LITEST_CLICKPAD, LITEST_ANY);
|
||||
litest_add("touchpad:thumb", touchpad_thumb_update_no_motion, LITEST_CLICKPAD, LITEST_ANY);
|
||||
litest_add("touchpad:thumb", touchpad_thumb_moving, LITEST_CLICKPAD, LITEST_ANY);
|
||||
litest_add("touchpad:thumb", touchpad_thumb_moving_empty_slots, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
|
||||
litest_add("touchpad:thumb", touchpad_thumb_clickfinger, LITEST_CLICKPAD, LITEST_ANY);
|
||||
litest_add("touchpad:thumb", touchpad_thumb_btnarea, LITEST_CLICKPAD, LITEST_ANY);
|
||||
litest_add("touchpad:thumb", touchpad_thumb_tap_begin, LITEST_CLICKPAD, LITEST_ANY);
|
||||
|
|
@ -5805,7 +5962,9 @@ litest_setup_tests_touchpad(void)
|
|||
litest_add("touchpad:pressure", touchpad_pressure_2fg_st, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
|
||||
litest_add("touchpad:pressure", touchpad_pressure_tap, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:pressure", touchpad_pressure_tap_2fg, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:pressure", touchpad_pressure_tap_2fg_1fg_light, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:pressure", touchpad_pressure_tap_2fg_1fg_light, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
|
||||
litest_add("touchpad:pressure", touchpad_pressure_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
|
||||
litest_add("touchpad:pressure", touchpad_pressure_semi_mt_2fg_goes_light, LITEST_SEMI_MT, LITEST_ANY);
|
||||
|
||||
litest_add("touchpad:touch-size", touchpad_touch_size, LITEST_APPLE_CLICKPAD, LITEST_ANY);
|
||||
litest_add("touchpad:touch-size", touchpad_touch_size_2fg, LITEST_APPLE_CLICKPAD, LITEST_ANY);
|
||||
|
|
|
|||
|
|
@ -394,6 +394,47 @@ START_TEST(udev_suspend_resume)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(udev_resume_before_seat)
|
||||
{
|
||||
struct libinput *li;
|
||||
struct udev *udev;
|
||||
int rc;
|
||||
|
||||
udev = udev_new();
|
||||
ck_assert(udev != NULL);
|
||||
|
||||
li = libinput_udev_create_context(&simple_interface, NULL, udev);
|
||||
ck_assert(li != NULL);
|
||||
|
||||
rc = libinput_resume(li);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
|
||||
libinput_unref(li);
|
||||
udev_unref(udev);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(udev_suspend_resume_before_seat)
|
||||
{
|
||||
struct libinput *li;
|
||||
struct udev *udev;
|
||||
int rc;
|
||||
|
||||
udev = udev_new();
|
||||
ck_assert(udev != NULL);
|
||||
|
||||
li = libinput_udev_create_context(&simple_interface, NULL, udev);
|
||||
ck_assert(li != NULL);
|
||||
|
||||
libinput_suspend(li);
|
||||
rc = libinput_resume(li);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
|
||||
libinput_unref(li);
|
||||
udev_unref(udev);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(udev_device_sysname)
|
||||
{
|
||||
struct libinput *li;
|
||||
|
|
@ -619,6 +660,8 @@ litest_setup_tests_udev(void)
|
|||
litest_add_for_device("udev:suspend", udev_double_suspend, LITEST_SYNAPTICS_CLICKPAD_X220);
|
||||
litest_add_for_device("udev:suspend", udev_double_resume, LITEST_SYNAPTICS_CLICKPAD_X220);
|
||||
litest_add_for_device("udev:suspend", udev_suspend_resume, LITEST_SYNAPTICS_CLICKPAD_X220);
|
||||
litest_add_for_device("udev:suspend", udev_resume_before_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
|
||||
litest_add_for_device("udev:suspend", udev_suspend_resume_before_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
|
||||
litest_add_for_device("udev:device events", udev_device_sysname, LITEST_SYNAPTICS_CLICKPAD_X220);
|
||||
litest_add_for_device("udev:seat", udev_seat_recycle, LITEST_SYNAPTICS_CLICKPAD_X220);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# This does not honor $bindir properly, because we cannot get to it
|
||||
# here. Does anyone build to something but prefix/bin?
|
||||
#
|
||||
bindir="${DESTDIR}/${MESON_INSTALL_PREFIX}/bin"
|
||||
mkdir -p "$bindir"
|
||||
|
||||
bindir="${DESTDIR}${1}"
|
||||
|
||||
# Do not create bindir, because if it is not there now, we have a problem
|
||||
cp "${MESON_SOURCE_ROOT}/tools/libinput-list-devices.compat" "${bindir}/libinput-list-devices"
|
||||
cp "${MESON_SOURCE_ROOT}/tools/libinput-debug-events.compat" "${bindir}/libinput-debug-events"
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ Enable or disable middle button emulation
|
|||
.B \-\-enable\-dwt|\-\-disable\-dwt
|
||||
Enable or disable disable-while-typing
|
||||
.TP 8
|
||||
.B \-\-set\-click\-method=[none|clickfinger|buttons]
|
||||
.B \-\-set\-click\-method=[none|clickfinger|buttonareas]
|
||||
Set the desired click method
|
||||
.TP 8
|
||||
.B \-\-set\-scroll\-method=[none|twofinger|edge|button]
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ class Device(object):
|
|||
ud = pyudev.Devices.from_device_file(context, self.path)
|
||||
v = ud.get('LIBINPUT_ATTR_TOUCH_SIZE_RANGE')
|
||||
if v:
|
||||
self.up, self.down = colon_tuple(v)
|
||||
self.down, self.up = colon_tuple(v)
|
||||
|
||||
v = ud.get('LIBINPUT_ATTR_PALM_SIZE_THRESHOLD')
|
||||
if v:
|
||||
|
|
|
|||
|
|
@ -163,8 +163,8 @@ class Device(object):
|
|||
prange = p.max - p.min
|
||||
|
||||
# libinput defaults
|
||||
self.up = int(p.min + 0.12 * prange)
|
||||
self.down = int(p.min + 0.10 * prange)
|
||||
self.down = int(p.min + 0.12 * prange)
|
||||
self.up = int(p.min + 0.10 * prange)
|
||||
self.palm = 130 # the libinput default
|
||||
|
||||
self._init_thresholds_from_udev()
|
||||
|
|
@ -189,7 +189,7 @@ class Device(object):
|
|||
ud = pyudev.Devices.from_device_file(context, self.path)
|
||||
v = ud.get('LIBINPUT_ATTR_PRESSURE_RANGE')
|
||||
if v:
|
||||
self.up, self.down = colon_tuple(v)
|
||||
self.down, self.up = colon_tuple(v)
|
||||
|
||||
v = ud.get('LIBINPUT_ATTR_PALM_PRESSURE_THRESHOLD')
|
||||
if v:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# vim: set expandtab shiftwidth=4:
|
||||
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
|
||||
#
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ main(int argc, char **argv)
|
|||
{ 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "h", opts, &option_index);
|
||||
c = getopt_long(argc, argv, "+h", opts, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -59,8 +59,10 @@ libinput:name:*Apple Inc. Apple Internal Keyboard*:dmi:*
|
|||
libinput:mouse:input:b0005v05ACp030D*
|
||||
LIBINPUT_MODEL_APPLE_MAGICMOUSE=1
|
||||
|
||||
# Magic Trackpad
|
||||
libinput:touchpad:input:b0005v05ACp030E*
|
||||
LIBINPUT_ATTR_SIZE_HINT=130x110
|
||||
LIBINPUT_ATTR_TOUCH_SIZE_RANGE=60:40
|
||||
|
||||
libinput:touchpad:input:b0003v05ACp021A*
|
||||
LIBINPUT_MODEL_APPLE_TOUCHPAD_ONEBUTTON=1
|
||||
|
|
@ -95,6 +97,10 @@ libinput:name:* Touchpad:dmi:*svnDellInc.:*
|
|||
libinput:name:*AlpsPS/2 ALPS GlidePoint:dmi:*svnDellInc.:pnLatitudeE6220:*
|
||||
LIBINPUT_ATTR_PRESSURE_RANGE=100:90
|
||||
|
||||
libinput:name:*CyPS/2 Cypress Trackpad:dmi:*svnDell*:*XPSL322X*
|
||||
LIBINPUT_ATTR_PRESSURE_RANGE=30:20
|
||||
LIBINPUT_ATTR_PALM_PRESSURE_THRESHOLD=254
|
||||
|
||||
##########################################
|
||||
# Elantech
|
||||
##########################################
|
||||
|
|
@ -196,6 +202,20 @@ libinput:tablet:input:b0003v256Cp*
|
|||
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadX230*
|
||||
LIBINPUT_MODEL_LENOVO_X230=1
|
||||
|
||||
# T440p on PS/2
|
||||
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadT440p*
|
||||
# T440p on RMI4
|
||||
libinput:name:Synaptics tm2964-001:dmi:*svnLENOVO:*:pvrThinkPadT440p*
|
||||
LIBINPUT_MODEL_LENOVO_T450_TOUCHPAD=1
|
||||
|
||||
# T440s trackpoint
|
||||
libinput:name:TPPS/2 IBM TrackPoint:dmi:*svnLENOVO:*:pvrThinkPadT440s*
|
||||
LIBINPUT_ATTR_TRACKPOINT_RANGE=30
|
||||
|
||||
# T450s trackpoint
|
||||
libinput:name:TPPS/2 IBM TrackPoint:dmi:*svnLENOVO:*:pvrThinkPadT450s*
|
||||
LIBINPUT_ATTR_TRACKPOINT_RANGE=50
|
||||
|
||||
# Lenovo T450/T460 and all other Lenovos of the *50 and *60 generation,
|
||||
# including the X1 Carbon 3rd gen
|
||||
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPad??50*:
|
||||
|
|
@ -208,6 +228,10 @@ libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadX1Carbon3rd
|
|||
libinput:keyboard:input:b0003v17EFp6047*
|
||||
LIBINPUT_ATTR_KEYBOARD_INTEGRATION=external
|
||||
|
||||
# Lenovo X280
|
||||
libinput:name:*ALPS TrackPoint*:svnLENOVO:*:pvrThinkPadX280:*
|
||||
LIBINPUT_ATTR_TRACKPOINT_RANGE=70
|
||||
|
||||
##########################################
|
||||
# Logitech
|
||||
##########################################
|
||||
|
|
@ -218,6 +242,10 @@ libinput:name:*Logitech M570*:dmi:*
|
|||
libinput:mouse:input:b0003v046DpC408*
|
||||
LIBINPUT_MODEL_LOGITECH_MARBLE_MOUSE=1
|
||||
|
||||
# Logitech K400
|
||||
libinput:mouse:input:b0003v046Dp4024*
|
||||
LIBINPUT_MODEL_LOGITECH_K400=1
|
||||
|
||||
##########################################
|
||||
# Microsoft
|
||||
##########################################
|
||||
|
|
@ -229,6 +257,10 @@ libinput:name:*Lid Switch*:dmi:*svnMicrosoftCorporation:pnSurface3:*
|
|||
libinput:name:*Microsoft Surface Type Cover Keyboard*:dmi:*svnMicrosoftCorporation:pnSurface3:*
|
||||
LIBINPUT_ATTR_KEYBOARD_INTEGRATION=internal
|
||||
|
||||
# Microsoft Microsoft® Nano Transceiver v2.0"
|
||||
libinput:mouse:input:b0003v045Ep0800*
|
||||
LIBINPUT_MODEL_MS_NANO_TRANSCEIVER=1
|
||||
|
||||
##########################################
|
||||
# Razer
|
||||
##########################################
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ def property_grammar():
|
|||
('LIBINPUT_ATTR_LID_SWITCH_RELIABILITY',
|
||||
Or(('reliable', 'write_open'))),
|
||||
('LIBINPUT_ATTR_KEYBOARD_INTEGRATION', Or(('internal', 'external'))),
|
||||
('LIBINPUT_ATTR_TRACKPOINT_RANGE', INTEGER('Y')),
|
||||
)
|
||||
value_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE') for
|
||||
name, val in vprops]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue