diff --git a/i3lock.c b/i3lock.c index 33a04a8..d412c52 100644 --- 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; @@ -2047,6 +2049,10 @@ int main(int argc, char *argv[]) { if (sscanf(arg, "%31s", bar_expr) != 1) { 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 @@ -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 index 3214ff3..38fa185 100755 --- 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 index f0283b4..5809565 100644 --- 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; - } - } - - 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 (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; - } - - 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); - } - } +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; } - for (int i = 0; i < num_bars; ++i) { - if (bar_heights[i] > 0) + + if (bar_orientation == BAR_VERT) + cairo_rectangle(ctx, offset, pos, height, width); + else + cairo_rectangle(ctx, pos, offset, width, height); + cairo_fill(ctx); +} + +static void draw_bar(cairo_t *ctx, double bar_offset, double screen_x, double screen_y, double screen_w, double screen_h) { + + 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; + } + + 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 index eef3d96..c12a16a 100644 --- 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;