|
@@ -1663,6 +1663,11 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
|
|
}
|
|
|
|
|
|
WAYLAND_xkb_keymap_key_for_each(seat->keyboard.xkb.keymap, Wayland_KeymapIterator, seat);
|
|
|
+
|
|
|
+ // Restore any previously set modifier/layout information, if valid.
|
|
|
+ WAYLAND_xkb_state_update_mask(seat->keyboard.xkb.state,
|
|
|
+ seat->keyboard.xkb.wl_pressed_modifiers, seat->keyboard.xkb.wl_latched_modifiers, seat->keyboard.xkb.wl_locked_modifiers,
|
|
|
+ 0, 0, seat->keyboard.xkb.current_layout < seat->keyboard.xkb.num_layouts ? seat->keyboard.xkb.current_layout : 0);
|
|
|
Wayland_SeatSetKeymap(seat);
|
|
|
}
|
|
|
|
|
@@ -1806,7 +1811,9 @@ static void Wayland_ReconcileModifiers(SDL_WaylandSeat *seat, bool key_pressed)
|
|
|
* The modifier will remain active until the latch/lock is released by
|
|
|
* the system.
|
|
|
*/
|
|
|
- if (seat->keyboard.xkb.wl_locked_modifiers & seat->keyboard.xkb.shift_mask) {
|
|
|
+ const xkb_mod_mask_t xkb_locked_modifiers = seat->keyboard.xkb.wl_latched_modifiers | seat->keyboard.xkb.wl_locked_modifiers;
|
|
|
+
|
|
|
+ if (xkb_locked_modifiers & seat->keyboard.xkb.shift_mask) {
|
|
|
if (seat->keyboard.pressed_modifiers & SDL_KMOD_SHIFT) {
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_SHIFT;
|
|
|
seat->keyboard.locked_modifiers |= (seat->keyboard.pressed_modifiers & SDL_KMOD_SHIFT);
|
|
@@ -1817,7 +1824,7 @@ static void Wayland_ReconcileModifiers(SDL_WaylandSeat *seat, bool key_pressed)
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_SHIFT;
|
|
|
}
|
|
|
|
|
|
- if (seat->keyboard.xkb.wl_locked_modifiers & seat->keyboard.xkb.ctrl_mask) {
|
|
|
+ if (xkb_locked_modifiers & seat->keyboard.xkb.ctrl_mask) {
|
|
|
if (seat->keyboard.pressed_modifiers & SDL_KMOD_CTRL) {
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_CTRL;
|
|
|
seat->keyboard.locked_modifiers |= (seat->keyboard.pressed_modifiers & SDL_KMOD_CTRL);
|
|
@@ -1828,7 +1835,7 @@ static void Wayland_ReconcileModifiers(SDL_WaylandSeat *seat, bool key_pressed)
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_CTRL;
|
|
|
}
|
|
|
|
|
|
- if (seat->keyboard.xkb.wl_locked_modifiers & seat->keyboard.xkb.alt_mask) {
|
|
|
+ if (xkb_locked_modifiers & seat->keyboard.xkb.alt_mask) {
|
|
|
if (seat->keyboard.pressed_modifiers & SDL_KMOD_ALT) {
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_ALT;
|
|
|
seat->keyboard.locked_modifiers |= (seat->keyboard.pressed_modifiers & SDL_KMOD_ALT);
|
|
@@ -1839,7 +1846,7 @@ static void Wayland_ReconcileModifiers(SDL_WaylandSeat *seat, bool key_pressed)
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_ALT;
|
|
|
}
|
|
|
|
|
|
- if (seat->keyboard.xkb.wl_locked_modifiers & seat->keyboard.xkb.gui_mask) {
|
|
|
+ if (xkb_locked_modifiers & seat->keyboard.xkb.gui_mask) {
|
|
|
if (seat->keyboard.pressed_modifiers & SDL_KMOD_GUI) {
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_GUI;
|
|
|
seat->keyboard.locked_modifiers |= (seat->keyboard.pressed_modifiers & SDL_KMOD_GUI);
|
|
@@ -1850,26 +1857,26 @@ static void Wayland_ReconcileModifiers(SDL_WaylandSeat *seat, bool key_pressed)
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_GUI;
|
|
|
}
|
|
|
|
|
|
- if (seat->keyboard.xkb.wl_locked_modifiers & seat->keyboard.xkb.level3_mask) {
|
|
|
+ if (xkb_locked_modifiers & seat->keyboard.xkb.level3_mask) {
|
|
|
seat->keyboard.locked_modifiers |= SDL_KMOD_MODE;
|
|
|
} else {
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_MODE;
|
|
|
}
|
|
|
|
|
|
- if (seat->keyboard.xkb.wl_locked_modifiers & seat->keyboard.xkb.level5_mask) {
|
|
|
+ if (xkb_locked_modifiers & seat->keyboard.xkb.level5_mask) {
|
|
|
seat->keyboard.locked_modifiers |= SDL_KMOD_LEVEL5;
|
|
|
} else {
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_LEVEL5;
|
|
|
}
|
|
|
|
|
|
// Capslock and Numlock can only be locked, not pressed.
|
|
|
- if (seat->keyboard.xkb.wl_locked_modifiers & seat->keyboard.xkb.caps_mask) {
|
|
|
+ if (xkb_locked_modifiers & seat->keyboard.xkb.caps_mask) {
|
|
|
seat->keyboard.locked_modifiers |= SDL_KMOD_CAPS;
|
|
|
} else {
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_CAPS;
|
|
|
}
|
|
|
|
|
|
- if (seat->keyboard.xkb.wl_locked_modifiers & seat->keyboard.xkb.num_mask) {
|
|
|
+ if (xkb_locked_modifiers & seat->keyboard.xkb.num_mask) {
|
|
|
seat->keyboard.locked_modifiers |= SDL_KMOD_NUM;
|
|
|
} else {
|
|
|
seat->keyboard.locked_modifiers &= ~SDL_KMOD_NUM;
|
|
@@ -2195,21 +2202,24 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
|
|
|
uint32_t group)
|
|
|
{
|
|
|
SDL_WaylandSeat *seat = data;
|
|
|
-
|
|
|
- if (seat->keyboard.xkb.state == NULL) {
|
|
|
- /* if we get a modifier notification before the keymap, there's nothing we can do with the information
|
|
|
- */
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- WAYLAND_xkb_state_update_mask(seat->keyboard.xkb.state, mods_depressed, mods_latched,
|
|
|
- mods_locked, 0, 0, group);
|
|
|
+ const uint32_t previous_layout = seat->keyboard.xkb.current_layout;
|
|
|
|
|
|
seat->keyboard.xkb.wl_pressed_modifiers = mods_depressed;
|
|
|
- seat->keyboard.xkb.wl_locked_modifiers = mods_latched | mods_locked;
|
|
|
+ seat->keyboard.xkb.wl_latched_modifiers = mods_latched;
|
|
|
+ seat->keyboard.xkb.wl_locked_modifiers = mods_locked;
|
|
|
+ seat->keyboard.xkb.current_layout = group;
|
|
|
|
|
|
Wayland_ReconcileModifiers(seat, false);
|
|
|
|
|
|
+ // If we get a modifier notification before the keymap, there's no further state to update yet.
|
|
|
+ if (!seat->keyboard.xkb.state) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ WAYLAND_xkb_state_update_mask(seat->keyboard.xkb.state,
|
|
|
+ mods_depressed, mods_latched, mods_locked,
|
|
|
+ 0, 0, group);
|
|
|
+
|
|
|
// If a key is repeating, update the text to apply the modifier.
|
|
|
if (keyboard_repeat_is_set(&seat->keyboard.repeat)) {
|
|
|
char text[8];
|
|
@@ -2220,8 +2230,7 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (group != seat->keyboard.xkb.current_layout) {
|
|
|
- seat->keyboard.xkb.current_layout = group;
|
|
|
+ if (group != previous_layout) {
|
|
|
Wayland_SeatSetKeymap(seat);
|
|
|
|
|
|
if (seat->keyboard.xkb.compose_state) {
|