Skip to content

Commit a7ebe81

Browse files
authored
load_keymap: handle error without corrupting global state (#353)
fixes #351
1 parent d8e853e commit a7ebe81

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

i3lock.c

+9-5
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ static void u8_dec(char *s, int *i) {
114114
* Necessary so that we can properly let xkbcommon track the keyboard state and
115115
* translate keypresses to utf-8.
116116
*
117+
* This function can be called when the user changes the XKB configuration,
118+
* so it must not leave unusable global state behind
119+
*
117120
*/
118121
static bool load_keymap(void) {
119122
if (xkb_context == NULL) {
@@ -123,25 +126,26 @@ static bool load_keymap(void) {
123126
}
124127
}
125128

126-
xkb_keymap_unref(xkb_keymap);
127-
128129
int32_t device_id = xkb_x11_get_core_keyboard_device_id(conn);
129130
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) {
131133
fprintf(stderr, "[i3lock] xkb_x11_keymap_new_from_device failed\n");
132134
return false;
133135
}
134136

135137
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);
137139
if (new_state == NULL) {
138140
fprintf(stderr, "[i3lock] xkb_x11_state_new_from_device failed\n");
139141
return false;
140142
}
141143

144+
/* Only update global state on success */
142145
xkb_state_unref(xkb_state);
146+
xkb_keymap_unref(xkb_keymap);
143147
xkb_state = new_state;
144-
148+
xkb_keymap = new_keymap;
145149
return true;
146150
}
147151

0 commit comments

Comments
 (0)