[PATCH libinput 5/5] lid: setup the keyboard notifier when pairing it

Peter Hutterer peter.hutterer at who-t.net
Wed May 24 00:04:04 UTC 2017


From: Benjamin Tissoires <benjamin.tissoires at gmail.com>

On unreliable LID switches, we might have the LID declared as closed
while it is actually not. We can not wait for the first switch event to setup
the keyboard listener: it will never occur.

https://bugs.freedesktop.org/show_bug.cgi?id=101099

Signed-off-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-lid.c |  7 +++++--
 test/test-lid.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/src/evdev-lid.c b/src/evdev-lid.c
index 010cb42d..fe98e6e1 100644
--- a/src/evdev-lid.c
+++ b/src/evdev-lid.c
@@ -224,8 +224,11 @@ lid_switch_pair_keyboard(struct evdev_device *lid_switch,
 				lid_switch->devname,
 				keyboard->devname);
 
-		/* We don't init the event listener yet - we don't care
-		 * about keyboard events until the lid is closed */
+		/* We need to init the event listener now only if the reported state
+		 * is closed. */
+		if (dispatch->lid_is_closed)
+			lid_switch_toggle_keyboard_listener(dispatch,
+						    dispatch->lid_is_closed);
 	}
 }
 
diff --git a/test/test-lid.c b/test/test-lid.c
index 1bd75cb6..4bf4c059 100644
--- a/test/test-lid.c
+++ b/test/test-lid.c
@@ -505,6 +505,56 @@ START_TEST(lid_update_hw_on_key)
 }
 END_TEST
 
+START_TEST(lid_update_hw_on_key_closed_on_init)
+{
+	struct litest_device *sw = litest_current_device();
+	struct libinput *li;
+	struct litest_device *keyboard;
+	struct libevdev *evdev = sw->evdev;
+	struct input_event ev;
+
+	litest_lid_action(sw, LIBINPUT_SWITCH_STATE_ON);
+
+	/* Make sure kernel state is right */
+	libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	while (libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_SYNC, &ev) >= 0)
+		;
+	ck_assert(libevdev_get_event_value(evdev, EV_SW, SW_LID));
+
+	keyboard = litest_add_device(sw->libinput, LITEST_KEYBOARD);
+
+	/* separate context for the right state on init */
+	li = litest_create_context();
+	libinput_path_add_device(li,
+				 libevdev_uinput_get_devnode(sw->uinput));
+	libinput_path_add_device(li,
+				 libevdev_uinput_get_devnode(keyboard->uinput));
+
+	/* don't expect a switch waiting for us */
+	while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) {
+		ck_assert_int_ne(libinput_next_event_type(li),
+				 LIBINPUT_EVENT_SWITCH_TOGGLE);
+		libinput_event_destroy(libinput_get_event(li));
+	}
+
+	litest_event(keyboard, EV_KEY, KEY_A, 1);
+	litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
+	litest_event(keyboard, EV_KEY, KEY_A, 0);
+	litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
+	/* No switch event, we're still in vanilla (open) state */
+	litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
+
+	/* Make sure kernel state has updated */
+	libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	while (libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_SYNC, &ev) >= 0)
+		;
+	ck_assert(!libevdev_get_event_value(evdev, EV_SW, SW_LID));
+
+	libinput_unref(li);
+	litest_delete_device(keyboard);
+}
+END_TEST
+
 void
 litest_setup_tests_lid(void)
 {
@@ -525,4 +575,5 @@ litest_setup_tests_lid(void)
 	litest_add_no_device("lid:disable_touchpad", lid_suspend_with_touchpad);
 
 	litest_add_for_device("lid:buggy", lid_update_hw_on_key, LITEST_LID_SWITCH_SURFACE3);
+	litest_add_for_device("lid:buggy", lid_update_hw_on_key_closed_on_init, LITEST_LID_SWITCH_SURFACE3);
 }
-- 
2.13.0



More information about the wayland-devel mailing list