Merge pull request #197 from Rio6/bar-count

New --bar-count option to replace --bar-width
This commit is contained in:
Raymond Li 2021-02-15 01:05:51 -05:00 committed by GitHub
commit 1aa7edc7a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 121 additions and 136 deletions

View File

@ -10,7 +10,7 @@ V='#bb00bbbb' # verifying
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 @@ i3lock \
--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 @@ i3lock \
--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

View File

@ -404,6 +404,8 @@ Sets the direction the bars grow in. 0 is the default (downwards, or rightwards,
.TP
.B \-\-bar\-width=15
Deprecated, use \-\-bar\-count instead.
Sets the width of the minibars in the bar.
.TP
@ -438,6 +440,10 @@ The value by which the bars decrease each time the screen is redrawn.
Works similarly to the time/date/indicator expressions. If the bar is horizontal, this sets the vertical offset from the top edge.
If it's vertically oriented, this sets the horizontal offset from the left edge.
.TP
.B \-\-bar\-count=10
Sets the number of minibars to draw on each screen.
.TP
.B \-\-no\-verify
Do not verify the password entered by the user and unlock immediately.

View File

@ -262,20 +262,23 @@ pthread_t draw_thread;
// allow you to disable. handy if you use bar with lots of crap.
bool redraw_thread = false;
// experimental bar stuff
#define BAR_VERT 0
#define BAR_FLAT 1
#define BAR_DEFAULT 0
#define BAR_REVERSED 1
#define BAR_BIDIRECTIONAL 2
// experimental bar stuff
#define MAX_BAR_COUNT 65535
#define MIN_BAR_COUNT 2
bool bar_enabled = false;
double *bar_heights = NULL;
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 = 0;
int bar_width = 0;
int bar_orientation = BAR_FLAT;
char bar_base_color[9] = "000000ff";
@ -1544,6 +1547,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},
@ -2090,7 +2094,6 @@ 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
break;
case 703:
arg = optarg;
@ -2131,6 +2134,12 @@ 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 > MAX_BAR_COUNT || bar_count < MIN_BAR_COUNT) {
errx(1, "bar-count must be between %d and %d\n", MIN_BAR_COUNT, MAX_BAR_COUNT);
}
break;
// Misc
@ -2278,13 +2287,28 @@ 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_enabled) {
if (bar_count == 0) {
if (bar_width != 0) {
fprintf(stderr, "Warning: bar-width is deprecated, use bar-count instead\n");
int tmp = screen->width_in_pixels;
if (bar_orientation == BAR_VERT) tmp = screen->height_in_pixels;
bar_count = tmp / bar_width;
if (tmp % bar_width != 0) {
++bar_count;
}
} else {
bar_count = MIN_BAR_COUNT;
}
} else if (bar_width != 0) {
errx(EXIT_FAILURE, "bar-width and bar-count cannot be used at the same time");
}
bar_heights = (double*) calloc(num_bars, sizeof(double));
if (bar_count >= MIN_BAR_COUNT && bar_count <= MAX_BAR_COUNT) {
bar_heights = (double*) calloc(bar_count, sizeof(double));
} else {
bar_enabled = false;
}
}
xcb_change_window_attributes(conn, screen->root, XCB_CW_EVENT_MASK,

View File

@ -228,8 +228,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];
@ -342,119 +341,74 @@ 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];
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 / 2;
}
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)
cairo_rectangle(ctx, offset, pos, height, width);
else
cairo_rectangle(ctx, pos, offset, width, height);
cairo_fill(ctx);
}
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);
}
}
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 < 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;
}
cairo_save(ctx);
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;
}
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);
cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE);
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];
if (bar_bidirectional) bar_height *= 2;
if (bar_height > 0) {
draw_single_bar(ctx, screen_pos + i * bar_width, bar_offset, bar_width, bar_height);
}
}
for (int i = 0; i < num_bars; ++i) {
if (bar_heights[i] > 0)
for (int i = 0; i < bar_count; ++i) {
if (bar_heights[i] > 0) {
bar_heights[i] -= bar_periodic_step;
}
}
cairo_restore(ctx);
}
static void draw_indic(cairo_t *ctx, double ind_x, double ind_y) {
@ -663,15 +617,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;
@ -683,7 +637,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);
@ -971,6 +925,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);
@ -978,8 +936,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);
@ -1011,7 +967,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);
@ -1026,10 +982,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);
@ -1059,7 +1017,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);

View File

@ -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;