Commit 53d53dd1 authored by Peter Hutterer's avatar Peter Hutterer

touchpad: don't resume a disabled touchpad

A touchpad that was disabled by toggling the sendevents option would come back
normally after a lid resume, despite still being nominally disabled.

https://bugzilla.redhat.com/show_bug.cgi?id=1448962Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
parent 5252fa5d
......@@ -1758,6 +1758,31 @@ tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
tp_sync_slots(tp, device);
}
#define NO_EXCLUDED_DEVICE NULL
static void
tp_resume_conditional(struct tp_dispatch *tp,
struct evdev_device *device,
struct evdev_device *excluded_device)
{
if (tp->sendevents.current_mode == LIBINPUT_CONFIG_SEND_EVENTS_DISABLED)
return;
if (tp->sendevents.current_mode ==
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE) {
struct libinput_device *dev;
list_for_each(dev, &device->base.seat->devices_list, link) {
struct evdev_device *d = evdev_device(dev);
if (d != excluded_device &&
(d->tags & EVDEV_TAG_EXTERNAL_MOUSE)) {
return;
}
}
}
tp_resume(tp, device);
}
static void
tp_trackpoint_timeout(uint64_t now, void *data)
{
......@@ -2010,7 +2035,7 @@ tp_switch_event(uint64_t time, struct libinput_event *event, void *data)
switch (libinput_event_switch_get_switch_state(swev)) {
case LIBINPUT_SWITCH_STATE_OFF:
tp_resume(tp, tp->device);
tp_resume_conditional(tp, tp->device, NO_EXCLUDED_DEVICE);
evdev_log_debug(tp->device, "%s: resume touchpad\n", which);
break;
case LIBINPUT_SWITCH_STATE_ON:
......@@ -2094,7 +2119,6 @@ tp_interface_device_removed(struct evdev_device *device,
struct evdev_device *removed_device)
{
struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
struct libinput_device *dev;
if (removed_device == tp->buttons.trackpoint) {
/* Clear any pending releases for the trackpoint */
......@@ -2127,19 +2151,9 @@ tp_interface_device_removed(struct evdev_device *device,
tp->tablet_mode_switch.tablet_mode_switch = NULL;
}
if (tp->sendevents.current_mode !=
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
return;
list_for_each(dev, &device->base.seat->devices_list, link) {
struct evdev_device *d = evdev_device(dev);
if (d != removed_device &&
(d->tags & EVDEV_TAG_EXTERNAL_MOUSE)) {
return;
}
}
tp_resume(tp, device);
/* removed_device is still in the device list at this point, so we
* need to exclude it from the tp_resume_conditional */
tp_resume_conditional(tp, device, removed_device);
}
static inline void
......
......@@ -418,6 +418,89 @@ START_TEST(switch_disable_touchpad_already_open)
}
END_TEST
START_TEST(switch_dont_resume_disabled_touchpad)
{
struct litest_device *sw = litest_current_device();
struct litest_device *touchpad;
struct libinput *li = sw->libinput;
enum libinput_switch which = _i; /* ranged test */
if (!libinput_device_switch_has_switch(sw->libinput_device, which))
return;
touchpad = switch_init_paired_touchpad(li);
litest_disable_tap(touchpad->libinput_device);
libinput_device_config_send_events_set_mode(touchpad->libinput_device,
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
litest_drain_events(li);
/* switch is on - no events */
litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
/* switch is off but but tp is still disabled */
litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
litest_delete_device(touchpad);
}
END_TEST
START_TEST(switch_dont_resume_disabled_touchpad_external_mouse)
{
struct litest_device *sw = litest_current_device();
struct litest_device *touchpad, *mouse;
struct libinput *li = sw->libinput;
enum libinput_switch which = _i; /* ranged test */
if (!libinput_device_switch_has_switch(sw->libinput_device, which))
return;
touchpad = switch_init_paired_touchpad(li);
mouse = litest_add_device(li, LITEST_MOUSE);
litest_disable_tap(touchpad->libinput_device);
libinput_device_config_send_events_set_mode(touchpad->libinput_device,
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE);
litest_drain_events(li);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
/* switch is on - no events */
litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
/* switch is off but but tp is still disabled */
litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
litest_delete_device(touchpad);
litest_delete_device(mouse);
}
END_TEST
START_TEST(lid_open_on_key)
{
struct litest_device *sw = litest_current_device();
......@@ -744,6 +827,8 @@ litest_setup_tests_lid(void)
litest_add_ranged("switch:touchpad", switch_disable_touchpad_edge_scroll, LITEST_SWITCH, LITEST_ANY, &switches);
litest_add_ranged("switch:touchpad", switch_disable_touchpad_edge_scroll_interrupt, LITEST_SWITCH, LITEST_ANY, &switches);
litest_add_ranged("switch:touchpad", switch_disable_touchpad_already_open, LITEST_SWITCH, LITEST_ANY, &switches);
litest_add_ranged("switch:touchpad", switch_dont_resume_disabled_touchpad, LITEST_SWITCH, LITEST_ANY, &switches);
litest_add_ranged("switch:touchpad", switch_dont_resume_disabled_touchpad_external_mouse, LITEST_SWITCH, LITEST_ANY, &switches);
litest_add_ranged_no_device("switch:keyboard", switch_suspend_with_keyboard, &switches);
litest_add_ranged_no_device("switch:touchpad", switch_suspend_with_touchpad, &switches);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment