diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index af837ff5..e2d50b03 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -28,6 +28,8 @@ enum wlr_keyboard_modifier { WLR_MODIFIER_MOD5 = 128, }; +#define WLR_KEYBOARD_KEYS_CAP 32 + struct wlr_keyboard_impl; struct wlr_keyboard { @@ -41,6 +43,7 @@ struct wlr_keyboard { xkb_led_index_t led_indexes[WLR_LED_COUNT]; xkb_mod_index_t mod_indexes[WLR_MODIFIER_COUNT]; + uint32_t keycodes[WLR_KEYBOARD_KEYS_CAP]; struct { xkb_mod_mask_t depressed; xkb_mod_mask_t latched; diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index c27264ef..98ebeed5 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -45,6 +45,30 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { wl_signal_emit(&keyboard->events.modifiers, keyboard); } +static void keyboard_key_update(struct wlr_keyboard *keyboard, + struct wlr_event_keyboard_key *event) { + bool found = false; + size_t i = 0; + for (; i < WLR_KEYBOARD_KEYS_CAP; ++i) { + if (keyboard->keycodes[i] == event->keycode) { + found = true; + break; + } + } + + if (event->state == WLR_KEY_PRESSED && !found) { + for (size_t i = 0; i < WLR_KEYBOARD_KEYS_CAP; ++i) { + if (keyboard->keycodes[i] == 0) { + keyboard->keycodes[i] = event->keycode; + break; + } + } + } + if (event->state == WLR_KEY_RELEASED && found) { + keyboard->keycodes[i] = 0; + } +} + void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { @@ -68,6 +92,7 @@ void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, } keyboard_led_update(keyboard); keyboard_modifier_update(keyboard); + keyboard_key_update(keyboard, event); wl_signal_emit(&keyboard->events.key, event); } diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 76b34d31..ae991383 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -751,13 +751,26 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, // enter the current surface if (client && client->keyboard) { - // TODO: read the currently pressed keys out of the active keyboard and - // put them in this array + struct wlr_keyboard *keyboard = wlr_seat->keyboard_state.keyboard; + struct wl_array keys; wl_array_init(&keys); + size_t n = 0; + for (size_t i = 0; i < WLR_KEYBOARD_KEYS_CAP; ++i) { + if (keyboard->keycodes[i] != 0) { + wl_array_add(&keys, sizeof(uint32_t)); + ((uint32_t *)keys.data)[n] = keyboard->keycodes[i]; + n++; + } + } uint32_t serial = wl_display_next_serial(wlr_seat->display); wl_keyboard_send_enter(client->keyboard, serial, surface->resource, &keys); + wl_array_release(&keys); + + wlr_seat_keyboard_send_modifiers(wlr_seat, + keyboard->modifiers.depressed, keyboard->modifiers.latched, + keyboard->modifiers.locked, keyboard->modifiers.group); wlr_seat_client_send_selection(client); }