From 551700e88722cf2ec77500b913c8164495d179c6 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 3 Jun 2018 13:18:57 +0100 Subject: [PATCH] backend/wayland: fix keyboard keys not pressed/released when focus changes --- backend/wayland/wl_seat.c | 40 ++++++++++++++++++++++++++++++++ include/wlr/types/wlr_keyboard.h | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index cf9b9372d..8ed614094 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -169,12 +170,51 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard, // TODO: set keymap } +static uint32_t get_current_time_msec() { + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + return now.tv_nsec / 1000; +} + static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { + struct wlr_input_device *dev = data; + + uint32_t time = get_current_time_msec(); + + uint32_t *keycode_ptr; + wl_array_for_each(keycode_ptr, keys) { + struct wlr_event_keyboard_key event = { + .keycode = *keycode_ptr, + .state = WLR_KEY_PRESSED, + .time_msec = time, + .update_state = false, + }; + wlr_keyboard_notify_key(dev->keyboard, &event); + } } static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface) { + struct wlr_input_device *dev = data; + + uint32_t time = get_current_time_msec(); + + uint32_t pressed[dev->keyboard->num_keycodes]; + memcpy(pressed, dev->keyboard->keycodes, + dev->keyboard->num_keycodes * sizeof(uint32_t)); + + for (size_t i = 0; i < sizeof(pressed)/sizeof(pressed[0]); ++i) { + uint32_t keycode = pressed[i]; + + struct wlr_event_keyboard_key event = { + .keycode = keycode, + .state = WLR_KEY_RELEASED, + .time_msec = time, + .update_state = false, + }; + wlr_keyboard_notify_key(dev->keyboard, &event); + } } static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index 972885086..67d4e5bef 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -89,7 +89,7 @@ enum wlr_key_state { struct wlr_event_keyboard_key { uint32_t time_msec; uint32_t keycode; - bool update_state; + bool update_state; // if backend doesn't update modifiers on its own enum wlr_key_state state; };