aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_keyboard.h14
-rw-r--r--include/wlr/types/wlr_seat.h14
-rw-r--r--rootston/keyboard.c3
-rw-r--r--types/wlr_data_device.c3
-rw-r--r--types/wlr_keyboard.c89
-rw-r--r--types/wlr_seat.c29
-rw-r--r--types/wlr_xdg_shell_v6.c5
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) {