i3lock-color

The world's most popular non-default computer lockscreen.
Index Commits Files Refs README LICENSE
commit 4bc07d8ea5f767a914a513bb3ee5f71ae82358b2
parent 9f774c84bee64a9ab9210c9f364ce3116bf08050
Author: Rio6 <rio.liu@r26.me>
Date:   Sun, 24 Jan 2021 01:09:10 -0500

Implement bar-count to replace bar-width

And tried to make draw_bar less messy

Diffstat:
Mi3lock.c | 29++++++++++++++++++++---------
Mlock_bar.sh | 11++++-------
Munlock_indicator.c | 190+++++++++++++++++++++++++++++--------------------------------------------------
Munlock_indicator.h | 2+-
4 files changed, 95 insertions(+), 137 deletions(-)
diff --git a/i3lock.c b/i3lock.c
@@ -252,6 +252,7 @@ bool redraw_thread = false;
 #define BAR_DEFAULT 0
 #define BAR_REVERSED 1
 #define BAR_BIDIRECTIONAL 2
+#define BAR_MAX_COUNT 65536
 // experimental bar stuff
 bool bar_enabled = false;
 double *bar_heights = NULL;
@@ -259,8 +260,8 @@ double bar_step = 15;
 double bar_base_height = 25;
 double bar_periodic_step = 15;
 double max_bar_height = 25;
-int num_bars = 0;
-int bar_width = 150;
+int bar_count = 10;
+int bar_width = 0;
 int bar_orientation = BAR_FLAT;
 
 char bar_base_color[9] = "000000ff";
