Display xkb layout while typing

Displays the current keyboard layout below the unlock indicator if more
than one xkb layout is configured or the show-keyboard-layout option is
given. The text is displayed with a background box.

Adds commandline options for text color, background color and border
color of the box as well.
This commit is contained in:
Dominik Bendle 2019-02-05 16:12:54 +01:00
parent 1db5c78037
commit a052a56bc2
4 changed files with 115 additions and 11 deletions

View File

@ -34,6 +34,9 @@ struct swaylock_colors {
uint32_t caps_lock_bs_highlight; uint32_t caps_lock_bs_highlight;
uint32_t caps_lock_key_highlight; uint32_t caps_lock_key_highlight;
uint32_t separator; uint32_t separator;
uint32_t layout_background;
uint32_t layout_border;
uint32_t layout_text;
struct swaylock_colorset inside; struct swaylock_colorset inside;
struct swaylock_colorset line; struct swaylock_colorset line;
struct swaylock_colorset ring; struct swaylock_colorset ring;
@ -50,6 +53,7 @@ struct swaylock_args {
bool show_indicator; bool show_indicator;
bool show_caps_lock_text; bool show_caps_lock_text;
bool show_caps_lock_indicator; bool show_caps_lock_indicator;
bool show_keyboard_layout;
bool show_failed_attempts; bool show_failed_attempts;
bool daemonize; bool daemonize;
}; };

55
main.c
View File

