diff --git a/include/swaylock/seat.h b/include/swaylock/seat.h index 44bc37d5..180ea7a0 100644 --- a/include/swaylock/seat.h +++ b/include/swaylock/seat.h @@ -27,6 +27,7 @@ enum mask { struct swaylock_xkb { uint32_t modifiers; + bool caps_lock; struct xkb_state *state; struct xkb_context *context; struct xkb_keymap *keymap; diff --git a/include/swaylock/swaylock.h b/include/swaylock/swaylock.h index ed9fea19..07b908d7 100644 --- a/include/swaylock/swaylock.h +++ b/include/swaylock/swaylock.h @@ -11,7 +11,9 @@ enum auth_state { AUTH_STATE_IDLE, + AUTH_STATE_CLEAR, AUTH_STATE_INPUT, + AUTH_STATE_INPUT_NOP, AUTH_STATE_BACKSPACE, AUTH_STATE_VALIDATING, AUTH_STATE_INVALID, diff --git a/swaylock/password.c b/swaylock/password.c index c8df3de8..1ad5cd81 100644 --- a/swaylock/password.c +++ b/swaylock/password.c @@ -105,11 +105,39 @@ void swaylock_handle_key(struct swaylock_state *state, state->auth_state = AUTH_STATE_INVALID; render_frames(state); break; + case XKB_KEY_Delete: case XKB_KEY_BackSpace: if (backspace(&state->password)) { state->auth_state = AUTH_STATE_BACKSPACE; - render_frames(state); + } else { + state->auth_state = AUTH_STATE_CLEAR; } + render_frames(state); + break; + case XKB_KEY_Escape: + clear_password_buffer(&state->password); + state->auth_state = AUTH_STATE_CLEAR; + render_frames(state); + break; + case XKB_KEY_Caps_Lock: + /* The state is getting active after this + * so we need to manually toggle it */ + state->xkb.caps_lock = !state->xkb.caps_lock; + state->auth_state = AUTH_STATE_INPUT_NOP; + render_frames(state); + break; + case XKB_KEY_Shift_L: + case XKB_KEY_Shift_R: + case XKB_KEY_Control_L: + case XKB_KEY_Control_R: + case XKB_KEY_Meta_L: + case XKB_KEY_Meta_R: + case XKB_KEY_Alt_L: + case XKB_KEY_Alt_R: + case XKB_KEY_Super_L: + case XKB_KEY_Super_R: + state->auth_state = AUTH_STATE_INPUT_NOP; + render_frames(state); break; default: if (codepoint) { diff --git a/swaylock/render.c b/swaylock/render.c index cd387be5..7d9d25a5 100644 --- a/swaylock/render.c +++ b/swaylock/render.c @@ -43,6 +43,7 @@ void render_frame(struct swaylock_surface *surface) { cairo_arc(cairo, buffer_width / 2, buffer_height / 2, arc_radius, 0, 2 * M_PI); switch (state->auth_state) { case AUTH_STATE_INPUT: + case AUTH_STATE_INPUT_NOP: case AUTH_STATE_BACKSPACE: { cairo_set_source_rgba(cairo, 0, 0, 0, 0.75); cairo_fill_preserve(cairo); @@ -61,6 +62,12 @@ void render_frame(struct swaylock_surface *surface) { cairo_set_source_rgb(cairo, 125.0 / 255, 51.0 / 255, 0); cairo_stroke(cairo); } break; + case AUTH_STATE_CLEAR: { + cairo_set_source_rgba(cairo, 229.0/255, 164.0/255, 69.0/255, 0.75); + cairo_fill_preserve(cairo); + cairo_set_source_rgb(cairo, 229.0/255, 164.0/255, 69.0/255); + cairo_stroke(cairo); + } break; default: break; } @@ -77,6 +84,15 @@ void render_frame(struct swaylock_surface *surface) { case AUTH_STATE_INVALID: text = "wrong"; break; + case AUTH_STATE_CLEAR: + text = "cleared"; + break; + case AUTH_STATE_INPUT: + case AUTH_STATE_INPUT_NOP: + if (state->xkb.caps_lock) { + text = "Caps Lock"; + cairo_set_source_rgb(cairo, 229.0/255, 164.0/255, 69.0/255); + } default: break; } diff --git a/swaylock/seat.c b/swaylock/seat.c index 21db7c4f..a81899a6 100644 --- a/swaylock/seat.c +++ b/swaylock/seat.c @@ -88,6 +88,7 @@ static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, xkb_mod_mask_t mask = xkb_state_serialize_mods(state->xkb.state, XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED); state->xkb.modifiers = 0; + state->xkb.caps_lock = xkb_state_mod_name_is_active(state->xkb.state, XKB_MOD_NAME_CAPS, XKB_STATE_MODS_LOCKED); for (uint32_t i = 0; i < MASK_LAST; ++i) { if (mask & state->xkb.masks[i]) { state->xkb.modifiers |= XKB_MODS[i];