@@ -114,6 +114,9 @@ static void u8_dec(char *s, int *i) {
114
114
* Necessary so that we can properly let xkbcommon track the keyboard state and
115
115
* translate keypresses to utf-8.
116
116
*
117
+ * This function can be called when the user changes the XKB configuration,
118
+ * so it must not leave unusable global state behind
119
+ *
117
120
*/
118
121
static bool load_keymap (void ) {
119
122
if (xkb_context == NULL ) {
@@ -123,25 +126,26 @@ static bool load_keymap(void) {
123
126
}
124
127
}
125
128
126
- xkb_keymap_unref (xkb_keymap );
127
-
128
129
int32_t device_id = xkb_x11_get_core_keyboard_device_id (conn );
129
130
DEBUG ("device = %d\n" , device_id );
130
- if ((xkb_keymap = xkb_x11_keymap_new_from_device (xkb_context , conn , device_id , 0 )) == NULL ) {
131
+ struct xkb_keymap * new_keymap = xkb_x11_keymap_new_from_device (xkb_context , conn , device_id , 0 );
132
+ if (new_keymap == NULL ) {
131
133
fprintf (stderr , "[i3lock] xkb_x11_keymap_new_from_device failed\n" );
132
134
return false;
133
135
}
134
136
135
137
struct xkb_state * new_state =
136
- xkb_x11_state_new_from_device (xkb_keymap , conn , device_id );
138
+ xkb_x11_state_new_from_device (new_keymap , conn , device_id );
137
139
if (new_state == NULL ) {
138
140
fprintf (stderr , "[i3lock] xkb_x11_state_new_from_device failed\n" );
139
141
return false;
140
142
}
141
143
144
+ /* Only update global state on success */
142
145
xkb_state_unref (xkb_state );
146
+ xkb_keymap_unref (xkb_keymap );
143
147
xkb_state = new_state ;
144
-
148
+ xkb_keymap = new_keymap ;
145
149
return true;
146
150
}
147
151
0 commit comments