diff options
-rw-r--r-- | include/wlr/types/wlr_keyboard.h | 14 | ||||
-rw-r--r-- | include/wlr/types/wlr_seat.h | 14 | ||||
-rw-r--r-- | rootston/keyboard.c | 3 | ||||
-rw-r--r-- | types/wlr_data_device.c | 3 | ||||
-rw-r--r-- | types/wlr_keyboard.c | 89 | ||||
-rw-r--r-- | types/wlr_seat.c | 29 | ||||
-rw-r--r-- | types/wlr_xdg_shell_v6.c | 5 |
7 files changed, 105 insertions, 52 deletions
diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index d32d6e96..b37797c8 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -32,6 +32,13 @@ enum wlr_keyboard_modifier { struct wlr_keyboard_impl; +struct wlr_keyboard_modifiers { + xkb_mod_mask_t depressed; + xkb_mod_mask_t latched; + xkb_mod_mask_t locked; + xkb_mod_mask_t group; +}; + struct wlr_keyboard { struct wlr_keyboard_impl *impl; // TODO: Should this store key repeat info too? @@ -45,12 +52,7 @@ struct wlr_keyboard { uint32_t keycodes[WLR_KEYBOARD_KEYS_CAP]; size_t num_keycodes; - struct { - xkb_mod_mask_t depressed; - xkb_mod_mask_t latched; - xkb_mod_mask_t locked; - xkb_mod_mask_t group; - } modifiers; + struct wlr_keyboard_modifiers *modifiers; struct { int32_t rate; diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 432e5dc3..f5b4afde 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -71,7 +71,8 @@ struct wlr_keyboard_grab_interface { struct wlr_surface *surface); void (*key)(struct wlr_seat_keyboard_grab *grab, uint32_t time, uint32_t key, uint32_t state); - void (*modifiers)(struct wlr_seat_keyboard_grab *grab); + void (*modifiers)(struct wlr_seat_keyboard_grab *grab, + struct wlr_keyboard_modifiers *modifiers); void (*cancel)(struct wlr_seat_keyboard_grab *grab); }; @@ -345,6 +346,11 @@ bool wlr_seat_pointer_has_grab(struct wlr_seat *seat); void wlr_seat_set_keyboard(struct wlr_seat *seat, struct wlr_input_device *dev); /** + * Get the active keyboard for the seat. + */ +struct wlr_keyboard *wlr_seat_get_keyboard(struct wlr_seat *seat); + +/** * Start a grab of the keyboard of this seat. The grabber is responsible for * handling all keyboard events until the grab ends. */ @@ -375,13 +381,15 @@ void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time, * Send the modifier state to focused keyboard resources. Compositors should use * `wlr_seat_keyboard_notify_modifiers()` to respect any keyboard grabs. */ -void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat); +void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat, + struct wlr_keyboard_modifiers *modifiers); /** * Notify the seat that the modifiers for the keyboard have changed. Defers to * any keyboard grabs. */ -void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat); +void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat, + struct wlr_keyboard_modifiers *modifiers); /** * Notify the seat that the keyboard focus has changed and request it to be the diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 7b281308..29409dd7 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -279,7 +279,8 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard, void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { struct wlr_seat *seat = r_keyboard->seat->seat; wlr_seat_set_keyboard(seat, r_keyboard->device); - wlr_seat_keyboard_notify_modifiers(seat); + wlr_seat_keyboard_notify_modifiers(seat, + r_keyboard->device->keyboard->modifiers); } static void keyboard_config_merge(struct roots_keyboard_config *config, diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index a4eb233b..3c48119a 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -594,7 +594,8 @@ static void keyboard_drag_key(struct wlr_seat_keyboard_grab *grab, // no keyboard input during drags } -static void keyboard_drag_modifiers(struct wlr_seat_keyboard_grab *grab) { +static void keyboard_drag_modifiers(struct wlr_seat_keyboard_grab *grab, + struct wlr_keyboard_modifiers *modifiers) { //struct wlr_keyboard *keyboard = grab->seat->keyboard_state.keyboard; // TODO change the dnd action based on what modifier is pressed on the // keyboard diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 6caf27f5..5a90e6b2 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -11,6 +11,10 @@ int os_create_anonymous_file(off_t size); static void keyboard_led_update(struct wlr_keyboard *keyboard) { + if (keyboard->xkb_state == NULL) { + return; + } + uint32_t leds = 0; for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) { if (xkb_state_led_index_is_active(keyboard->xkb_state, @@ -21,7 +25,15 @@ static void keyboard_led_update(struct wlr_keyboard *keyboard) { wlr_keyboard_led_update(keyboard, leds); } -static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { +/** + * Update the modifier state of the wlr-keyboard. Returns true if the modifier + * state changed. + */ +static bool keyboard_modifier_update(struct wlr_keyboard *keyboard) { + if (keyboard->xkb_state == NULL) { + return false; + } + xkb_mod_mask_t depressed = xkb_state_serialize_mods(keyboard->xkb_state, XKB_STATE_MODS_DEPRESSED); xkb_mod_mask_t latched = xkb_state_serialize_mods(keyboard->xkb_state, @@ -30,19 +42,19 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { XKB_STATE_MODS_LOCKED); xkb_mod_mask_t group = xkb_state_serialize_layout(keyboard->xkb_state, XKB_STATE_LAYOUT_EFFECTIVE); - if (depressed == keyboard->modifiers.depressed && - latched == keyboard->modifiers.latched && - locked == keyboard->modifiers.locked && - group == keyboard->modifiers.group) { - return; + if (depressed == keyboard->modifiers->depressed && + latched == keyboard->modifiers->latched && + locked == keyboard->modifiers->locked && + group == keyboard->modifiers->group) { + return false; } - keyboard->modifiers.depressed = depressed; - keyboard->modifiers.latched = latched; - keyboard->modifiers.locked = locked; - keyboard->modifiers.group = group; + keyboard->modifiers->depressed = depressed; + keyboard->modifiers->latched = latched; + keyboard->modifiers->locked = locked; + keyboard->modifiers->group = group; - wl_signal_emit(&keyboard->events.modifiers, keyboard); + return true; } // https://www.geeksforgeeks.org/move-zeroes-end-array/ @@ -90,17 +102,21 @@ static void keyboard_key_update(struct wlr_keyboard *keyboard, void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { - if (!keyboard->xkb_state) { + if (keyboard->xkb_state == NULL) { return; } xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group); - keyboard_modifier_update(keyboard); + + bool updated = keyboard_modifier_update(keyboard); + if (updated) { + wl_signal_emit(&keyboard->events.modifiers, keyboard); + } } void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event) { - if (!keyboard->xkb_state) { + if (keyboard->xkb_state == NULL) { return; } if (event->update_state) { @@ -109,7 +125,12 @@ void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, event->state == WLR_KEY_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); } keyboard_led_update(keyboard); - keyboard_modifier_update(keyboard); + + bool updated = keyboard_modifier_update(keyboard); + if (updated) { + wl_signal_emit(&keyboard->events.modifiers, keyboard); + } + keyboard_key_update(keyboard, event); wl_signal_emit(&keyboard->events.key, event); } @@ -117,6 +138,7 @@ void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, void wlr_keyboard_init(struct wlr_keyboard *kb, struct wlr_keyboard_impl *impl) { kb->impl = impl; + kb->modifiers = calloc(1, sizeof(struct wlr_keyboard_modifiers)); wl_signal_init(&kb->events.key); wl_signal_init(&kb->events.modifiers); wl_signal_init(&kb->events.keymap); @@ -139,6 +161,7 @@ void wlr_keyboard_destroy(struct wlr_keyboard *kb) { xkb_state_unref(kb->xkb_state); xkb_keymap_unref(kb->keymap); close(kb->keymap_fd); + free(kb->modifiers); free(kb); } @@ -150,20 +173,16 @@ void wlr_keyboard_led_update(struct wlr_keyboard *kb, uint32_t leds) { void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap) { - if (kb->keymap) { - xkb_keymap_unref(kb->keymap); - } - xkb_keymap_ref(keymap); - kb->keymap = keymap; + char *keymap_str = NULL; - if (kb->xkb_state) { - xkb_state_unref(kb->xkb_state); - } + xkb_keymap_unref(kb->keymap); + kb->keymap = xkb_keymap_ref(keymap); + xkb_state_unref(kb->xkb_state); kb->xkb_state = xkb_state_new(kb->keymap); if (kb->xkb_state == NULL) { wlr_log(L_ERROR, "Failed to create XKB state"); - return; + goto err; } const char *led_names[WLR_LED_COUNT] = { @@ -190,7 +209,7 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, kb->mod_indexes[i] = xkb_map_mod_get_index(kb->keymap, mod_names[i]); } - char *keymap_str = xkb_keymap_get_as_string(kb->keymap, + keymap_str = xkb_keymap_get_as_string(kb->keymap, XKB_KEYMAP_FORMAT_TEXT_V1); kb->keymap_size = strlen(keymap_str) + 1; if (kb->keymap_fd) { @@ -199,16 +218,34 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, kb->keymap_fd = os_create_anonymous_file(kb->keymap_size); if (kb->keymap_fd < 0) { wlr_log(L_ERROR, "creating a keymap file for %lu bytes failed", kb->keymap_size); + goto err; } void *ptr = mmap(NULL, kb->keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, kb->keymap_fd, 0); if (ptr == (void*)-1) { wlr_log(L_ERROR, "failed to mmap() %lu bytes", kb->keymap_size); + goto err; } strcpy(ptr, keymap_str); free(keymap_str); + for (size_t i = 0; i < kb->num_keycodes; ++i) { + xkb_keycode_t keycode = kb->keycodes[i] + 8; + xkb_state_update_key(kb->xkb_state, keycode, XKB_KEY_DOWN); + } + + keyboard_modifier_update(kb); + wl_signal_emit(&kb->events.keymap, kb); + return; + +err: + xkb_state_unref(kb->xkb_state); + kb->xkb_state = NULL; + xkb_keymap_unref(keymap); + kb->keymap = NULL; + close(kb->keymap_fd); + free(keymap_str); } void wlr_keyboard_set_repeat_info(struct wlr_keyboard *kb, int32_t rate, @@ -222,7 +259,7 @@ void wlr_keyboard_set_repeat_info(struct wlr_keyboard *kb, int32_t rate, } uint32_t wlr_keyboard_get_modifiers(struct wlr_keyboard *kb) { - xkb_mod_mask_t mask = kb->modifiers.depressed | kb->modifiers.latched; + xkb_mod_mask_t mask = kb->modifiers->depressed | kb->modifiers->latched; uint32_t modifiers = 0; for (size_t i = 0; i < WLR_MODIFIER_COUNT; ++i) { if (kb->mod_indexes[i] != XKB_MOD_INVALID && diff --git a/types/wlr_seat.c b/types/wlr_seat.c index fd76775d..91a7a681 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -291,8 +291,9 @@ static void default_keyboard_key(struct wlr_seat_keyboard_grab *grab, wlr_seat_keyboard_send_key(grab->seat, time, key, state); } -static void default_keyboard_modifiers(struct wlr_seat_keyboard_grab *grab) { - wlr_seat_keyboard_send_modifiers(grab->seat); +static void default_keyboard_modifiers(struct wlr_seat_keyboard_grab *grab, + struct wlr_keyboard_modifiers *modifiers) { + wlr_seat_keyboard_send_modifiers(grab->seat, modifiers); } static void default_keyboard_cancel(struct wlr_seat_keyboard_grab *grab) { @@ -797,6 +798,10 @@ void wlr_seat_set_keyboard(struct wlr_seat *seat, wlr_seat_keyboard_send_modifiers(seat); } +struct wlr_keyboard *wlr_seat_get_keyboard(struct wlr_seat *seat) { + return seat->keyboard_state.keyboard; +} + void wlr_seat_keyboard_start_grab(struct wlr_seat *wlr_seat, struct wlr_seat_keyboard_grab *grab) { grab->seat = wlr_seat; @@ -835,23 +840,19 @@ static void keyboard_resource_destroy_notify(struct wl_listener *listener, wlr_seat_keyboard_clear_focus(state->seat); } -void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat) { +void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat, + struct wlr_keyboard_modifiers *modifiers) { struct wlr_seat_client *client = seat->keyboard_state.focused_client; if (client == NULL) { return; } - struct wlr_keyboard *keyboard = seat->keyboard_state.keyboard; - if (keyboard == NULL) { - return; - } - uint32_t serial = wl_display_next_serial(seat->display); struct wl_resource *resource; wl_resource_for_each(resource, &client->keyboards) { wl_keyboard_send_modifiers(resource, serial, - keyboard->modifiers.depressed, keyboard->modifiers.latched, - keyboard->modifiers.locked, keyboard->modifiers.group); + modifiers->depressed, modifiers->latched, + modifiers->locked, modifiers->group); } } @@ -931,7 +932,8 @@ void wlr_seat_keyboard_enter(struct wlr_seat *seat, if (client != NULL && seat->keyboard_state.keyboard != NULL) { // tell new client about any modifier change last, // as it targets seat->keyboard_state.focused_client - wlr_seat_keyboard_send_modifiers(seat); + wlr_seat_keyboard_send_modifiers(seat, + seat->keyboard_state.keyboard->modifiers); } } @@ -951,10 +953,11 @@ bool wlr_seat_keyboard_has_grab(struct wlr_seat *seat) { return seat->keyboard_state.grab->interface != &default_keyboard_grab_impl; } -void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat) { +void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat, + struct wlr_keyboard_modifiers *modifiers) { clock_gettime(CLOCK_MONOTONIC, &seat->last_event); struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; - grab->interface->modifiers(grab); + grab->interface->modifiers(grab, modifiers); } void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time, diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 1c46197e..fd09b467 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -112,8 +112,9 @@ static void xdg_keyboard_grab_key(struct wlr_seat_keyboard_grab *grab, uint32_t wlr_seat_keyboard_send_key(grab->seat, time, key, state); } -static void xdg_keyboard_grab_modifiers(struct wlr_seat_keyboard_grab *grab) { - wlr_seat_keyboard_send_modifiers(grab->seat); +static void xdg_keyboard_grab_modifiers(struct wlr_seat_keyboard_grab *grab, + struct wlr_keyboard_modifiers *modifiers) { + wlr_seat_keyboard_send_modifiers(grab->seat, modifiers); } static void xdg_keyboard_grab_cancel(struct wlr_seat_keyboard_grab *grab) { |