@@ -1663,6 +1663,11 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
16631663 }
16641664
16651665 WAYLAND_xkb_keymap_key_for_each (seat -> keyboard .xkb .keymap , Wayland_KeymapIterator , seat );
1666+
1667+ // Restore any previously set modifier/layout information, if valid.
1668+ WAYLAND_xkb_state_update_mask (seat -> keyboard .xkb .state ,
1669+ seat -> keyboard .xkb .wl_pressed_modifiers , seat -> keyboard .xkb .wl_latched_modifiers , seat -> keyboard .xkb .wl_locked_modifiers ,
1670+ 0 , 0 , seat -> keyboard .xkb .current_layout < seat -> keyboard .xkb .num_layouts ? seat -> keyboard .xkb .current_layout : 0 );
16661671 Wayland_SeatSetKeymap (seat );
16671672 }
16681673
@@ -1806,7 +1811,9 @@ static void Wayland_ReconcileModifiers(SDL_WaylandSeat *seat, bool key_pressed)
18061811 * The modifier will remain active until the latch/lock is released by
18071812 * the system.
18081813 */
1809- if (seat -> keyboard .xkb .wl_locked_modifiers & seat -> keyboard .xkb .shift_mask ) {
1814+ const xkb_mod_mask_t xkb_locked_modifiers = seat -> keyboard .xkb .wl_latched_modifiers | seat -> keyboard .xkb .wl_locked_modifiers ;
1815+
1816+ if (xkb_locked_modifiers & seat -> keyboard .xkb .shift_mask ) {
18101817 if (seat -> keyboard .pressed_modifiers & SDL_KMOD_SHIFT ) {
18111818 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_SHIFT ;
18121819 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)
18171824 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_SHIFT ;
18181825 }
18191826
1820- if (seat -> keyboard . xkb . wl_locked_modifiers & seat -> keyboard .xkb .ctrl_mask ) {
1827+ if (xkb_locked_modifiers & seat -> keyboard .xkb .ctrl_mask ) {
18211828 if (seat -> keyboard .pressed_modifiers & SDL_KMOD_CTRL ) {
18221829 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_CTRL ;
18231830 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)
18281835 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_CTRL ;
18291836 }
18301837
1831- if (seat -> keyboard . xkb . wl_locked_modifiers & seat -> keyboard .xkb .alt_mask ) {
1838+ if (xkb_locked_modifiers & seat -> keyboard .xkb .alt_mask ) {
18321839 if (seat -> keyboard .pressed_modifiers & SDL_KMOD_ALT ) {
18331840 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_ALT ;
18341841 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)
18391846 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_ALT ;
18401847 }
18411848
1842- if (seat -> keyboard . xkb . wl_locked_modifiers & seat -> keyboard .xkb .gui_mask ) {
1849+ if (xkb_locked_modifiers & seat -> keyboard .xkb .gui_mask ) {
18431850 if (seat -> keyboard .pressed_modifiers & SDL_KMOD_GUI ) {
18441851 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_GUI ;
18451852 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)
18501857 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_GUI ;
18511858 }
18521859
1853- if (seat -> keyboard . xkb . wl_locked_modifiers & seat -> keyboard .xkb .level3_mask ) {
1860+ if (xkb_locked_modifiers & seat -> keyboard .xkb .level3_mask ) {
18541861 seat -> keyboard .locked_modifiers |= SDL_KMOD_MODE ;
18551862 } else {
18561863 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_MODE ;
18571864 }
18581865
1859- if (seat -> keyboard . xkb . wl_locked_modifiers & seat -> keyboard .xkb .level5_mask ) {
1866+ if (xkb_locked_modifiers & seat -> keyboard .xkb .level5_mask ) {
18601867 seat -> keyboard .locked_modifiers |= SDL_KMOD_LEVEL5 ;
18611868 } else {
18621869 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_LEVEL5 ;
18631870 }
18641871
18651872 // Capslock and Numlock can only be locked, not pressed.
1866- if (seat -> keyboard . xkb . wl_locked_modifiers & seat -> keyboard .xkb .caps_mask ) {
1873+ if (xkb_locked_modifiers & seat -> keyboard .xkb .caps_mask ) {
18671874 seat -> keyboard .locked_modifiers |= SDL_KMOD_CAPS ;
18681875 } else {
18691876 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_CAPS ;
18701877 }
18711878
1872- if (seat -> keyboard . xkb . wl_locked_modifiers & seat -> keyboard .xkb .num_mask ) {
1879+ if (xkb_locked_modifiers & seat -> keyboard .xkb .num_mask ) {
18731880 seat -> keyboard .locked_modifiers |= SDL_KMOD_NUM ;
18741881 } else {
18751882 seat -> keyboard .locked_modifiers &= ~SDL_KMOD_NUM ;
@@ -2195,21 +2202,24 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
21952202 uint32_t group )
21962203{
21972204 SDL_WaylandSeat * seat = data ;
2198-
2199- if (seat -> keyboard .xkb .state == NULL ) {
2200- /* if we get a modifier notification before the keymap, there's nothing we can do with the information
2201- */
2202- return ;
2203- }
2204-
2205- WAYLAND_xkb_state_update_mask (seat -> keyboard .xkb .state , mods_depressed , mods_latched ,
2206- mods_locked , 0 , 0 , group );
2205+ const uint32_t previous_layout = seat -> keyboard .xkb .current_layout ;
22072206
22082207 seat -> keyboard .xkb .wl_pressed_modifiers = mods_depressed ;
2209- seat -> keyboard .xkb .wl_locked_modifiers = mods_latched | mods_locked ;
2208+ seat -> keyboard .xkb .wl_latched_modifiers = mods_latched ;
2209+ seat -> keyboard .xkb .wl_locked_modifiers = mods_locked ;
2210+ seat -> keyboard .xkb .current_layout = group ;
22102211
22112212 Wayland_ReconcileModifiers (seat , false);
22122213
2214+ // If we get a modifier notification before the keymap, there's no further state to update yet.
2215+ if (!seat -> keyboard .xkb .state ) {
2216+ return ;
2217+ }
2218+
2219+ WAYLAND_xkb_state_update_mask (seat -> keyboard .xkb .state ,
2220+ mods_depressed , mods_latched , mods_locked ,
2221+ 0 , 0 , group );
2222+
22132223 // If a key is repeating, update the text to apply the modifier.
22142224 if (keyboard_repeat_is_set (& seat -> keyboard .repeat )) {
22152225 char text [8 ];
@@ -2220,8 +2230,7 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
22202230 }
22212231 }
22222232
2223- if (group != seat -> keyboard .xkb .current_layout ) {
2224- seat -> keyboard .xkb .current_layout = group ;
2233+ if (group != previous_layout ) {
22252234 Wayland_SeatSetKeymap (seat );
22262235
22272236 if (seat -> keyboard .xkb .compose_state ) {
0 commit comments