summaryrefslogtreecommitdiff
path: root/i3lock.c
diff options
context:
space:
mode:
Diffstat (limited to 'i3lock.c')
-rw-r--r--i3lock.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/i3lock.c b/i3lock.c
index aee9b2a..3f8eb77 100644
--- a/i3lock.c
+++ b/i3lock.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * This file is part of i3lock-extended 2 * This file is part of i3lock-extended
3 * Copyright (C) 2020-2023 Simeon Simeonov 3 * Copyright (C) 2020-2024 Simeon Simeonov
4 4
5 * i3lock-extended is free software: you can redistribute it and/or modify 5 * i3lock-extended is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -130,6 +130,7 @@ extern unlock_state_t unlock_state;
130extern auth_state_t auth_state; 130extern auth_state_t auth_state;
131int failed_attempts = 0; 131int failed_attempts = 0;
132bool show_failed_attempts = false; 132bool show_failed_attempts = false;
133bool show_keyboard_layout = false;
133bool retry_verification = false; 134bool retry_verification = false;
134 135
135struct xkb_state *xkb_state; 136struct xkb_state *xkb_state;
@@ -162,6 +163,9 @@ static void u8_dec(char *s, int *i) {
162 * Necessary so that we can properly let xkbcommon track the keyboard state and 163 * Necessary so that we can properly let xkbcommon track the keyboard state and
163 * translate keypresses to utf-8. 164 * translate keypresses to utf-8.
164 * 165 *
166 * This function can be called when the user changes the XKB configuration,
167 * so it must not leave unusable global state behind
168 *
165 */ 169 */
166static bool load_keymap(void) { 170static bool load_keymap(void) {
167 if (xkb_context == NULL) { 171 if (xkb_context == NULL) {
@@ -171,25 +175,26 @@ static bool load_keymap(void) {
171 } 175 }
172 } 176 }
173 177
174 xkb_keymap_unref(xkb_keymap);
175
176 int32_t device_id = xkb_x11_get_core_keyboard_device_id(conn); 178 int32_t device_id = xkb_x11_get_core_keyboard_device_id(conn);
177 DEBUG("device = %d\n", device_id); 179 DEBUG("device = %d\n", device_id);
178 if ((xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, conn, device_id, 0)) == NULL) { 180 struct xkb_keymap *new_keymap = xkb_x11_keymap_new_from_device(xkb_context, conn, device_id, 0);
181 if (new_keymap == NULL) {
179 fprintf(stderr, "[i3lock] xkb_x11_keymap_new_from_device failed\n"); 182 fprintf(stderr, "[i3lock] xkb_x11_keymap_new_from_device failed\n");
180 return false; 183 return false;
181 } 184 }
182 185
183 struct xkb_state *new_state = 186 struct xkb_state *new_state =
184 xkb_x11_state_new_from_device(xkb_keymap, conn, device_id); 187 xkb_x11_state_new_from_device(new_keymap, conn, device_id);
185 if (new_state == NULL) { 188 if (new_state == NULL) {
186 fprintf(stderr, "[i3lock] xkb_x11_state_new_from_device failed\n"); 189 fprintf(stderr, "[i3lock] xkb_x11_state_new_from_device failed\n");
187 return false; 190 return false;
188 } 191 }
189 192
193 /* Only update global state on success */
190 xkb_state_unref(xkb_state); 194 xkb_state_unref(xkb_state);
195 xkb_keymap_unref(xkb_keymap);
191 xkb_state = new_state; 196 xkb_state = new_state;
192 197 xkb_keymap = new_keymap;
193 return true; 198 return true;
194} 199}
195 200
@@ -954,6 +959,7 @@ static void xcb_check_cb(EV_P_ ev_check *w, int revents) {
954 default: 959 default:
955 if (type == xkb_base_event) { 960 if (type == xkb_base_event) {
956 process_xkb_event(event); 961 process_xkb_event(event);
962 redraw_screen();
957 } 963 }
958 if (randr_base > -1 && 964 if (randr_base > -1 &&
959 type == randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY) { 965 type == randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
@@ -1079,6 +1085,7 @@ int main(int argc, char *argv[]) {
1079 {"ignore-empty-password", no_argument, NULL, 'e'}, 1085 {"ignore-empty-password", no_argument, NULL, 'e'},
1080 {"inactivity-timeout", required_argument, NULL, 'I'}, 1086 {"inactivity-timeout", required_argument, NULL, 'I'},
1081 {"show-failed-attempts", no_argument, NULL, 'f'}, 1087 {"show-failed-attempts", no_argument, NULL, 'f'},
1088 {"show-keyboard-layout", no_argument, NULL, 'k'},
1082 {NULL, no_argument, NULL, 0}}; 1089 {NULL, no_argument, NULL, 0}};
1083 1090
1084 if ((pw = getpwuid(getuid())) == NULL) 1091 if ((pw = getpwuid(getuid())) == NULL)
@@ -1089,14 +1096,14 @@ int main(int argc, char *argv[]) {
1089 errx(EXIT_FAILURE, "i3lock is a program for X11 and does not work on Wayland. Try https://github.com/swaywm/swaylock instead"); 1096 errx(EXIT_FAILURE, "i3lock is a program for X11 and does not work on Wayland. Try https://github.com/swaywm/swaylock instead");
1090 1097
1091#ifdef EXTRAS 1098#ifdef EXTRAS
1092 char *optstring = "hvnbDdELC:c:B:G:F:J:O:R:r:S:T:W:X:x:Y:y:Z:p:ui:teI:f"; 1099 char *optstring = "hvnbDdELC:c:B:G:F:J:O:R:r:S:T:W:X:x:Y:y:Z:p:ui:teI:fk";
1093#else 1100#else
1094 char *optstring = "hvnbdc:p:ui:teI:f"; 1101 char *optstring = "hvnbdc:p:ui:teI:fk";
1095#endif 1102#endif
1096 while ((o = getopt_long(argc, argv, optstring, longopts, &longoptind)) != -1) { 1103 while ((o = getopt_long(argc, argv, optstring, longopts, &longoptind)) != -1) {
1097 switch (o) { 1104 switch (o) {
1098 case 'v': 1105 case 'v':
1099 errx(EXIT_SUCCESS, "version " I3LOCK_VERSION " © 2010 Michael Stapelberg, 2020-2023 Simeon Simeonov"); 1106 errx(EXIT_SUCCESS, "version " I3LOCK_VERSION " © 2010 Michael Stapelberg, 2020-2024 Simeon Simeonov");
1100 case 'n': 1107 case 'n':
1101 dont_fork = true; 1108 dont_fork = true;
1102 break; 1109 break;
@@ -1333,12 +1340,15 @@ int main(int argc, char *argv[]) {
1333 case 'f': 1340 case 'f':
1334 show_failed_attempts = true; 1341 show_failed_attempts = true;
1335 break; 1342 break;
1343 case 'k':
1344 show_keyboard_layout = true;
1345 break;
1336 default: 1346 default:
1337#ifdef EXTRAS 1347#ifdef EXTRAS
1338 errx( 1348 errx(
1339 EXIT_FAILURE, 1349 EXIT_FAILURE,
1340 "Syntax: i3lock-extended [-B color] [-b] [-C seconds] " 1350 "Syntax: i3lock-extended [-B color] [-b] [-C seconds] "
1341 "[-c color] [-D] [-d] [-E] [-e] [-F color] [-f] " 1351 "[-c color] [-D] [-d] [-E] [-e] [-F color] [-f] [-k]"
1342 "[-G color] [-h] [-I timeout] [-i image.png] [-J text] " 1352 "[-G color] [-h] [-I timeout] [-i image.png] [-J text] "
1343 "[-L] [-n] [-O color] [-p win|default] [-R color] " 1353 "[-L] [-n] [-O color] [-p win|default] [-R color] "
1344 "[-r refresh rate] [-S size] [-T template] [-t] [-u] [-v] " 1354 "[-r refresh rate] [-S size] [-T template] [-t] [-u] [-v] "
@@ -1347,7 +1357,7 @@ int main(int argc, char *argv[]) {
1347 "[-y vertical-alignment] [-Z vertical-alignment]"); 1357 "[-y vertical-alignment] [-Z vertical-alignment]");
1348#else 1358#else
1349 errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default]" 1359 errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default]"
1350 " [-i image.png] [-t] [-e] [-I timeout] [-f]"); 1360 " [-i image.png] [-t] [-e] [-I timeout] [-f] [-k]");
1351#endif 1361#endif
1352 } 1362 }
1353 } 1363 }