From ee108f22da524ffd68130463c4fbdd861e545c45 Mon Sep 17 00:00:00 2001 From: Tsan-Kuang Lee Date: Sun, 5 Nov 2017 04:16:51 -0500 Subject: [PATCH] add the regretable timer feature --- i3lock.1 | 9 +++++++++ i3lock.c | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/i3lock.1 b/i3lock.1 index 55af52d..6477e29 100644 --- a/i3lock.1 +++ b/i3lock.1 @@ -18,6 +18,8 @@ i3lock \- improved screen locker .RB [\|\-v\|] .RB [\|\-n\|] .RB [\|\-b\|] +.RB [\|\-r +.IR timeout \|] .RB [\|\-i .IR image.png \|] .RB [\|\-c @@ -42,6 +44,8 @@ i3lock forks, so you can combine it with an alias to suspend to RAM (run "i3lock .IP \[bu] You can specify either a background color or a PNG image which will be displayed while your screen is locked. .IP \[bu] +You can cancel the lock by pressing any key within the first few seconds. +.IP \[bu] You can specify whether i3lock should bell upon a wrong password. .IP \[bu] i3lock uses PAM and therefore is compatible with LDAP, etc. @@ -62,6 +66,11 @@ Don't fork after starting. Enable beeping. Be sure to not do this when you are about to annoy other people, like when opening your laptop in a boring lecture. +.TP +.BI \-r\ timeout \fR,\ \fB\-\-regrettable= timeout +Specify the regrettable timer in seconds. Within this time period, any key press +will cancel the lock. + .TP .B \-u, \-\-no-unlock-indicator Disable the unlock indicator. i3lock will by default show an unlock indicator diff --git a/i3lock.c b/i3lock.c index 1bb7b0c..3f9aef0 100644 --- a/i3lock.c +++ b/i3lock.c @@ -68,7 +68,10 @@ bool debug_mode = false; bool unlock_indicator = true; char *modifier_string = NULL; static bool dont_fork = false; +bool regrettable = true; +int regrettable_timeout = 0; struct ev_loop *main_loop; +static struct ev_timer *regrettable_timer; static struct ev_timer *clear_auth_wrong_timeout; static struct ev_timer *clear_indicator_timeout; static struct ev_timer *discard_passwd_timeout; @@ -221,6 +224,18 @@ static void finish_input(void) { input_done(); } +/* + * Turn regrettable status off (called beyond regrettable_timeout) + * + */ +static void regrettable_off(EV_P_ ev_timer *w, int revents) { + regrettable = false; + + /* Now free this timeout. */ + STOP_TIMER(w); + DEBUG("regrettable off\n"); +} + /* * Resets auth_state to STATE_AUTH_IDLE 2 seconds after an unsuccessful * authentication event. @@ -387,6 +402,12 @@ static void handle_key_press(xcb_key_press_event_t *event) { bool ctrl; bool composed = false; + /* if a key is pressed within regrettable_timeout, then unlock */ + if (regrettable) { + ev_break(EV_DEFAULT, EVBREAK_ALL); + return; + } + ksym = xkb_state_key_get_one_sym(xkb_state, event->detail); ctrl = xkb_state_mod_name_is_active(xkb_state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_DEPRESSED); @@ -822,6 +843,7 @@ int main(int argc, char *argv[]) { {"version", no_argument, NULL, 'v'}, {"nofork", no_argument, NULL, 'n'}, {"beep", no_argument, NULL, 'b'}, + {"regrettable", required_argument, NULL, 'r'}, {"dpms", no_argument, NULL, 'd'}, {"color", required_argument, NULL, 'c'}, {"pointer", required_argument, NULL, 'p'}, @@ -840,7 +862,7 @@ int main(int argc, char *argv[]) { if ((username = pw->pw_name) == NULL) errx(EXIT_FAILURE, "pw->pw_name is NULL.\n"); - char *optstring = "hvnbdc:p:ui:teI:f"; + char *optstring = "hvnbr:dc:p:ui:teI:f"; while ((o = getopt_long(argc, argv, optstring, longopts, &longoptind)) != -1) { switch (o) { case 'v': @@ -851,6 +873,9 @@ int main(int argc, char *argv[]) { case 'b': beep = true; break; + case 'r': + regrettable_timeout = atoi(optarg); + break; case 'd': fprintf(stderr, "DPMS support has been removed from i3lock. Please see the manpage i3lock(1).\n"); break; @@ -899,7 +924,7 @@ int main(int argc, char *argv[]) { show_failed_attempts = true; break; default: - errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default]" + errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-r timeout] [-d] [-c color] [-u] [-p win|default]" " [-i image.png] [-t] [-e] [-I timeout] [-f]"); } } @@ -1064,6 +1089,10 @@ int main(int argc, char *argv[]) { if (main_loop == NULL) errx(EXIT_FAILURE, "Could not initialize libev. Bad LIBEV_FLAGS?\n"); + /* start the timer to expire the regrettable state */ + if (regrettable_timeout > 0) + START_TIMER(regrettable_timer, TSTAMP_N_SECS(regrettable_timeout), regrettable_off); + /* Explicitly call the screen redraw in case "locking…" message was displayed */ auth_state = STATE_AUTH_IDLE; redraw_screen();