Skip to content

Commit

Permalink
Fixed behavior when user unlocks too early
Browse files Browse the repository at this point in the history
If user has entered a correct password and pressed enter before the
initialization has completed, i3lock used to verify the password but not
exit correctly, which was easy to encounter with a high sigma value for blurring.

I wonder if there is a more elegant implementation...
  • Loading branch information
kolayne committed May 20, 2023
1 parent 2894697 commit eb326b9
Showing 1 changed file with 23 additions and 11 deletions.
34 changes: 23 additions & 11 deletions i3lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ int failed_attempts = 0;
bool show_failed_attempts = false;
bool retry_verification = false;

/* Set to true by `input_done` when the password is correct.
* Needed if user has entered password before intialization completed. */
bool unlocked = false;

static struct xkb_state *xkb_state;
static struct xkb_context *xkb_context;
static struct xkb_keymap *xkb_keymap;
Expand Down Expand Up @@ -564,6 +568,7 @@ static void input_done(void) {

if (no_verify) {
ev_break(EV_DEFAULT, EVBREAK_ALL);
unlocked = true;
return;
}

Expand All @@ -578,6 +583,7 @@ static void input_done(void) {
clear_password_memory();

ev_break(EV_DEFAULT, EVBREAK_ALL);
unlocked = true;
return;
}
#else
Expand All @@ -593,6 +599,7 @@ static void input_done(void) {
pam_cleanup = true;

ev_break(EV_DEFAULT, EVBREAK_ALL);
unlocked = true;
return;
}
#endif
Expand Down Expand Up @@ -2635,19 +2642,24 @@ int main(int argc, char *argv[]) {
* file descriptor becomes readable). */
ev_invoke(main_loop, xcb_check, 0);

if (show_clock || bar_enabled || slideshow_enabled) {
if (redraw_thread) {
struct timespec ts;
double s;
double ns = modf(refresh_rate, &s);
ts.tv_sec = (time_t) s;
ts.tv_nsec = ns * NANOSECONDS_IN_SECOND;
(void) pthread_create(&draw_thread, NULL, start_time_redraw_tick_pthread, (void*) &ts);
} else {
start_time_redraw_tick(main_loop);
/* If the user was fast enough to have typed their password (and pressed Enter) before
* i3lock has finished intializing, all of that is processed in the above `ev_invoke`.
* If the password was correct (`unlocked` is true), we should not enter the event loop. */
if (!unlocked) {
if (show_clock || bar_enabled || slideshow_enabled) {
if (redraw_thread) {
struct timespec ts;
double s;
double ns = modf(refresh_rate, &s);
ts.tv_sec = (time_t) s;
ts.tv_nsec = ns * NANOSECONDS_IN_SECOND;
(void) pthread_create(&draw_thread, NULL, start_time_redraw_tick_pthread, (void*) &ts);
} else {
start_time_redraw_tick(main_loop);
}
}
ev_loop(main_loop, 0);
}
ev_loop(main_loop, 0);

#ifndef __OpenBSD__
if (pam_cleanup) {
Expand Down

0 comments on commit eb326b9

Please sign in to comment.