mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-11 22:10:30 +01:00
lid: force the lid to open when the keyboard device is removed
On unreliable tablets (Surface3), always force the lid switch to open when the paired keyboard is removed. This way the lid can't be stuck in a closed state when there's nothing attached that can actually trigger that state. https://bugs.freedesktop.org/show_bug.cgi?id=101100 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
8fbdef3aad
commit
d35d122eb1
2 changed files with 59 additions and 11 deletions
|
|
@ -64,6 +64,23 @@ lid_switch_notify_toggle(struct lid_switch_dispatch *dispatch,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lid_switch_update_kernel_state(struct lid_switch_dispatch *dispatch,
|
||||
uint64_t time)
|
||||
{
|
||||
int fd;
|
||||
const struct input_event ev[2] = {
|
||||
{{ 0, 0 }, EV_SW, SW_LID, 0 },
|
||||
{{ 0, 0 }, EV_SYN, SYN_REPORT, 0 },
|
||||
};
|
||||
|
||||
if (dispatch->reliability != RELIABILITY_WRITE_OPEN)
|
||||
return;
|
||||
|
||||
fd = libevdev_get_fd(dispatch->device->evdev);
|
||||
(void)write(fd, ev, sizeof(ev));
|
||||
}
|
||||
|
||||
static void
|
||||
lid_switch_keyboard_event(uint64_t time,
|
||||
struct libinput_event *event,
|
||||
|
|
@ -77,17 +94,7 @@ lid_switch_keyboard_event(uint64_t time,
|
|||
if (event->type != LIBINPUT_EVENT_KEYBOARD_KEY)
|
||||
return;
|
||||
|
||||
if (dispatch->reliability == RELIABILITY_WRITE_OPEN) {
|
||||
int fd = libevdev_get_fd(dispatch->device->evdev);
|
||||
struct input_event ev[2] = {
|
||||
{{ 0, 0 }, EV_SW, SW_LID, 0 },
|
||||
{{ 0, 0 }, EV_SYN, SYN_REPORT, 0 },
|
||||
};
|
||||
|
||||
(void)write(fd, ev, sizeof(ev));
|
||||
/* In case write() fails, we sync the lid state manually
|
||||
* regardless. */
|
||||
}
|
||||
lid_switch_update_kernel_state(dispatch, time);
|
||||
|
||||
/* Posting the event here means we preempt the keyboard events that
|
||||
* caused us to wake up, so the lid event is always passed on before
|
||||
|
|
@ -246,11 +253,16 @@ lid_switch_interface_device_removed(struct evdev_device *device,
|
|||
struct lid_switch_dispatch *dispatch = lid_dispatch(device->dispatch);
|
||||
|
||||
if (removed_device == dispatch->keyboard.keyboard) {
|
||||
uint64_t time;
|
||||
|
||||
libinput_device_remove_event_listener(
|
||||
&dispatch->keyboard.listener);
|
||||
libinput_device_init_event_listener(
|
||||
&dispatch->keyboard.listener);
|
||||
dispatch->keyboard.keyboard = NULL;
|
||||
|
||||
time = libinput_now(evdev_libinput_context(device));
|
||||
lid_switch_update_kernel_state(dispatch, time);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -555,6 +555,41 @@ START_TEST(lid_update_hw_on_key_closed_on_init)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(lid_force_open_if_no_keyboard)
|
||||
{
|
||||
struct litest_device *sw = litest_current_device();
|
||||
struct libinput *li;
|
||||
struct litest_device *keyboard;
|
||||
|
||||
litest_lid_action(sw, LIBINPUT_SWITCH_STATE_ON);
|
||||
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));
|
||||
|
||||
/* We only have the switch device in this context, not the keyboard.
|
||||
* So don't expect any switch event to be in the pipe and don't
|
||||
* expect the event to change if we type or toggle the state
|
||||
*/
|
||||
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);
|
||||
litest_lid_action(sw, LIBINPUT_SWITCH_STATE_OFF);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
libinput_unref(li);
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
void
|
||||
litest_setup_tests_lid(void)
|
||||
{
|
||||
|
|
@ -576,4 +611,5 @@ litest_setup_tests_lid(void)
|
|||
|
||||
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);
|
||||
litest_add_for_device("lid:buggy", lid_force_open_if_no_keyboard, LITEST_LID_SWITCH_SURFACE3);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue