diff --git a/i3lock-bash b/i3lock-bash index ce440740..3bd0e955 100644 --- a/i3lock-bash +++ b/i3lock-bash @@ -93,6 +93,10 @@ _i3lock() { "--bar-pos" "--bar-count" "--bar-total-width" + # Polygon indicator + "--polygon-sides" + "--polygon-offset" + "--polygon-highlight" # Extra configs "--redraw-thread" "--refresh-rate" diff --git a/i3lock-zsh b/i3lock-zsh index 14327765..dde6a6ab 100644 --- a/i3lock-zsh +++ b/i3lock-zsh @@ -93,6 +93,10 @@ _i3lock() { "--bar-pos[Sets the bar position]:pos:->bar_pos" "--bar-count[Sets the number of minibars to draw on each screen]:int:" "--bar-total-width[The total width of the bar]:float:" + # Polygon indicator + "--polygon-sides[Draws the indicator as a regular polygon]:int:" + "--polygon-offset[Rotates the indicator polygon]:float:" + "--polygon-highlight[Sets the polygon highlight mode]:mode:((0\:'random' 1\:'clockwise' 2\:'counterclockwise'))" # Extra configs "--redraw-thread[Starts a separate thread for redrawing the screen]" "--refresh-rate[The refresh rate of the indicator]:double:" diff --git a/i3lock.1 b/i3lock.1 index 2ef335d6..22805c29 100644 --- a/i3lock.1 +++ b/i3lock.1 @@ -444,6 +444,21 @@ Sets the number of minibars to draw on each screen. .B \-\-bar\-total\-width The total width of the bar. Can be an expression. +.TP +.B \-\-polygon\-sides=0 +If set to an integer greater then 2, draw the indicator as a regular polygon +instead of a circle. + +.TP +.B \-\-polygon\-offset=degrees\-as\-double +The angle to rotate the indicator polygon by. + +.TP +.B \-\-polygon\-highlight={0, 1, 2} +Sets the highlight mode when drawing the indicator as a polygon. 0 highlights a +random edge on each keypress, 1 highlights consecutive edges clockwise, 2 highlights +counterclockwise. Highlights reverse direction while backspacing. + .TP .B \-\-redraw\-thread Starts a separate thread for redrawing the screen. Potentially worse from a diff --git a/i3lock.c b/i3lock.c index 1435897b..203f8cad 100644 --- a/i3lock.c +++ b/i3lock.c @@ -294,6 +294,11 @@ char bar_width_expr[32] = ""; // empty string means full width based on bar orie bool bar_bidirectional = false; bool bar_reversed = false; +// Polygon indicator +int polygon_sides = 0; +double polygon_offset = 0; +int polygon_highlight = 0; + /* isutf, u8_dec © 2005 Jeff Bezanson, public domain */ #define isutf(c) (((c)&0xC0) != 0x80) @@ -1493,6 +1498,9 @@ int main(int argc, char *argv[]) { {"indicator", no_argument, NULL, 401}, {"radius", required_argument, NULL, 402}, {"ring-width", required_argument, NULL, 403}, + {"polygon-sides", required_argument, NULL, 404}, + {"polygon-offset", required_argument, NULL, 405}, + {"polygon-highlight", required_argument, NULL, 406}, // alignment {"time-align", required_argument, NULL, 500}, @@ -1810,6 +1818,30 @@ int main(int argc, char *argv[]) { fprintf(stderr, "ring-width must be a positive float; ignoring...\n"); ring_width = 7.0; } + break; + case 404: + arg = optarg; + if (sscanf(arg, "%d", &polygon_sides) != 1) + errx(1, "polygon-sides must be a number\n"); + if (polygon_sides < 3 && polygon_sides != 0) { + fprintf(stderr, "polygon-sides must be greater then 2 or 0; ignoring...\n"); + polygon_sides = 0; + } + break; + case 405: + arg = optarg; + if (sscanf(arg, "%lf", &polygon_offset) != 1) + errx(1, "polygon-offset must be a number\n"); + polygon_offset = polygon_offset * (M_PI / 180); + break; + case 406: + arg = optarg; + if (sscanf(arg, "%d", &polygon_highlight) != 1) + errx(1, "polygon-highlight must be a number\n"); + if (polygon_highlight < 0 || polygon_highlight > 2) { + fprintf(stderr, "polygon-highlight must be between 0 and 2; ignoring...\n"); + polygon_highlight = 0; + } break; // Alignment stuff diff --git a/unlock_indicator.c b/unlock_indicator.c index e10984a6..8c61eca2 100644 --- a/unlock_indicator.c +++ b/unlock_indicator.c @@ -247,6 +247,11 @@ extern char bar_width_expr[32]; extern bool bar_bidirectional; extern bool bar_reversed; +// Polygon indicator +extern int polygon_sides; +extern double polygon_offset; +extern int polygon_highlight; + static cairo_font_face_t *font_faces[6] = { NULL, NULL, @@ -518,12 +523,31 @@ static void draw_bar(cairo_t *ctx, double bar_x, double bar_y, double bar_width, cairo_restore(ctx); } +void draw_polygon(cairo_t *ctx, double center_x, double center_y, double radius, int points, int start, int end, double offset) { + int count = end - start; + + for (int v = 0; v < count + 1; v++) { + double theta = (start + v) * ((M_PI * 2) / points) + offset; + + int x = radius * cos(theta); + int y = radius * sin(theta); + + if (v == 0) + cairo_move_to(ctx, center_x + x, center_y + y); + else + cairo_line_to(ctx, center_x + x, center_y + y); + } +} + static void draw_indic(cairo_t *ctx, double ind_x, double ind_y) { if (unlock_indicator && (unlock_state >= STATE_KEY_PRESSED || auth_state > STATE_AUTH_IDLE || show_indicator)) { /* Draw a (centered) circle with transparent background. */ cairo_set_line_width(ctx, RING_WIDTH); - cairo_arc(ctx, ind_x, ind_y, BUTTON_RADIUS, 0, 2 * M_PI); + if (polygon_sides > 0) + draw_polygon(ctx, ind_x, ind_y, BUTTON_RADIUS, polygon_sides, 0, polygon_sides, polygon_offset); + else + cairo_arc(ctx, ind_x, ind_y, BUTTON_RADIUS, 0, 2 * M_PI); /* Use the appropriate color for the different PAM states * (currently verifying, wrong password, or default) */ @@ -593,15 +617,16 @@ static void draw_indic(cairo_t *ctx, double ind_x, double ind_y) { if (internal_line_source != 2) { //pretty sure this only needs drawn if it's being drawn over the inside? cairo_set_source_rgba(ctx, line16.red, line16.green, line16.blue, line16.alpha); cairo_set_line_width(ctx, 2.0); - cairo_arc(ctx, ind_x, ind_y, BUTTON_RADIUS - 5, 0, 2 * M_PI); + if (polygon_sides > 0) + draw_polygon(ctx, ind_x, ind_y, BUTTON_RADIUS - 5, polygon_sides, 0, polygon_sides, polygon_offset); + else + cairo_arc(ctx, ind_x, ind_y, BUTTON_RADIUS - 5, 0, 2 * M_PI); cairo_stroke(ctx); } if (unlock_state == STATE_KEY_ACTIVE || unlock_state == STATE_BACKSPACE_ACTIVE) { cairo_set_line_width(ctx, RING_WIDTH); cairo_new_sub_path(ctx); - double highlight_start = (rand() % (int)(2 * M_PI * 100)) / 100.0; - cairo_arc(ctx, ind_x, ind_y, BUTTON_RADIUS, - highlight_start, highlight_start + (M_PI / 3.0)); + if (unlock_state == STATE_KEY_ACTIVE) { /* For normal keys, we use a lighter green. */ cairo_set_source_rgba(ctx, keyhl16.red, keyhl16.green, keyhl16.blue, keyhl16.alpha); @@ -610,6 +635,23 @@ static void draw_indic(cairo_t *ctx, double ind_x, double ind_y) { cairo_set_source_rgba(ctx, bshl16.red, bshl16.green, bshl16.blue, bshl16.alpha); } + if (polygon_sides > 0) { + int highlight_start = 0; + if (polygon_highlight == 0) + highlight_start = rand() % polygon_sides; + else if(polygon_highlight == 1) + highlight_start = input_position % polygon_sides; + else if(polygon_highlight == 2) + highlight_start = -input_position % polygon_sides; + draw_polygon(ctx, ind_x, ind_y, BUTTON_RADIUS, polygon_sides, highlight_start, highlight_start+1, polygon_offset); + cairo_stroke(ctx); + return; + } + + double highlight_start = (rand() % (int)(2 * M_PI * 100)) / 100.0; + cairo_arc(ctx, ind_x, ind_y, BUTTON_RADIUS, + highlight_start, highlight_start + (M_PI / 3.0)); + cairo_stroke(ctx); /* Draw two little separators for the highlighted part of the