diff options
-rw-r--r-- | common/list.c | 15 | ||||
-rw-r--r-- | include/list.h | 2 | ||||
-rw-r--r-- | include/swaylock/swaylock.h | 24 | ||||
-rw-r--r-- | sway/input/seat.c | 8 | ||||
-rw-r--r-- | swaylock/main.c | 284 | ||||
-rw-r--r-- | swaylock/password.c | 4 | ||||
-rw-r--r-- | swaylock/render.c | 74 | ||||
-rw-r--r-- | swaylock/swaylock.1.scd | 88 |
8 files changed, 401 insertions, 98 deletions
diff --git a/common/list.c b/common/list.c index 39cc10e1..66d52f70 100644 --- a/common/list.c +++ b/common/list.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <stdio.h> | 2 | #include <stdio.h> |
3 | #include <stdlib.h> | 3 | #include <stdlib.h> |
4 | #include <string.h> | 4 | #include <string.h> |
5 | #include "log.h" | ||
5 | 6 | ||
6 | list_t *create_list(void) { | 7 | list_t *create_list(void) { |
7 | list_t *list = malloc(sizeof(list_t)); | 8 | list_t *list = malloc(sizeof(list_t)); |
@@ -82,6 +83,20 @@ void list_swap(list_t *list, int src, int dest) { | |||
82 | list->items[dest] = tmp; | 83 | list->items[dest] = tmp; |
83 | } | 84 | } |
84 | 85 | ||
86 | void list_move_to_end(list_t *list, void *item) { | ||
87 | int i; | ||
88 | for (i = 0; i < list->length; ++i) { | ||
89 | if (list->items[i] == item) { | ||
90 | break; | ||
91 | } | ||
92 | } | ||
93 | if (!sway_assert(i < list->length, "Item not found in list")) { | ||
94 | return; | ||
95 | } | ||
96 | list_del(list, i); | ||
97 | list_add(list, item); | ||
98 | } | ||
99 | |||
85 | static void list_rotate(list_t *list, int from, int to) { | 100 | static void list_rotate(list_t *list, int from, int to) { |
86 | void *tmp = list->items[to]; | 101 | void *tmp = list->items[to]; |
87 | 102 | ||
diff --git a/include/list.h b/include/list.h index 7eead4ac..5a0d7d80 100644 --- a/include/list.h +++ b/include/list.h | |||
@@ -24,4 +24,6 @@ int list_seq_find(list_t *list, int compare(const void *item, const void *cmp_to | |||
24 | void list_stable_sort(list_t *list, int compare(const void *a, const void *b)); | 24 | void list_stable_sort(list_t *list, int compare(const void *a, const void *b)); |
25 | // swap two elements in a list | 25 | // swap two elements in a list |
26 | void list_swap(list_t *list, int src, int dest); | 26 | void list_swap(list_t *list, int src, int dest); |
27 | // move item to end of list | ||
28 | void list_move_to_end(list_t *list, void *item); | ||
27 | #endif | 29 | #endif |
diff --git a/include/swaylock/swaylock.h b/include/swaylock/swaylock.h index cf80a6ba..950cfaaf 100644 --- a/include/swaylock/swaylock.h +++ b/include/swaylock/swaylock.h | |||
@@ -19,9 +19,31 @@ enum auth_state { | |||
19 | AUTH_STATE_INVALID, | 19 | AUTH_STATE_INVALID, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | struct swaylock_colorset { | ||
23 | uint32_t input; | ||
24 | uint32_t cleared; | ||
25 | uint32_t verifying; | ||
26 | uint32_t wrong; | ||
27 | }; | ||
28 | |||
29 | struct swaylock_colors { | ||
30 | uint32_t background; | ||
31 | uint32_t bs_highlight; | ||
32 | uint32_t key_highlight; | ||
33 | uint32_t separator; | ||
34 | struct swaylock_colorset inside; | ||
35 | struct swaylock_colorset line; | ||
36 | struct swaylock_colorset ring; | ||
37 | struct swaylock_colorset text; | ||
38 | }; | ||
39 | |||
22 | struct swaylock_args { | 40 | struct swaylock_args { |
23 | uint32_t color; | 41 | struct swaylock_colors colors; |
24 | enum background_mode mode; | 42 | enum background_mode mode; |
43 | char *font; | ||
44 | uint32_t radius; | ||
45 | uint32_t thickness; | ||
46 | bool ignore_empty; | ||
25 | bool show_indicator; | 47 | bool show_indicator; |
26 | bool daemonize; | 48 | bool daemonize; |
27 | }; | 49 | }; |
diff --git a/sway/input/seat.c b/sway/input/seat.c index 5dadb31d..bf4e8876 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -666,6 +666,14 @@ void seat_set_focus_warp(struct sway_seat *seat, | |||
666 | container_damage_whole(container->parent); | 666 | container_damage_whole(container->parent); |
667 | } | 667 | } |
668 | 668 | ||
669 | // If we've focused a floating container, bring it to the front. | ||
670 | // We do this by putting it at the end of the floating list. | ||
671 | // This must happen for both the pending and current children lists. | ||
672 | if (container_is_floating(container)) { | ||
673 | list_move_to_end(container->parent->children, container); | ||
674 | list_move_to_end(container->parent->current.children, container); | ||
675 | } | ||
676 | |||
669 | // clean up unfocused empty workspace on new output | 677 | // clean up unfocused empty workspace on new output |
670 | if (new_output_last_ws) { | 678 | if (new_output_last_ws) { |
671 | if (!workspace_is_visible(new_output_last_ws) | 679 | if (!workspace_is_visible(new_output_last_ws) |
diff --git a/swaylock/main.c b/swaylock/main.c index 68d67a10..faebc757 100644 --- a/swaylock/main.c +++ b/swaylock/main.c | |||
@@ -89,7 +89,7 @@ static bool surface_is_opaque(struct swaylock_surface *surface) { | |||
89 | if (surface->image) { | 89 | if (surface->image) { |
90 | return cairo_surface_get_content(surface->image) == CAIRO_CONTENT_COLOR; | 90 | return cairo_surface_get_content(surface->image) == CAIRO_CONTENT_COLOR; |
91 | } | 91 | } |
92 | return (surface->state->args.color & 0xff) == 0xff; | 92 | return (surface->state->args.colors.background & 0xff) == 0xff; |
93 | } | 93 | } |
94 | 94 | ||
95 | static void create_layer_surface(struct swaylock_surface *surface) { | 95 | static void create_layer_surface(struct swaylock_surface *surface) { |
@@ -381,59 +381,225 @@ static void load_image(char *arg, struct swaylock_state *state) { | |||
381 | image->path, image->output_name ? image->output_name : "*"); | 381 | image->path, image->output_name ? image->output_name : "*"); |
382 | } | 382 | } |
383 | 383 | ||
384 | static void set_default_colors(struct swaylock_colors *colors) { | ||
385 | colors->background = 0xFFFFFFFF; | ||
386 | colors->bs_highlight = 0xDB3300FF; | ||
387 | colors->key_highlight = 0x33DB00FF; | ||
388 | colors->separator = 0x000000FF; | ||
389 | colors->inside = (struct swaylock_colorset){ | ||
390 | .input = 0x000000C0, | ||
391 | .cleared = 0xE5A445C0, | ||
392 | .verifying = 0x0072FFC0, | ||
393 | .wrong = 0xFA0000C0, | ||
394 | }; | ||
395 | colors->line = (struct swaylock_colorset){ | ||
396 | .input = 0x000000FF, | ||
397 | .cleared = 0x000000FF, | ||
398 | .verifying = 0x000000FF, | ||
399 | .wrong = 0x000000FF, | ||
400 | }; | ||
401 | colors->ring = (struct swaylock_colorset){ | ||
402 | .input = 0x337D00FF, | ||
403 | .cleared = 0xE5A445FF, | ||
404 | .verifying = 0x3300FFFF, | ||
405 | .wrong = 0x7D3300FF, | ||
406 | }; | ||
407 | colors->text = (struct swaylock_colorset){ | ||
408 | .input = 0xE5A445FF, | ||
409 | .cleared = 0x000000FF, | ||
410 | .verifying = 0x000000FF, | ||
411 | .wrong = 0x000000FF, | ||
412 | }; | ||
413 | } | ||
414 | |||
384 | static struct swaylock_state state; | 415 | static struct swaylock_state state; |
385 | 416 | ||
386 | int main(int argc, char **argv) { | 417 | int main(int argc, char **argv) { |
418 | enum line_mode { | ||
419 | LM_LINE, | ||
420 | LM_INSIDE, | ||
421 | LM_RING, | ||
422 | }; | ||
423 | |||
424 | enum long_option_codes { | ||
425 | LO_BS_HL_COLOR = 256, | ||
426 | LO_FONT, | ||
427 | LO_IND_RADIUS, | ||
428 | LO_IND_THICKNESS, | ||
429 | LO_INSIDE_COLOR, | ||
430 | LO_INSIDE_CLEAR_COLOR, | ||
431 | LO_INSIDE_VER_COLOR, | ||
432 | LO_INSIDE_WRONG_COLOR, | ||
433 | LO_KEY_HL_COLOR, | ||
434 | LO_LINE_COLOR, | ||
435 | LO_LINE_CLEAR_COLOR, | ||
436 | LO_LINE_VER_COLOR, | ||
437 | LO_LINE_WRONG_COLOR, | ||
438 | LO_RING_COLOR, | ||
439 | LO_RING_CLEAR_COLOR, | ||
440 | LO_RING_VER_COLOR, | ||
441 | LO_RING_WRONG_COLOR, | ||
442 | LO_SEP_COLOR, | ||
443 | LO_TEXT_COLOR, | ||
444 | LO_TEXT_CLEAR_COLOR, | ||
445 | LO_TEXT_VER_COLOR, | ||
446 | LO_TEXT_WRONG_COLOR, | ||
447 | }; | ||
448 | |||
387 | static struct option long_options[] = { | 449 | static struct option long_options[] = { |
388 | {"help", no_argument, NULL, 'h'}, | ||
389 | {"color", required_argument, NULL, 'c'}, | 450 | {"color", required_argument, NULL, 'c'}, |
451 | {"ignore-empty-password", no_argument, NULL, 'e'}, | ||
452 | {"daemonize", no_argument, NULL, 'f'}, | ||
453 | {"help", no_argument, NULL, 'h'}, | ||
390 | {"image", required_argument, NULL, 'i'}, | 454 | {"image", required_argument, NULL, 'i'}, |
455 | {"line-uses-inside", no_argument, NULL, 'n'}, | ||
456 | {"socket", required_argument, NULL, 'p'}, | ||
457 | {"line-uses-ring", no_argument, NULL, 'r'}, | ||
391 | {"scaling", required_argument, NULL, 's'}, | 458 | {"scaling", required_argument, NULL, 's'}, |
392 | {"tiling", no_argument, NULL, 't'}, | 459 | {"tiling", no_argument, NULL, 't'}, |
393 | {"version", no_argument, NULL, 'v'}, | ||
394 | {"socket", required_argument, NULL, 'p'}, | ||
395 | {"no-unlock-indicator", no_argument, NULL, 'u'}, | 460 | {"no-unlock-indicator", no_argument, NULL, 'u'}, |
396 | {"daemonize", no_argument, NULL, 'f'}, | 461 | {"version", no_argument, NULL, 'v'}, |
462 | {"bs-hl-color", required_argument, NULL, LO_BS_HL_COLOR}, | ||
463 | {"font", required_argument, NULL, LO_FONT}, | ||
464 | {"indicator-radius", required_argument, NULL, LO_IND_RADIUS}, | ||
465 | {"indicator-thickness", required_argument, NULL, LO_IND_THICKNESS}, | ||
466 | {"inside-color", required_argument, NULL, LO_INSIDE_COLOR}, | ||
467 | {"inside-clear-color", required_argument, NULL, LO_INSIDE_CLEAR_COLOR}, | ||
468 | {"inside-ver-color", required_argument, NULL, LO_INSIDE_VER_COLOR}, | ||
469 | {"inside-wrong-color", required_argument, NULL, LO_INSIDE_WRONG_COLOR}, | ||
470 | {"key-hl-color", required_argument, NULL, LO_KEY_HL_COLOR}, | ||
471 | {"line-color", required_argument, NULL, LO_LINE_COLOR}, | ||
472 | {"line-clear-color", required_argument, NULL, LO_LINE_CLEAR_COLOR}, | ||
473 | {"line-ver-color", required_argument, NULL, LO_LINE_VER_COLOR}, | ||
474 | {"line-wrong-color", required_argument, NULL, LO_LINE_WRONG_COLOR}, | ||
475 | {"ring-color", required_argument, NULL, LO_RING_COLOR}, | ||
476 | {"ring-clear-color", required_argument, NULL, LO_RING_CLEAR_COLOR}, | ||
477 | {"ring-ver-color", required_argument, NULL, LO_RING_VER_COLOR}, | ||
478 | {"ring-wrong-color", required_argument, NULL, LO_RING_WRONG_COLOR}, | ||
479 | {"separator-color", required_argument, NULL, LO_SEP_COLOR}, | ||
480 | {"text-color", required_argument, NULL, LO_TEXT_COLOR}, | ||
481 | {"text-clear-color", required_argument, NULL, LO_TEXT_CLEAR_COLOR}, | ||
482 | {"text-ver-color", required_argument, NULL, LO_TEXT_VER_COLOR}, | ||
483 | {"text-wrong-color", required_argument, NULL, LO_TEXT_WRONG_COLOR}, | ||
397 | {0, 0, 0, 0} | 484 | {0, 0, 0, 0} |
398 | }; | 485 | }; |
399 | 486 | ||
400 | const char usage[] = | 487 | const char usage[] = |
401 | "Usage: swaylock [options...]\n" | 488 | "Usage: swaylock [options...]\n" |
402 | "\n" | 489 | "\n" |
403 | " -h, --help Show help message and quit.\n" | 490 | " -c, --color <color> " |
404 | " -c, --color <rrggbb[aa]> Turn the screen into the given color instead of white.\n" | 491 | "Turn the screen into the given color instead of white.\n" |
405 | " -s, --scaling Scaling mode: stretch, fill, fit, center, tile.\n" | 492 | " -e, --ignore-empty-password " |
406 | " -t, --tiling Same as --scaling=tile.\n" | 493 | "When an empty password is provided, do not validate it.\n" |
407 | " -v, --version Show the version number and quit.\n" | 494 | " -f, --daemonize " |
408 | " -i, --image [<output>:]<path> Display the given image.\n" | 495 | "Detach from the controlling terminal after locking.\n" |
409 | " -u, --no-unlock-indicator Disable the unlock indicator.\n" | 496 | " -h, --help " |
410 | " -f, --daemonize Detach from the controlling terminal after locking.\n"; | 497 | "Show help message and quit.\n" |
498 | " -i, --image [<output>:]<path> " | ||
499 | "Display the given image.\n" | ||
500 | " -s, --scaling <mode> " | ||
501 | "Scaling mode: stretch, fill, fit, center, tile.\n" | ||
502 | " -t, --tiling " | ||
503 | "Same as --scaling=tile.\n" | ||
504 | " -u, --no-unlock-indicator " | ||
505 | "Disable the unlock indicator.\n" | ||
506 | " -v, --version " | ||
507 | "Show the version number and quit.\n" | ||
508 | " --bs-hl-color <color> " | ||
509 | "Sets the color of backspace highlight segments.\n" | ||
510 | " --font <font> " | ||
511 | "Sets the font of the text.\n" | ||
512 | " --indicator-radius <radius> " | ||
513 | "Sets the indicator radius.\n" | ||
514 | " --indicator-thickness <thick> " | ||
515 | "Sets the indicator thickness.\n" | ||
516 | " --inside-color <color> " | ||
517 | "Sets the color of the inside of the indicator.\n" | ||
518 | " --inside-clear-color <color> " | ||
519 | "Sets the color of the inside of the indicator when cleared.\n" | ||
520 | " --inside-ver-color <color> " | ||
521 | "Sets the color of the inside of the indicator when verifying.\n" | ||
522 | " --inside-wrong-color <color> " | ||
523 | "Sets the color of the inside of the indicator when invalid.\n" | ||
524 | " --key-hl-color <color> " | ||
525 | "Sets the color of the key press highlight segments.\n" | ||
526 | " --line-color <color> " | ||
527 | "Sets the color of the line between the inside and ring.\n" | ||
528 | " --line-clear-color <color> " | ||
529 | "Sets the color of the line between the inside and ring when " | ||
530 | "cleared.\n" | ||
531 | " --line-ver-color <color> " | ||
532 | "Sets the color of the line between the inside and ring when " | ||
533 | "verifying.\n" | ||
534 | " --line-wrong-color <color> " | ||
535 | "Sets the color of the line between the inside and ring when " | ||
536 | "invalid.\n" | ||
537 | " -n, --line-uses-inside " | ||
538 | "Use the inside color for the line between the inside and ring.\n" | ||
539 | " -r, --line-uses-ring " | ||
540 | "Use the ring color for the line between the inside and ring.\n" | ||
541 | " --ring-color <color> " | ||
542 | "Sets the color of the ring of the indicator.\n" | ||
543 | " --ring-clear-color <color> " | ||
544 | "Sets the color of the ring of the indicator when cleared.\n" | ||
545 | " --ring-ver-color <color> " | ||
546 | "Sets the color of the ring of the indicator when verifying.\n" | ||
547 | " --ring-wrong-color <color> " | ||
548 | "Sets the color of the ring of the indicator when invalid.\n" | ||
549 | " --separator-color <color> " | ||
550 | "Sets the color of the lines that separate highlight segments.\n" | ||
551 | " --text-color <color> " | ||
552 | "Sets the color of the text.\n" | ||
553 | " --text-clear-color <color> " | ||
554 | "Sets the color of the text when cleared.\n" | ||
555 | " --text-ver-color <color> " | ||
556 | "Sets the color of the text when verifying.\n" | ||
557 | " --text-wrong-color <color> " | ||
558 | "Sets the color of the text when invalid.\n" | ||
559 | "\n" | ||
560 | "All <color> options are of the form <rrggbb[aa]>.\n"; | ||
411 | 561 | ||
562 | enum line_mode line_mode = LM_LINE; | ||
412 | state.args = (struct swaylock_args){ | 563 | state.args = (struct swaylock_args){ |
413 | .mode = BACKGROUND_MODE_SOLID_COLOR, | 564 | .mode = BACKGROUND_MODE_SOLID_COLOR, |
414 | .color = 0xFFFFFFFF, | 565 | .font = strdup("sans-serif"), |
566 | .radius = 50, | ||
567 | .thickness = 10, | ||
568 | .ignore_empty = false, | ||
415 | .show_indicator = true, | 569 | .show_indicator = true, |
416 | }; | 570 | }; |
417 | wl_list_init(&state.images); | 571 | wl_list_init(&state.images); |
572 | set_default_colors(&state.args.colors); | ||
418 | 573 | ||
419 | wlr_log_init(WLR_DEBUG, NULL); | 574 | wlr_log_init(WLR_DEBUG, NULL); |
420 | 575 | ||
421 | int c; | 576 | int c; |
422 | while (1) { | 577 | while (1) { |
423 | int option_index = 0; | 578 | int opt_idx = 0; |
424 | c = getopt_long(argc, argv, "hc:i:s:tvuf", long_options, &option_index); | 579 | c = getopt_long(argc, argv, "c:efhi:nrs:tuv", long_options, &opt_idx); |
425 | if (c == -1) { | 580 | if (c == -1) { |
426 | break; | 581 | break; |
427 | } | 582 | } |
428 | switch (c) { | 583 | switch (c) { |
429 | case 'c': { | 584 | case 'c': |
430 | state.args.color = parse_color(optarg); | 585 | state.args.colors.background = parse_color(optarg); |
431 | state.args.mode = BACKGROUND_MODE_SOLID_COLOR; | 586 | state.args.mode = BACKGROUND_MODE_SOLID_COLOR; |
432 | break; | 587 | break; |
433 | } | 588 | case 'e': |
589 | state.args.ignore_empty = true; | ||
590 | break; | ||
591 | case 'f': | ||
592 | state.args.daemonize = true; | ||
593 | break; | ||
434 | case 'i': | 594 | case 'i': |
435 | load_image(optarg, &state); | 595 | load_image(optarg, &state); |
436 | break; | 596 | break; |
597 | case 'n': | ||
598 | line_mode = LM_INSIDE; | ||
599 | break; | ||
600 | case 'r': | ||
601 | line_mode = LM_RING; | ||
602 | break; | ||
437 | case 's': | 603 | case 's': |
438 | state.args.mode = parse_background_mode(optarg); | 604 | state.args.mode = parse_background_mode(optarg); |
439 | if (state.args.mode == BACKGROUND_MODE_INVALID) { | 605 | if (state.args.mode == BACKGROUND_MODE_INVALID) { |
@@ -443,6 +609,9 @@ int main(int argc, char **argv) { | |||
443 | case 't': | 609 | case 't': |
444 | state.args.mode = BACKGROUND_MODE_TILE; | 610 | state.args.mode = BACKGROUND_MODE_TILE; |
445 | break; | 611 | break; |
612 | case 'u': | ||
613 | state.args.show_indicator = false; | ||
614 | break; | ||
446 | case 'v': | 615 | case 'v': |
447 | #if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE | 616 | #if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE |
448 | fprintf(stdout, "swaylock version %s (%s, branch \"%s\")\n", | 617 | fprintf(stdout, "swaylock version %s (%s, branch \"%s\")\n", |
@@ -451,11 +620,72 @@ int main(int argc, char **argv) { | |||
451 | fprintf(stdout, "version unknown\n"); | 620 | fprintf(stdout, "version unknown\n"); |
452 | #endif | 621 | #endif |
453 | return 0; | 622 | return 0; |
454 | case 'u': | 623 | case LO_BS_HL_COLOR: |
455 | state.args.show_indicator = false; | 624 | state.args.colors.bs_highlight = parse_color(optarg); |
456 | break; | 625 | break; |
457 | case 'f': | 626 | case LO_FONT: |
458 | state.args.daemonize = true; | 627 | free(state.args.font); |
628 | state.args.font = strdup(optarg); | ||
629 | break; | ||
630 | case LO_IND_RADIUS: | ||
631 | state.args.radius = strtol(optarg, NULL, 0); | ||
632 | break; | ||
633 | case LO_IND_THICKNESS: | ||
634 | state.args.thickness = strtol(optarg, NULL, 0); | ||
635 | break; | ||
636 | case LO_INSIDE_COLOR: | ||
637 | state.args.colors.inside.input = parse_color(optarg); | ||
638 | break; | ||
639 | case LO_INSIDE_CLEAR_COLOR: | ||
640 | state.args.colors.inside.cleared = parse_color(optarg); | ||
641 | break; | ||
642 | case LO_INSIDE_VER_COLOR: | ||
643 | state.args.colors.inside.verifying = parse_color(optarg); | ||
644 | break; | ||
645 | case LO_INSIDE_WRONG_COLOR: | ||
646 | state.args.colors.inside.wrong = parse_color(optarg); | ||
647 | break; | ||
648 | case LO_KEY_HL_COLOR: | ||
649 | state.args.colors.key_highlight = parse_color(optarg); | ||
650 | break; | ||
651 | case LO_LINE_COLOR: | ||
652 | state.args.colors.line.input = parse_color(optarg); | ||
653 | break; | ||
654 | case LO_LINE_CLEAR_COLOR: | ||
655 | state.args.colors.line.cleared = parse_color(optarg); | ||
656 | break; | ||
657 | case LO_LINE_VER_COLOR: | ||
658 | state.args.colors.line.verifying = parse_color(optarg); | ||
659 | break; | ||
660 | case LO_LINE_WRONG_COLOR: | ||
661 | state.args.colors.line.wrong = parse_color(optarg); | ||
662 | break; | ||
663 | case LO_RING_COLOR: | ||
664 | state.args.colors.ring.input = parse_color(optarg); | ||
665 | break; | ||
666 | case LO_RING_CLEAR_COLOR: | ||
667 | state.args.colors.ring.cleared = parse_color(optarg); | ||
668 | break; | ||
669 | case LO_RING_VER_COLOR: | ||
670 | state.args.colors.ring.verifying = parse_color(optarg); | ||
671 | break; | ||
672 | case LO_RING_WRONG_COLOR: | ||
673 | state.args.colors.ring.wrong = parse_color(optarg); | ||
674 | break; | ||
675 | case LO_SEP_COLOR: | ||
676 | state.args.colors.separator = parse_color(optarg); | ||
677 | break; | ||
678 | case LO_TEXT_COLOR: | ||
679 | state.args.colors.text.input = parse_color(optarg); | ||
680 | break; | ||
681 | case LO_TEXT_CLEAR_COLOR: | ||
682 | state.args.colors.text.cleared = parse_color(optarg); | ||
683 | break; | ||
684 | case LO_TEXT_VER_COLOR: | ||
685 | state.args.colors.text.verifying = parse_color(optarg); | ||
686 | break; | ||
687 | case LO_TEXT_WRONG_COLOR: | ||
688 | state.args.colors.text.wrong = parse_color(optarg); | ||
459 | break; | 689 | break; |
460 | default: | 690 | default: |
461 | fprintf(stderr, "%s", usage); | 691 | fprintf(stderr, "%s", usage); |
@@ -463,6 +693,12 @@ int main(int argc, char **argv) { | |||
463 | } | 693 | } |
464 | } | 694 | } |
465 | 695 | ||
696 | if (line_mode == LM_INSIDE) { | ||
697 | state.args.colors.line = state.args.colors.inside; | ||
698 | } else if (line_mode == LM_RING) { | ||
699 | state.args.colors.line = state.args.colors.ring; | ||
700 | } | ||
701 | |||
466 | #ifdef __linux__ | 702 | #ifdef __linux__ |
467 | // Most non-linux platforms require root to mlock() | 703 | // Most non-linux platforms require root to mlock() |
468 | if (mlock(state.password.buffer, sizeof(state.password.buffer)) != 0) { | 704 | if (mlock(state.password.buffer, sizeof(state.password.buffer)) != 0) { |
@@ -520,5 +756,7 @@ int main(int argc, char **argv) { | |||
520 | while (wl_display_dispatch(state.display) != -1 && state.run_display) { | 756 | while (wl_display_dispatch(state.display) != -1 && state.run_display) { |
521 | // This space intentionally left blank | 757 | // This space intentionally left blank |
522 | } | 758 | } |
759 | |||
760 | free(state.args.font); | ||
523 | return 0; | 761 | return 0; |
524 | } | 762 | } |
diff --git a/swaylock/password.c b/swaylock/password.c index 7c6fd67b..7c686b34 100644 --- a/swaylock/password.c +++ b/swaylock/password.c | |||
@@ -95,6 +95,10 @@ void swaylock_handle_key(struct swaylock_state *state, | |||
95 | switch (keysym) { | 95 | switch (keysym) { |
96 | case XKB_KEY_KP_Enter: /* fallthrough */ | 96 | case XKB_KEY_KP_Enter: /* fallthrough */ |
97 | case XKB_KEY_Return: | 97 | case XKB_KEY_Return: |
98 | if (state->args.ignore_empty && state->password.len == 0) { | ||
99 | break; | ||
100 | } | ||
101 | |||
98 | state->auth_state = AUTH_STATE_VALIDATING; | 102 | state->auth_state = AUTH_STATE_VALIDATING; |
99 | damage_state(state); | 103 | damage_state(state); |
100 | while (wl_display_dispatch(state->display) != -1 && state->run_display) { | 104 | while (wl_display_dispatch(state->display) != -1 && state->run_display) { |
diff --git a/swaylock/render.c b/swaylock/render.c index ea23d0d8..66c55965 100644 --- a/swaylock/render.c +++ b/swaylock/render.c | |||
@@ -7,11 +7,22 @@ | |||
7 | #include "swaylock/swaylock.h" | 7 | #include "swaylock/swaylock.h" |
8 | 8 | ||
9 | #define M_PI 3.14159265358979323846 | 9 | #define M_PI 3.14159265358979323846 |
10 | const int ARC_RADIUS = 50; | ||
11 | const int ARC_THICKNESS = 10; | ||
12 | const float TYPE_INDICATOR_RANGE = M_PI / 3.0f; | 10 | const float TYPE_INDICATOR_RANGE = M_PI / 3.0f; |
13 | const float TYPE_INDICATOR_BORDER_THICKNESS = M_PI / 128.0f; | 11 | const float TYPE_INDICATOR_BORDER_THICKNESS = M_PI / 128.0f; |
14 | 12 | ||
13 | static void set_color_for_state(cairo_t *cairo, struct swaylock_state *state, | ||
14 | struct swaylock_colorset *colorset) { | ||
15 | if (state->auth_state == AUTH_STATE_VALIDATING) { | ||
16 | cairo_set_source_u32(cairo, colorset->verifying); | ||
17 | } else if (state->auth_state == AUTH_STATE_INVALID) { | ||
18 | cairo_set_source_u32(cairo, colorset->wrong); | ||
19 | } else if (state->auth_state == AUTH_STATE_CLEAR) { | ||
20 | cairo_set_source_u32(cairo, colorset->cleared); | ||
21 | } else { | ||
22 | cairo_set_source_u32(cairo, colorset->input); | ||
23 | } | ||
24 | } | ||
25 | |||
15 | void render_frame(struct swaylock_surface *surface) { | 26 | void render_frame(struct swaylock_surface *surface) { |
16 | struct swaylock_state *state = surface->state; | 27 | struct swaylock_state *state = surface->state; |
17 | 28 | ||
@@ -33,7 +44,7 @@ void render_frame(struct swaylock_surface *surface) { | |||
33 | cairo_save(cairo); | 44 | cairo_save(cairo); |
34 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | 45 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); |
35 | if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR || !surface->image) { | 46 | if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR || !surface->image) { |
36 | cairo_set_source_u32(cairo, state->args.color); | 47 | cairo_set_source_u32(cairo, state->args.colors.background); |
37 | cairo_paint(cairo); | 48 | cairo_paint(cairo); |
38 | } else { | 49 | } else { |
39 | render_background_image(cairo, surface->image, | 50 | render_background_image(cairo, surface->image, |
@@ -42,49 +53,25 @@ void render_frame(struct swaylock_surface *surface) { | |||
42 | cairo_restore(cairo); | 53 | cairo_restore(cairo); |
43 | cairo_identity_matrix(cairo); | 54 | cairo_identity_matrix(cairo); |
44 | 55 | ||
45 | int arc_radius = ARC_RADIUS * surface->scale; | 56 | int arc_radius = state->args.radius * surface->scale; |
46 | int arc_thickness = ARC_THICKNESS * surface->scale; | 57 | int arc_thickness = state->args.thickness * surface->scale; |
47 | float type_indicator_border_thickness = | 58 | float type_indicator_border_thickness = |
48 | TYPE_INDICATOR_BORDER_THICKNESS * surface->scale; | 59 | TYPE_INDICATOR_BORDER_THICKNESS * surface->scale; |
49 | 60 | ||
50 | if (state->args.show_indicator && state->auth_state != AUTH_STATE_IDLE) { | 61 | if (state->args.show_indicator && state->auth_state != AUTH_STATE_IDLE) { |
51 | // Draw circle | 62 | // Draw circle |
52 | cairo_set_line_width(cairo, arc_thickness); | 63 | cairo_set_line_width(cairo, arc_thickness); |
53 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, arc_radius, 0, 2 * M_PI); | 64 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, arc_radius, |
54 | switch (state->auth_state) { | 65 | 0, 2 * M_PI); |
55 | case AUTH_STATE_INPUT: | 66 | set_color_for_state(cairo, state, &state->args.colors.inside); |
56 | case AUTH_STATE_INPUT_NOP: | 67 | cairo_fill_preserve(cairo); |
57 | case AUTH_STATE_BACKSPACE: { | 68 | set_color_for_state(cairo, state, &state->args.colors.ring); |
58 | cairo_set_source_rgba(cairo, 0, 0, 0, 0.75); | 69 | cairo_stroke(cairo); |
59 | cairo_fill_preserve(cairo); | ||
60 | cairo_set_source_rgb(cairo, 51.0 / 255, 125.0 / 255, 0); | ||
61 | cairo_stroke(cairo); | ||
62 | } break; | ||
63 | case AUTH_STATE_VALIDATING: { | ||
64 | cairo_set_source_rgba(cairo, 0, 114.0 / 255, 255.0 / 255, 0.75); | ||
65 | cairo_fill_preserve(cairo); | ||
66 | cairo_set_source_rgb(cairo, 51.0 / 255, 0, 250.0 / 255); | ||
67 | cairo_stroke(cairo); | ||
68 | } break; | ||
69 | case AUTH_STATE_INVALID: { | ||
70 | cairo_set_source_rgba(cairo, 250.0 / 255, 0, 0, 0.75); | ||
71 | cairo_fill_preserve(cairo); | ||
72 | cairo_set_source_rgb(cairo, 125.0 / 255, 51.0 / 255, 0); | ||
73 | cairo_stroke(cairo); | ||
74 | } break; | ||
75 | case AUTH_STATE_CLEAR: { | ||
76 | cairo_set_source_rgba(cairo, 229.0/255, 164.0/255, 69.0/255, 0.75); | ||
77 | cairo_fill_preserve(cairo); | ||
78 | cairo_set_source_rgb(cairo, 229.0/255, 164.0/255, 69.0/255); | ||
79 | cairo_stroke(cairo); | ||
80 | } break; | ||
81 | default: break; | ||
82 | } | ||
83 | 70 | ||
84 | // Draw a message | 71 | // Draw a message |
85 | char *text = NULL; | 72 | char *text = NULL; |
86 | cairo_set_source_rgb(cairo, 0, 0, 0); | 73 | set_color_for_state(cairo, state, &state->args.colors.text); |
87 | cairo_select_font_face(cairo, "sans-serif", | 74 | cairo_select_font_face(cairo, state->args.font, |
88 | CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); | 75 | CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); |
89 | cairo_set_font_size(cairo, arc_radius / 3.0f); | 76 | cairo_set_font_size(cairo, arc_radius / 3.0f); |
90 | switch (state->auth_state) { | 77 | switch (state->auth_state) { |
@@ -101,9 +88,10 @@ void render_frame(struct swaylock_surface *surface) { | |||
101 | case AUTH_STATE_INPUT_NOP: | 88 | case AUTH_STATE_INPUT_NOP: |
102 | if (state->xkb.caps_lock) { | 89 | if (state->xkb.caps_lock) { |
103 | text = "Caps Lock"; | 90 | text = "Caps Lock"; |
104 | cairo_set_source_rgb(cairo, 229.0/255, 164.0/255, 69.0/255); | ||
105 | } | 91 | } |
106 | default: break; | 92 | break; |
93 | default: | ||
94 | break; | ||
107 | } | 95 | } |
108 | 96 | ||
109 | if (text) { | 97 | if (text) { |
@@ -131,14 +119,14 @@ void render_frame(struct swaylock_surface *surface) { | |||
131 | arc_radius, highlight_start, | 119 | arc_radius, highlight_start, |
132 | highlight_start + TYPE_INDICATOR_RANGE); | 120 | highlight_start + TYPE_INDICATOR_RANGE); |
133 | if (state->auth_state == AUTH_STATE_INPUT) { | 121 | if (state->auth_state == AUTH_STATE_INPUT) { |
134 | cairo_set_source_rgb(cairo, 51.0 / 255, 219.0 / 255, 0); | 122 | cairo_set_source_u32(cairo, state->args.colors.key_highlight); |
135 | } else { | 123 | } else { |
136 | cairo_set_source_rgb(cairo, 219.0 / 255, 51.0 / 255, 0); | 124 | cairo_set_source_u32(cairo, state->args.colors.bs_highlight); |
137 | } | 125 | } |
138 | cairo_stroke(cairo); | 126 | cairo_stroke(cairo); |
139 | 127 | ||
140 | // Draw borders | 128 | // Draw borders |
141 | cairo_set_source_rgb(cairo, 0, 0, 0); | 129 | cairo_set_source_u32(cairo, state->args.colors.separator); |
142 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, | 130 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, |
143 | arc_radius, highlight_start, | 131 | arc_radius, highlight_start, |
144 | highlight_start + type_indicator_border_thickness); | 132 | highlight_start + type_indicator_border_thickness); |
@@ -152,7 +140,7 @@ void render_frame(struct swaylock_surface *surface) { | |||
152 | } | 140 | } |
153 | 141 | ||
154 | // Draw inner + outer border of the circle | 142 | // Draw inner + outer border of the circle |
155 | cairo_set_source_rgb(cairo, 0, 0, 0); | 143 | set_color_for_state(cairo, state, &state->args.colors.line); |
156 | cairo_set_line_width(cairo, 2.0 * surface->scale); | 144 | cairo_set_line_width(cairo, 2.0 * surface->scale); |
157 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, | 145 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, |
158 | arc_radius - arc_thickness / 2, 0, 2 * M_PI); | 146 | arc_radius - arc_thickness / 2, 0, 2 * M_PI); |
diff --git a/swaylock/swaylock.1.scd b/swaylock/swaylock.1.scd index 1b3366f0..eea62c2a 100644 --- a/swaylock/swaylock.1.scd +++ b/swaylock/swaylock.1.scd | |||
@@ -12,23 +12,25 @@ Locks your Wayland session. | |||
12 | 12 | ||
13 | # OPTIONS | 13 | # OPTIONS |
14 | 14 | ||
15 | *-h, --help* | ||
16 | Show help message and quit. | ||
17 | |||
18 | *-c, --color* <rrggbb[aa]> | 15 | *-c, --color* <rrggbb[aa]> |
19 | Turn the screen into the given color. If -i is used, this sets the | 16 | Turn the screen into the given color. If -i is used, this sets the |
20 | background of the image to the given color. Defaults to white (FFFFFF), or | 17 | background of the image to the given color. Defaults to white (FFFFFF), or |
21 | transparent (00000000) if an image is in use. | 18 | transparent (00000000) if an image is in use. |
22 | 19 | ||
20 | *-e, --ignore-empty-password* | ||
21 | When an empty password is provided by the user, do not validate it. | ||
22 | |||
23 | *-f, --daemonize* | 23 | *-f, --daemonize* |
24 | Fork into the background after spawning. Note: this is the default behavior | 24 | Detach from the controlling terminal after locking. |
25 | of i3lock. | 25 | |
26 | *-h, --help* | ||
27 | Show help message and quit. | ||
26 | 28 | ||
27 | *-i, --image* [<output>:]<path> | 29 | *-i, --image* [<output>:]<path> |
28 | Display the given image, optionally only on the given output. Use -c to set | 30 | Display the given image, optionally only on the given output. Use -c to set |
29 | a background color. | 31 | a background color. |
30 | 32 | ||
31 | *--scaling* | 33 | *-s, --scaling* |
32 | Scaling mode for images: _stretch_, _fill_, _fit_, _center_, or _tile_. | 34 | Scaling mode for images: _stretch_, _fill_, _fit_, _center_, or _tile_. |
33 | 35 | ||
34 | *-t, --tiling* | 36 | *-t, --tiling* |
@@ -37,37 +39,57 @@ Locks your Wayland session. | |||
37 | *-u, --no-unlock-indicator* | 39 | *-u, --no-unlock-indicator* |
38 | Disable the unlock indicator. | 40 | Disable the unlock indicator. |
39 | 41 | ||
40 | *-f, --daemonize* | ||
41 | Detach from the controlling terminal after locking. | ||
42 | |||
43 | *-v, --version* | 42 | *-v, --version* |
44 | Show the version number and quit. | 43 | Show the version number and quit. |
45 | 44 | ||
46 | # APPEARANCE | 45 | # APPEARANCE |
47 | 46 | ||
48 | *--bshlcolor* <rrggbb[aa]> | 47 | *--bs-hl-color* <rrggbb[aa]> |
49 | Sets the color of backspace highlight segments. | 48 | Sets the color of backspace highlight segments. |
50 | 49 | ||
51 | *--font* <font> | 50 | *--font* <font> |
52 | Sets the font of the text inside the indicator. | 51 | Sets the font of the text inside the indicator. |
53 | 52 | ||
54 | *--insidecolor* <rrggbb[aa]> | 53 | *--indicator-radius* <radius> |
54 | Sets the radius of the indicator to _radius_ pixels. The default value is | ||
55 | 50. | ||
56 | |||
57 | *--indicator-thickness* <thickness> | ||
58 | Sets the thickness of the indicator to _thickness_ pixels. The default value | ||
59 | is 10. | ||
60 | |||
61 | *--inside-color* <rrggbb[aa]> | ||
55 | Sets the color of the inside of the indicator when typing or idle. | 62 | Sets the color of the inside of the indicator when typing or idle. |
56 | 63 | ||
57 | *--insidevercolor* <rrggbb[aa]> | 64 | *--inside-clear-color* <rrggbb[aa]> |
65 | Sets the color of the inside of the indicator when cleared. | ||
66 | |||
67 | *--inside-ver-color* <rrggbb[aa]> | ||
58 | Sets the color of the inside of the indicator when verifying. | 68 | Sets the color of the inside of the indicator when verifying. |
59 | 69 | ||
60 | *--insidewrongcolor* <rrggbb[aa]> | 70 | *--inside-wrong-color* <rrggbb[aa]> |
61 | Sets the color of the inside of the indicator when invalid. | 71 | Sets the color of the inside of the indicator when invalid. |
62 | 72 | ||
63 | *--keyhlcolor* <rrggbb[aa]> | 73 | *--key-hl-color* <rrggbb[aa]> |
64 | Sets the color of keypress highlight segments. | 74 | Sets the color of key press highlight segments. |
75 | |||
76 | *--line-color* <rrggbb[aa]> | ||
77 | Sets the color of the lines that separate the inside and outside of the | ||
78 | indicator when typing or idle. | ||
79 | |||
80 | *--line-clear-color* <rrggbb[aa]> | ||
81 | Sets the color of the lines that separate the inside and outside of the | ||
82 | indicator when cleared. | ||
83 | |||
84 | *--line-ver-color* <rrggbb[aa]> | ||
85 | Sets the color of the lines that separate the inside and outside of the | ||
86 | indicator when verifying. | ||
65 | 87 | ||
66 | *--linecolor* <rrggbb[aa]> | 88 | *--line-wrong-color* <rrggbb[aa]> |
67 | Sets the color of the lines that separate the inside and outside of the | 89 | Sets the color of the lines that separate the inside and outside of the |
68 | indicator. | 90 | indicator when invalid. |
69 | 91 | ||
70 | *-s, --line-uses-inside* | 92 | *-n, --line-uses-inside* |
71 | Use the color of the inside of the indicator for the line separating the | 93 | Use the color of the inside of the indicator for the line separating the |
72 | inside and outside of the indicator. | 94 | inside and outside of the indicator. |
73 | 95 | ||
@@ -75,28 +97,32 @@ Locks your Wayland session. | |||
75 | Use the outer ring's color for the line separating the inside and outside of | 97 | Use the outer ring's color for the line separating the inside and outside of |
76 | the indicator. | 98 | the indicator. |
77 | 99 | ||
78 | *--ringcolor* <rrggbb[aa]> | 100 | *--ring-color* <rrggbb[aa]> |
79 | Sets the color of the outside of the indicator when typing or idle. | 101 | Sets the color of the outside of the indicator when typing or idle. |
80 | 102 | ||
81 | *--ringvercolor* <rrggbb[aa]> | 103 | *--ring-clear-color* <rrggbb[aa]> |
104 | Sets the color of the outside of the indicator when cleared. | ||
105 | |||
106 | *--ring-ver-color* <rrggbb[aa]> | ||
82 | Sets the color of the outside of the indicator when verifying. | 107 | Sets the color of the outside of the indicator when verifying. |
83 | 108 | ||
84 | *--ringwrongcolor* <rrggbb[aa]> | 109 | *--ring-wrong-color* <rrggbb[aa]> |
85 | Sets the color of the outside of the indicator when invalid. | 110 | Sets the color of the outside of the indicator when invalid. |
86 | 111 | ||
87 | *--separatorcolor* <rrggbb[aa]> | 112 | *--separator-color* <rrggbb[aa]> |
88 | Sets the color of the lines that seperate highlight segments. | 113 | Sets the color of the lines that separate highlight segments. |
89 | 114 | ||
90 | *--textcolor* <rrggbb[aa]> | 115 | *--text-color* <rrggbb[aa]> |
91 | Sets the color of the text inside the indicator. | 116 | Sets the color of the text inside the indicator when typing or idle. |
92 | 117 | ||
93 | *--indicator-radius* <radius> | 118 | *--text-clear-color* <rrggbb[aa]> |
94 | Sets the radius of the indicator to _radius_ pixels. The default value is | 119 | Sets the color of the text inside the indicator when cleared. |
95 | 50. | ||
96 | 120 | ||
97 | *--indicator-thickness* <thickness> | 121 | *--text-ver-color* <rrggbb[aa]> |
98 | Sets the thickness of the indicator to _thickness_ pixels. The default value | 122 | Sets the color of the text inside the indicator when verifying. |
99 | is 10. | 123 | |
124 | *--text-wrong-color* <rrggbb[aa]> | ||
125 | Sets the color of the text inside the indicator when invalid. | ||
100 | 126 | ||
101 | # AUTHORS | 127 | # AUTHORS |
102 | 128 | ||