aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--swaybar/render.c174
1 files changed, 170 insertions, 4 deletions
diff --git a/swaybar/render.c b/swaybar/render.c
index 116cc595..faf17509 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -144,16 +144,21 @@ static void i3bar_block_unref_callback(void *data) {
static uint32_t render_status_block(cairo_t *cairo,
struct swaybar_output *output, struct i3bar_block *block, double *x,
- bool edge) {
+ bool edge, bool use_short_text) {
if (!block->full_text || !*block->full_text) {
return 0;
}
+ char* text = block->full_text;
+ if (use_short_text && block->short_text && *block->short_text) {
+ text = block->short_text;
+ }
+
struct swaybar_config *config = output->bar->config;
int text_width, text_height;
get_text_size(cairo, config->font, &text_width, &text_height, NULL,
- output->scale, block->markup, "%s", block->full_text);
+ output->scale, block->markup, "%s", text);
int margin = 3 * output->scale;
double ws_vertical_padding = config->status_padding * output->scale;
@@ -263,7 +268,7 @@ static uint32_t render_status_block(cairo_t *cairo,
color = block->urgent ? config->colors.urgent_workspace.text : color;
cairo_set_source_u32(cairo, color);
pango_printf(cairo, config->font, output->scale,
- block->markup, "%s", block->full_text);
+ block->markup, "%s", text);
x_pos += width;
if (block->border && block->border_right > 0) {
@@ -294,13 +299,174 @@ static uint32_t render_status_block(cairo_t *cairo,
return output->height;
}
+static void predict_status_block_pos(cairo_t *cairo,
+ struct swaybar_output *output, struct i3bar_block *block, double *x,
+ bool edge) {
+ if (!block->full_text || !*block->full_text) {
+ return;
+ }
+
+ struct swaybar_config *config = output->bar->config;
+
+ int text_width, text_height;
+ get_text_size(cairo, config->font, &text_width, &text_height, NULL,
+ output->scale, block->markup, "%s", block->full_text);
+
+ int margin = 3 * output->scale;
+ double ws_vertical_padding = config->status_padding * output->scale;
+
+ int width = text_width;
+
+ if (block->min_width_str) {
+ int w;
+ get_text_size(cairo, config->font, &w, NULL, NULL,
+ output->scale, block->markup, "%s", block->min_width_str);
+ block->min_width = w;
+ }
+ if (width < block->min_width) {
+ width = block->min_width;
+ }
+
+ double block_width = width;
+ uint32_t ideal_height = text_height + ws_vertical_padding * 2;
+ uint32_t ideal_surface_height = ideal_height / output->scale;
+ if (!output->bar->config->height &&
+ output->height < ideal_surface_height) {
+ return;
+ }
+
+ *x -= width;
+ if ((block->border || block->urgent) && block->border_left > 0) {
+ *x -= (block->border_left * output->scale + margin);
+ block_width += block->border_left * output->scale + margin;
+ }
+ if ((block->border || block->urgent) && block->border_right > 0) {
+ *x -= (block->border_right * output->scale + margin);
+ block_width += block->border_right * output->scale + margin;
+ }
+
+ int sep_width, sep_height;
+ int sep_block_width = block->separator_block_width;
+ if (!edge) {
+ if (config->sep_symbol) {
+ get_text_size(cairo, config->font, &sep_width, &sep_height, NULL,
+ output->scale, false, "%s", config->sep_symbol);
+ uint32_t _ideal_height = sep_height + ws_vertical_padding * 2;
+ uint32_t _ideal_surface_height = _ideal_height / output->scale;
+ if (!output->bar->config->height &&
+ output->height < _ideal_surface_height) {
+ return;
+ }
+ if (sep_width > sep_block_width) {
+ sep_block_width = sep_width + margin * 2;
+ }
+ }
+ *x -= sep_block_width;
+ } else if (config->status_edge_padding) {
+ *x -= config->status_edge_padding * output->scale;
+ }
+}
+
+static double predict_status_line_pos(cairo_t *cairo,
+ struct swaybar_output *output, double x) {
+ bool edge = x == output->width * output->scale;
+ struct i3bar_block *block;
+ wl_list_for_each(block, &output->bar->status->blocks, link) {
+ predict_status_block_pos(cairo, output, block, &x, edge);
+ edge = false;
+ }
+ return x;
+}
+
+static uint32_t predict_workspace_button_length(cairo_t *cairo,
+ struct swaybar_output *output,
+ struct swaybar_workspace *ws) {
+ struct swaybar_config *config = output->bar->config;
+
+ int text_width, text_height;
+ get_text_size(cairo, config->font, &text_width, &text_height, NULL,
+ output->scale, config->pango_markup, "%s", ws->label);
+
+ int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale;
+ int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale;
+ int border_width = BORDER_WIDTH * output->scale;
+
+ uint32_t ideal_height = ws_vertical_padding * 2 + text_height
+ + border_width * 2;
+ uint32_t ideal_surface_height = ideal_height / output->scale;
+ if (!output->bar->config->height &&
+ output->height < ideal_surface_height) {
+ return 0;
+ }
+
+ return ws_horizontal_padding * 2 + text_width + border_width * 2;
+}
+
+static uint32_t predict_workspace_buttons_length(cairo_t *cairo,
+ struct swaybar_output *output) {
+ uint32_t width = 0;
+ if (output->bar->config->workspace_buttons) {
+ struct swaybar_workspace *ws;
+ wl_list_for_each(ws, &output->workspaces, link) {
+ width += predict_workspace_button_length(cairo, output, ws);
+ }
+ }
+ return width;
+}
+
+static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo,
+ struct swaybar_output *output) {
+ const char *mode = output->bar->mode;
+ if (!mode) {
+ return 0;
+ }
+
+ struct swaybar_config *config = output->bar->config;
+
+ if (!config->binding_mode_indicator) {
+ return 0;
+ }
+
+ int text_width, text_height;
+ get_text_size(cairo, config->font, &text_width, &text_height, NULL,
+ output->scale, output->bar->mode_pango_markup,
+ "%s", mode);
+
+ int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale;
+ int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale;
+ int border_width = BORDER_WIDTH * output->scale;
+
+ uint32_t ideal_height = text_height + ws_vertical_padding * 2
+ + border_width * 2;
+ uint32_t ideal_surface_height = ideal_height / output->scale;
+ if (!output->bar->config->height &&
+ output->height < ideal_surface_height) {
+ return 0;
+ }
+ return text_width + ws_horizontal_padding * 2 + border_width * 2;
+}
+
static uint32_t render_status_line_i3bar(cairo_t *cairo,
struct swaybar_output *output, double *x) {
uint32_t max_height = 0;
bool edge = *x == output->width * output->scale;
struct i3bar_block *block;
+ bool use_short_text = false;
+
+ // TODO: Add margin here?
+ uint32_t reserved_width = predict_workspace_buttons_length(cairo, output) +
+ predict_binding_mode_indicator_length(cairo, output);
+
+ uint32_t predicted_full_pos =
+ predict_status_line_pos(cairo, output, *x);
+
+ if (predicted_full_pos < reserved_width) {
+ use_short_text = true;
+ }
+
wl_list_for_each(block, &output->bar->status->blocks, link) {
- uint32_t h = render_status_block(cairo, output, block, x, edge);
+ uint32_t h = render_status_block(cairo, output, block, x, edge,
+ use_short_text);
max_height = h > max_height ? h : max_height;
edge = false;
}