@ -423,6 +423,9 @@ static void set_default_colors(struct swaylock_colors *colors) {
colors->caps_lock_bs_highlight = 0xDB3300FF; colors->caps_lock_bs_highlight = 0xDB3300FF;
colors->caps_lock_key_highlight = 0x33DB00FF; colors->caps_lock_key_highlight = 0x33DB00FF;
colors->separator = 0x000000FF; colors->separator = 0x000000FF;
colors->layout_background = 0x000000C0;
colors->layout_border = 0x00000000;
colors->layout_text = 0xFFFFFFFF;
colors->inside = (struct swaylock_colorset){ colors->inside = (struct swaylock_colorset){
.input = 0x000000C0, .input = 0x000000C0,
.cleared = 0xE5A445C0, .cleared = 0xE5A445C0,
@ -474,6 +477,9 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
LO_INSIDE_VER_COLOR, LO_INSIDE_VER_COLOR,
LO_INSIDE_WRONG_COLOR, LO_INSIDE_WRONG_COLOR,
LO_KEY_HL_COLOR, LO_KEY_HL_COLOR,
LO_LAYOUT_TXT_COLOR,
LO_LAYOUT_BG_COLOR,
LO_LAYOUT_BORDER_COLOR,
LO_LINE_COLOR, LO_LINE_COLOR,
LO_LINE_CLEAR_COLOR, LO_LINE_CLEAR_COLOR,
LO_LINE_CAPS_LOCK_COLOR, LO_LINE_CAPS_LOCK_COLOR,
@ -508,6 +514,7 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
{"scaling", required_argument, NULL, 's'}, {"scaling", required_argument, NULL, 's'},
{"tiling", no_argument, NULL, 't'}, {"tiling", no_argument, NULL, 't'},
{"no-unlock-indicator", no_argument, NULL, 'u'}, {"no-unlock-indicator", no_argument, NULL, 'u'},
{"show-keyboard-layout", no_argument, NULL, 'k'},
{"show-failed-attempts", no_argument, NULL, 'F'}, {"show-failed-attempts", no_argument, NULL, 'F'},
{"version", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'v'},
{"bs-hl-color", required_argument, NULL, LO_BS_HL_COLOR}, {"bs-hl-color", required_argument, NULL, LO_BS_HL_COLOR},
@ -522,6 +529,9 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
{"inside-ver-color", required_argument, NULL, LO_INSIDE_VER_COLOR}, {"inside-ver-color", required_argument, NULL, LO_INSIDE_VER_COLOR},
{"inside-wrong-color", required_argument, NULL, LO_INSIDE_WRONG_COLOR}, {"inside-wrong-color", required_argument, NULL, LO_INSIDE_WRONG_COLOR},
{"key-hl-color", required_argument, NULL, LO_KEY_HL_COLOR}, {"key-hl-color", required_argument, NULL, LO_KEY_HL_COLOR},
{"layout-bg-color", required_argument, NULL, LO_LAYOUT_BG_COLOR},
{"layout-border-color", required_argument, NULL, LO_LAYOUT_BORDER_COLOR},
{"layout-text-color", required_argument, NULL, LO_LAYOUT_TXT_COLOR},
{"line-color", required_argument, NULL, LO_LINE_COLOR}, {"line-color", required_argument, NULL, LO_LINE_COLOR},
{"line-clear-color", required_argument, NULL, LO_LINE_CLEAR_COLOR}, {"line-clear-color", required_argument, NULL, LO_LINE_CLEAR_COLOR},
{"line-caps-lock-color", required_argument, NULL, LO_LINE_CAPS_LOCK_COLOR}, {"line-caps-lock-color", required_argument, NULL, LO_LINE_CAPS_LOCK_COLOR},
@ -552,12 +562,16 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
"Enable debugging output.\n" "Enable debugging output.\n"
" -e, --ignore-empty-password " " -e, --ignore-empty-password "
"When an empty password is provided, do not validate it.\n" "When an empty password is provided, do not validate it.\n"
" -F, --show-failed-attempts "
"Show current count of failed authentication attempts.\n"
" -f, --daemonize " " -f, --daemonize "
"Detach from the controlling terminal after locking.\n" "Detach from the controlling terminal after locking.\n"
" -h, --help " " -h, --help "
"Show help message and quit.\n" "Show help message and quit.\n"
" -i, --image [[<output>]:]<path> " " -i, --image [[<output>]:]<path> "
"Display the given image.\n" "Display the given image.\n"
" -k, --show-keyboard-layout "
"Display the current xkb layout while typing.\n"
" -L, --disable-caps-lock-text " " -L, --disable-caps-lock-text "
"Disable the Caps Lock text.\n" "Disable the Caps Lock text.\n"
" -l, --indicator-caps-lock " " -l, --indicator-caps-lock "
@ -568,8 +582,6 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
"Same as --scaling=tile.\n" "Same as --scaling=tile.\n"
" -u, --no-unlock-indicator " " -u, --no-unlock-indicator "
"Disable the unlock indicator.\n" "Disable the unlock indicator.\n"
" -F, --show-failed-attempts "
"Show current count of failed authentication attempts.\n"
" -v, --version " " -v, --version "
"Show the version number and quit.\n" "Show the version number and quit.\n"
" --bs-hl-color <color> " " --bs-hl-color <color> "
@ -599,6 +611,12 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
"Sets the color of the inside of the indicator when invalid.\n" "Sets the color of the inside of the indicator when invalid.\n"
" --key-hl-color <color> " " --key-hl-color <color> "
"Sets the color of the key press highlight segments.\n" "Sets the color of the key press highlight segments.\n"
" --layout-bg-color <color> "
"Sets the background color of the box containing the layout text.\n"
" --layout-border-color <color> "
"Sets the color of the border of the box containing the layout text.\n"
" --layout-text-color <color> "
"Sets the color of the layout text.\n"
" --line-color <color> " " --line-color <color> "
"Sets the color of the line between the inside and ring.\n" "Sets the color of the line between the inside and ring.\n"
" --line-clear-color <color> " " --line-clear-color <color> "
@ -647,7 +665,7 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
optind = 1; optind = 1;
while (1) { while (1) {
int opt_idx = 0; int opt_idx = 0;
c = getopt_long(argc, argv, "c:deFfhi:Llnrs:tuvC:", long_options, c = getopt_long(argc, argv, "c:deFfhi:kLlnrs:tuvC:", long_options,
&opt_idx); &opt_idx);
if (c == -1) { if (c == -1) {
break; break;
@ -671,6 +689,11 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
state->args.ignore_empty = true; state->args.ignore_empty = true;
} }
break; break;
case 'F':
if (state) {
state->args.show_failed_attempts = true;
}
break;
case 'f': case 'f':
if (state) { if (state) {
state->args.daemonize = true; state->args.daemonize = true;
@ -681,6 +704,11 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
load_image(optarg, state); load_image(optarg, state);
} }
break; break;
case 'k':
if (state) {
state->args.show_keyboard_layout = true;
}
break;
case 'L': case 'L':
if (state) { if (state) {
state->args.show_caps_lock_text = false; state->args.show_caps_lock_text = false;
@ -719,11 +747,6 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
state->args.show_indicator = false; state->args.show_indicator = false;
} }
break; break;
case 'F':
if (state) {
state->args.show_failed_attempts = true;
}
break;
case 'v': case 'v':
fprintf(stdout, "swaylock version " SWAYLOCK_VERSION "\n"); fprintf(stdout, "swaylock version " SWAYLOCK_VERSION "\n");
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -789,6 +812,21 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
state->args.colors.key_highlight = parse_color(optarg); state->args.colors.key_highlight = parse_color(optarg);
} }
break; break;
case LO_LAYOUT_BG_COLOR:
if (state) {
state->args.colors.layout_background = parse_color(optarg);
}
break;
case LO_LAYOUT_BORDER_COLOR:
if (state) {
state->args.colors.layout_border = parse_color(optarg);
}
break;
case LO_LAYOUT_TXT_COLOR:
if (state) {
state->args.colors.layout_text = parse_color(optarg);
}
break;
case LO_LINE_COLOR: case LO_LINE_COLOR:
if (state) { if (state) {
state->args.colors.line.input = parse_color(optarg); state->args.colors.line.input = parse_color(optarg);
@ -989,6 +1027,7 @@ int main(int argc, char **argv) {
.show_indicator = true, .show_indicator = true,
.show_caps_lock_indicator = false, .show_caps_lock_indicator = false,
.show_caps_lock_text = true, .show_caps_lock_text = true,
.show_keyboard_layout = false,
.show_failed_attempts = false .show_failed_attempts = false
}; };
wl_list_init(&state.images); wl_list_init(&state.images);

View File

@ -86,6 +86,7 @@ void render_frame(struct swaylock_surface *surface) {
// Draw a message // Draw a message
char *text = NULL; char *text = NULL;
const char *layout_text = NULL;
char attempts[4]; // like i3lock: count no more than 999 char attempts[4]; // like i3lock: count no more than 999
set_color_for_state(cairo, state, &state->args.colors.text); set_color_for_state(cairo, state, &state->args.colors.text);
cairo_select_font_face(cairo, state->args.font, cairo_select_font_face(cairo, state->args.font,
@ -116,6 +117,20 @@ void render_frame(struct swaylock_surface *surface) {
text = attempts; text = attempts;
} }
} }
xkb_layout_index_t num_layout = xkb_keymap_num_layouts(state->xkb.keymap);
if (state->args.show_keyboard_layout || num_layout > 1) {
xkb_layout_index_t curr_layout = 0;
// advance to the first active layout (if any)
while (curr_layout < num_layout &&
xkb_state_layout_index_is_active(state->xkb.state,
curr_layout, XKB_STATE_LAYOUT_EFFECTIVE) != 1) {
++curr_layout;
}
// will handle invalid index if none are active
layout_text = xkb_keymap_layout_get_name(state->xkb.keymap, curr_layout);
}
break; break;
default: default:
break; break;
@ -185,6 +200,39 @@ void render_frame(struct swaylock_surface *surface) {
cairo_arc(cairo, buffer_width / 2, buffer_height / 2, cairo_arc(cairo, buffer_width / 2, buffer_height / 2,
arc_radius + arc_thickness / 2, 0, 2 * M_PI); arc_radius + arc_thickness / 2, 0, 2 * M_PI);
cairo_stroke(cairo); cairo_stroke(cairo);
// display layout text seperately
if (layout_text) {
cairo_text_extents_t extents;
cairo_font_extents_t fe;
double x, y;
double box_padding = 4.0 * surface->scale;
cairo_text_extents(cairo, layout_text, &extents);
cairo_font_extents(cairo, &fe);
// upper left coordinates for box
x = (buffer_width / 2) - (extents.width / 2) - box_padding;
y = (buffer_height / 2) + arc_radius + arc_thickness/2 +
box_padding; // use box_padding also as gap to indicator
// background box
cairo_rectangle(cairo, x, y,
extents.width + 2.0 * box_padding,
fe.height + 2.0 * box_padding);
cairo_set_source_u32(cairo, state->args.colors.layout_background);
cairo_fill_preserve(cairo);
// border
cairo_set_source_u32(cairo, state->args.colors.layout_border);
cairo_stroke(cairo);
cairo_new_sub_path(cairo);
// take font extents and padding into account
cairo_move_to(cairo,
x - extents.x_bearing + box_padding,
y + (fe.height - fe.descent) + box_padding);
cairo_set_source_u32(cairo, state->args.colors.layout_text);
cairo_show_text(cairo, layout_text);
cairo_new_sub_path(cairo);
}
} }
wl_surface_set_buffer_scale(surface->surface, surface->scale); wl_surface_set_buffer_scale(surface->surface, surface->scale);

View File

@ -27,6 +27,9 @@ Locks your Wayland session.
*-e, --ignore-empty-password* *-e, --ignore-empty-password*
When an empty password is provided by the user, do not validate it. When an empty password is provided by the user, do not validate it.
*-F, --show-failed-attempts*
Show the number of failed authentication attempts on the indicator.
*-f, --daemonize* *-f, --daemonize*
Detach from the controlling terminal after locking. Detach from the controlling terminal after locking.
@ -48,15 +51,16 @@ Locks your Wayland session.
a background color. If the path potentially contains a ':', prefix it with another a background color. If the path potentially contains a ':', prefix it with another
':' to prevent interpreting part of it as <output>. ':' to prevent interpreting part of it as <output>.
*-k, --show-keyboard-layout*
Force displaying the current xkb layout while typing, even if only one layout
is configured.
*-L, --disable-caps-lock-text* *-L, --disable-caps-lock-text*
Disable the Caps Lock Text. Disable the Caps Lock Text.
*-l, --indicator-caps-lock* *-l, --indicator-caps-lock*
Show the current Caps Lock state also on the indicator. Show the current Caps Lock state also on the indicator.
*-F, --show-failed-attempts*
Show the number of failed authentication attempts on the indicator.
*-s, --scaling* *-s, --scaling*
Scaling mode for images: _stretch_, _fill_, _fit_, _center_, or _tile_. Use Scaling mode for images: _stretch_, _fill_, _fit_, _center_, or _tile_. Use
the additional mode _solid\_color_ to display only the background color, even the additional mode _solid\_color_ to display only the background color, even
@ -107,6 +111,15 @@ Locks your Wayland session.
*--key-hl-color* <rrggbb[aa]> *--key-hl-color* <rrggbb[aa]>
Sets the color of key press highlight segments. Sets the color of key press highlight segments.
*--layout-bg-color* <rrggbb[aa]>
Sets the background color of the box containing the layout text.
*--layout-border-color* <rrggbb[aa]>
Sets the color of the border of the box containing the layout text.
*--layout-text-color* <rrggbb[aa]>
Sets the color of the layout text.
*--line-color* <rrggbb[aa]> *--line-color* <rrggbb[aa]>
Sets the color of the lines that separate the inside and outside of the Sets the color of the lines that separate the inside and outside of the
indicator when typing or idle. indicator when typing or idle.