@@ -1512,6 +1513,7 @@ int main(int argc, char *argv[]) {
         {"bar-color", required_argument, NULL, 707},
         {"bar-periodic-step", required_argument, NULL, 708},
         {"bar-position", required_argument, NULL, 709},
+        {"bar-count", required_argument, NULL, 710},
 
         // misc.
         {"redraw-thread", no_argument, NULL, 900},
@@ -2006,7 +2008,7 @@ int main(int argc, char *argv[]) {
             case 702:
                 bar_width = atoi(optarg);
                 if (bar_width < 1) bar_width = 150;
-                // num_bars and bar_heights* initialized later when we grab display info
+                // bar_count and bar_heights* initialized later when we grab display info
                 break;
             case 703:
                 arg = optarg;
@@ -2048,6 +2050,10 @@ int main(int argc, char *argv[]) {
                     errx(1, "bar-position must be of the form [pos] with a max length of 31\n");
                 }
                 break;
+            case 710:
+                bar_count = atoi(optarg);
+                if (bar_count > BAR_MAX_COUNT) bar_count = BAR_MAX_COUNT;
+                break;
 
             // Misc
             case 900:
@@ -2194,13 +2200,18 @@ int main(int argc, char *argv[]) {
     last_resolution[0] = screen->width_in_pixels;
     last_resolution[1] = screen->height_in_pixels;
 
-    if (bar_enabled && bar_width > 0) {
-        int tmp = screen->width_in_pixels;
-        if (bar_orientation == BAR_VERT) tmp = screen->height_in_pixels;
-        num_bars = tmp / bar_width;
-        if (tmp % bar_width != 0) ++num_bars;
+    if (bar_width > 0) {
+        fprintf(stderr, "Warning: --bar-width is deprecated, use --bar-count instead\n");
+        if (bar_orientation == BAR_VERT)
+            bar_count = screen->height_in_pixels / bar_width;
+        else
+            bar_count = screen->width_in_pixels / bar_width;
+    }
 
-        bar_heights = (double*) calloc(num_bars, sizeof(double));
+    if (bar_enabled && bar_count > 0) {
+        bar_heights = (double*) calloc(bar_count, sizeof(double));
+    } else {
+        bar_enabled = false;
     }
 
     xcb_change_window_attributes(conn, screen->root, XCB_CW_EVENT_MASK,
diff --git a/lock_bar.sh b/lock_bar.sh
@@ -10,7 +10,7 @@ V='#bb00bbbb'  # verifying
 ./x86_64-pc-linux-gnu/i3lock \
 --blur 5 \
 --bar-indicator \
---bar-position h \
+--bar-position y+h \
 --bar-direction 1 \
 --bar-max-height 50 \
 --bar-base-width 50 \
@@ -18,12 +18,11 @@ V='#bb00bbbb'  # verifying
 --keyhlcolor 880088cc \
 --bar-periodic-step 50 \
 --bar-step 50 \
---bar-width 250 \
 --redraw-thread \
 \
 --clock \
 --force-clock \
---timepos 5:h-80 \
+--timepos x+5:y+h-80 \
 --timecolor 880088ff \
 --datepos tx:ty+15 \
 --datecolor 990099ff \
@@ -31,11 +30,9 @@ V='#bb00bbbb'  # verifying
 --time-align 1 \
 --ringvercolor 8800ff88 \
 --ringwrongcolor ff008888 \
---statuspos 5:h-16 \
+--statuspos x+5:y+h-16 \
 --verif-align 1 \
 --wrong-align 1 \
 --verifcolor ffffffff \
 --wrongcolor ffffffff \
---modifpos -50:-50 \
-\
---screen 1
+--modifpos -50:-50
diff --git a/unlock_indicator.c b/unlock_indicator.c
@@ -206,8 +206,7 @@ extern double bar_base_height;
 extern double bar_periodic_step;
 extern double max_bar_height;
 extern double bar_position;
-extern int num_bars;
-extern int bar_width;
+extern int bar_count;
 extern int bar_orientation;
 
 extern char bar_base_color[9];
@@ -316,118 +315,65 @@ static void draw_text(cairo_t *ctx, text_t text) {
     cairo_stroke(ctx);
 }
 
-static void draw_bar(cairo_t *ctx, double x, double y, double bar_offset) {
-    // oh boy, here we go!
-    // TODO: get this to play nicely with multiple monitors
-    // ideally it'd intelligently span both monitors
-    double width, height;
-    double back_x = 0, back_y = 0, back_x2 = 0, back_y2 = 0, back_width = 0, back_height = 0;
-    for (int i = 0; i < num_bars; ++i) {
-        double cur_bar_height = bar_heights[i];
-
-        if (cur_bar_height > 0) {
-            if (unlock_state == STATE_BACKSPACE_ACTIVE) {
-                cairo_set_source_rgba(ctx, bshl16.red, bshl16.green, bshl16.blue, bshl16.alpha);
-            } else {
-                cairo_set_source_rgba(ctx, keyhl16.red, keyhl16.green, keyhl16.blue, keyhl16.alpha);
-            }
-        } else {
-            switch (auth_state) {
-                case STATE_AUTH_VERIFY:
-                case STATE_AUTH_LOCK:
-                    cairo_set_source_rgba(ctx, ringver16.red, ringver16.green, ringver16.blue, ringver16.alpha);
-                    break;
-                case STATE_AUTH_WRONG:
-                case STATE_I3LOCK_LOCK_FAILED:
-                    cairo_set_source_rgba(ctx, ringwrong16.red, ringwrong16.green, ringwrong16.blue, ringwrong16.alpha);
-                    break;
-                default:
-                    cairo_set_source_rgba(ctx, bar16.red, bar16.green, bar16.blue, bar16.alpha);
-                    break;
-            }
-        }
+static void draw_single_bar(cairo_t *ctx, double pos, double offset, double width, double height) {
+    if (bar_reversed) {
+        offset -= height;
+    } else if (bar_bidirectional) {
+        offset -= height;
+        height *= 2;
+    }
 
-        if (bar_orientation == BAR_VERT) {
-            width = (cur_bar_height <= 0 ? bar_base_height : cur_bar_height);
-            height = bar_width;
-            x = bar_offset;
-            y = i * bar_width;
-            if (bar_reversed) {
-                x -= width;
-            } else if (bar_bidirectional) {
-                width = (cur_bar_height <= 0 ? bar_base_height : cur_bar_height * 2);
-                x = bar_offset - (width / 2) + (bar_base_height / 2);
-            }
-        } else {
-            width = bar_width;
-            height = (cur_bar_height <= 0 ? bar_base_height : cur_bar_height);
-            x = i * bar_width;
-            y = bar_offset;
-            if (bar_reversed) {
-                y -= height;
-            } else if (bar_bidirectional) {
-                height = (cur_bar_height <= 0 ? bar_base_height : cur_bar_height * 2);
-                y = bar_offset - (height / 2) + (bar_base_height / 2);
-            }
-        }
+    if (bar_orientation == BAR_VERT)
+        cairo_rectangle(ctx, offset, pos, height, width);
+    else
+        cairo_rectangle(ctx, pos, offset, width, height);
+    cairo_fill(ctx);
+}
 
-        if (cur_bar_height < bar_base_height && cur_bar_height > 0) {
-            if (bar_orientation == BAR_VERT) {
-                back_x = bar_offset + cur_bar_height;
-                back_y = y;
-                back_width = bar_base_height - cur_bar_height;
-                back_height = height;
-                if (bar_reversed) {
-                    back_x = bar_offset - bar_base_height;
-                } else if (bar_bidirectional) {
-                    back_x = bar_offset;
-                    back_y2 = y;
-                    back_width = (bar_base_height - (cur_bar_height * 2)) / 2;
-                    back_x2 = bar_offset + (cur_bar_height * 2) + back_width;
-                }
-            } else {
-                back_x = x;
-                back_y = bar_offset + cur_bar_height;
-                back_width = width;
-                back_height = bar_base_height - cur_bar_height;
-                if (bar_reversed) {
-                    back_y = bar_offset - bar_base_height;
-                } else if (bar_bidirectional) {
-                    back_x2 = x;
-                    back_y = bar_offset;
-                    back_height = (bar_base_height - (cur_bar_height * 2)) / 2;
-                    back_y2 = bar_offset + (cur_bar_height * 2) + back_height;
-                }
-            }
-        }
-        cairo_rectangle(ctx, x, y, width, height);
-        cairo_fill(ctx);
-        switch (auth_state) {
-            case STATE_AUTH_VERIFY:
-            case STATE_AUTH_LOCK:
-                cairo_set_source_rgba(ctx, ringver16.red, ringver16.green, ringver16.blue, ringver16.alpha);
-                break;
-            case STATE_AUTH_WRONG:
-            case STATE_I3LOCK_LOCK_FAILED:
-                cairo_set_source_rgba(ctx, ringwrong16.red, ringwrong16.green, ringwrong16.blue, ringwrong16.alpha);
-                break;
-            default:
-                cairo_set_source_rgba(ctx, bar16.red, bar16.green, bar16.blue, bar16.alpha);
-                break;
-        }
+static void draw_bar(cairo_t *ctx, double bar_offset, double screen_x, double screen_y, double screen_w, double screen_h) {
 
-        if (cur_bar_height > 0 && cur_bar_height < bar_base_height && ((bar_bidirectional && ((cur_bar_height * 2) < bar_base_height)) || (!bar_bidirectional && (cur_bar_height < bar_base_height)))) {
-            cairo_rectangle(ctx, back_x, back_y, back_width, back_height);
-            cairo_fill(ctx);
-            if (bar_bidirectional) {
-                cairo_rectangle(ctx, back_x2, back_y2, back_width, back_height);
-                cairo_fill(ctx);
-            }
-        }
+    switch (auth_state) {
+        case STATE_AUTH_VERIFY:
+        case STATE_AUTH_LOCK:
+            cairo_set_source_rgba(ctx, ringver16.red, ringver16.green, ringver16.blue, ringver16.alpha);
+            break;
+        case STATE_AUTH_WRONG:
+        case STATE_I3LOCK_LOCK_FAILED:
+            cairo_set_source_rgba(ctx, ringwrong16.red, ringwrong16.green, ringwrong16.blue, ringwrong16.alpha);
+            break;
+        default:
+            cairo_set_source_rgba(ctx, bar16.red, bar16.green, bar16.blue, bar16.alpha);
+            break;
     }
-    for (int i = 0; i < num_bars; ++i) {
-        if (bar_heights[i] > 0)
+
+    if (bar_orientation == BAR_VERT)
+        draw_single_bar(ctx, screen_y, bar_offset, screen_h, bar_base_height);
+    else
+        draw_single_bar(ctx, screen_x, bar_offset, screen_w, bar_base_height);
+
+    if (unlock_state == STATE_BACKSPACE_ACTIVE)
+        cairo_set_source_rgba(ctx, bshl16.red, bshl16.green, bshl16.blue, bshl16.alpha);
+    else
+        cairo_set_source_rgba(ctx, keyhl16.red, keyhl16.green, keyhl16.blue, keyhl16.alpha);
+
+    double bar_width, screen_pos;
+    if (bar_orientation == BAR_VERT) {
+        bar_width = screen_h / bar_count;
+        screen_pos = screen_y;
+    } else {
+        bar_width = screen_w / bar_count;
+        screen_pos = screen_x;
+    }
+
+    for (int i = 0; i < bar_count; ++i) {
+        double bar_height = bar_heights[i];
+        draw_single_bar(ctx, screen_pos + i * bar_width, bar_offset, bar_width, bar_height);
+    }
+
+    for (int i = 0; i < bar_count; ++i) {
+        if (bar_heights[i] > 0) {
             bar_heights[i] -= bar_periodic_step;
+        }
     }
 }
 
@@ -630,15 +576,15 @@ static void draw_elements(cairo_t *const ctx, DrawData const *const draw_data) {
         if (unlock_state == STATE_KEY_ACTIVE ||
             unlock_state == STATE_BACKSPACE_ACTIVE) {
             // note: might be biased to cause more hits on lower indices
-            // maybe see about doing ((double) rand() / RAND_MAX) * num_bars
-            int index = rand() % num_bars;
+            // maybe see about doing ((double) rand() / RAND_MAX) * bar_count
+            int index = rand() % bar_count;
             bar_heights[index] = max_bar_height;
             for (int i = 0; i < ((max_bar_height / bar_step) + 1); ++i) {
                 int low_ind = index - i;
                 while (low_ind < 0) {
-                    low_ind += num_bars;
+                    low_ind += bar_count;
                 }
-                int high_ind = (index + i) % num_bars;
+                int high_ind = (index + i) % bar_count;
                 int tmp_height = max_bar_height - (bar_step * i);
                 if (tmp_height < 0)
                     tmp_height = 0;
@@ -650,7 +596,7 @@ static void draw_elements(cairo_t *const ctx, DrawData const *const draw_data) {
                     break;
             }
         }
-        draw_bar(ctx, draw_data->bar_x, draw_data->bar_y, draw_data->bar_offset);
+        draw_bar(ctx, draw_data->bar_offset, draw_data->screen_x, draw_data->screen_y, draw_data->screen_w, draw_data->screen_h);
     }
 
     draw_text(ctx, draw_data->status_text);
@@ -914,6 +860,10 @@ void render_lock(uint32_t *resolution, xcb_drawable_t drawable) {
             height = xr_resolutions[current_screen].height / scaling_factor;
             screen_x = xr_resolutions[current_screen].x / scaling_factor;
             screen_y = xr_resolutions[current_screen].y / scaling_factor;
+            draw_data.screen_w = width;
+            draw_data.screen_h = height;
+            draw_data.screen_x = screen_x;
+            draw_data.screen_y = screen_y;
             if (te_ind_x_expr && te_ind_y_expr) {
                 draw_data.indicator_x = te_eval(te_ind_x_expr);
                 draw_data.indicator_y = te_eval(te_ind_y_expr);
@@ -921,8 +871,6 @@ void render_lock(uint32_t *resolution, xcb_drawable_t drawable) {
                 draw_data.indicator_x = screen_x + width / 2;
                 draw_data.indicator_y = screen_y + height / 2;
             }
-            draw_data.bar_x = draw_data.indicator_x - (button_diameter_physical / 2);
-            draw_data.bar_y = draw_data.indicator_y - (button_diameter_physical / 2);
             draw_data.bar_offset = te_eval(te_bar_expr);
             draw_data.time_text.x = te_eval(te_time_x_expr);
             draw_data.time_text.y = te_eval(te_time_y_expr);
@@ -954,7 +902,7 @@ void render_lock(uint32_t *resolution, xcb_drawable_t drawable) {
             draw_data.mod_text.y = te_eval(te_modif_y_expr);
 
             DEBUG("Indicator at %fx%f on screen %d\n", draw_data.indicator_x, draw_data.indicator_y, current_screen + 1);
-            DEBUG("Bar at %fx%f on screen %d\n", draw_data.bar_x, draw_data.bar_y, current_screen + 1);
+            DEBUG("Bar at %f on screen %d\n", draw_data.bar_offset, current_screen + 1);
             DEBUG("Time at %fx%f on screen %d\n", draw_data.time_text.x, draw_data.time_text.y, current_screen + 1);
             DEBUG("Date at %fx%f on screen %d\n", draw_data.date_text.x, draw_data.date_text.y, current_screen + 1);
             DEBUG("Layout at %fx%f on screen %d\n", draw_data.keylayout_text.x, draw_data.keylayout_text.y, current_screen + 1);
@@ -969,10 +917,12 @@ void render_lock(uint32_t *resolution, xcb_drawable_t drawable) {
          * hope for the best. */
         width = last_resolution[0] / scaling_factor;
         height = last_resolution[1] / scaling_factor;
+        draw_data.screen_w = width;
+        draw_data.screen_h = height;
+        draw_data.screen_x = 0;
+        draw_data.screen_y = 0;
         draw_data.indicator_x = width / 2;
         draw_data.indicator_y = height / 2;
-        draw_data.bar_x = draw_data.indicator_x - (button_diameter_physical / 2);
-        draw_data.bar_y = draw_data.indicator_y - (button_diameter_physical / 2);
 
         draw_data.time_text.x = te_eval(te_time_x_expr);
         draw_data.time_text.y = te_eval(te_time_y_expr);
@@ -1002,7 +952,7 @@ void render_lock(uint32_t *resolution, xcb_drawable_t drawable) {
         draw_data.mod_text.y = te_eval(te_modif_y_expr);
 
         DEBUG("Indicator at %fx%f\n", draw_data.indicator_x, draw_data.indicator_y);
-        DEBUG("Bar at %fx%f\n", draw_data.bar_x, draw_data.bar_y);
+        DEBUG("Bar at %f\n", draw_data.bar_offset);
         DEBUG("Time at %fx%f\n", draw_data.time_text.x, draw_data.time_text.y);
         DEBUG("Date at %fx%f\n", draw_data.date_text.x, draw_data.date_text.y);
         DEBUG("Layout at %fx%f\n", draw_data.keylayout_text.x, draw_data.keylayout_text.y);
diff --git a/unlock_indicator.h b/unlock_indicator.h
@@ -34,7 +34,7 @@ typedef struct {
 
     double indicator_x, indicator_y;
 
-    double bar_x, bar_y;
+    double screen_x, screen_y, screen_w, screen_h;
     double bar_offset;
 } DrawData;