diff options
Diffstat (limited to 'swaybar/render.c')
-rw-r--r-- | swaybar/render.c | 190 |
1 files changed, 105 insertions, 85 deletions
diff --git a/swaybar/render.c b/swaybar/render.c index 4ebf922e..55f680ed 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -1,5 +1,6 @@ #define _POSIX_C_SOURCE 200809L #include <assert.h> +#include <linux/input-event-codes.h> #include <limits.h> #include <stdlib.h> #include <stdint.h> @@ -14,6 +15,9 @@ #include "swaybar/ipc.h" #include "swaybar/render.h" #include "swaybar/status_line.h" +#if HAVE_TRAY +#include "swaybar/tray/tray.h" +#endif #include "wlr-layer-shell-unstable-v1-client-protocol.h" static const int WS_HORIZONTAL_PADDING = 5; @@ -32,7 +36,8 @@ static uint32_t render_status_line_error(cairo_t *cairo, cairo_set_source_u32(cairo, 0xFF0000FF); int margin = 3 * output->scale; - int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; + double ws_vertical_padding = + output->bar->config->status_padding * output->scale; char *font = output->bar->config->font; int text_width, text_height; @@ -41,7 +46,8 @@ static uint32_t render_status_line_error(cairo_t *cairo, uint32_t ideal_height = text_height + ws_vertical_padding * 2; uint32_t ideal_surface_height = ideal_height / output->scale; - if (output->height < ideal_surface_height) { + if (!output->bar->config->height && + output->height < ideal_surface_height) { return ideal_surface_height; } *x -= text_width + margin; @@ -68,12 +74,13 @@ static uint32_t render_status_line_text(cairo_t *cairo, get_text_size(cairo, config->font, &text_width, &text_height, NULL, output->scale, config->pango_markup, "%s", text); - int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; + double ws_vertical_padding = config->status_padding * output->scale; int margin = 3 * output->scale; uint32_t ideal_height = text_height + ws_vertical_padding * 2; uint32_t ideal_surface_height = ideal_height / output->scale; - if (output->height < ideal_surface_height) { + if (!output->bar->config->height && + output->height < ideal_surface_height) { return ideal_surface_height; } @@ -87,13 +94,24 @@ static uint32_t render_status_line_text(cairo_t *cairo, return output->height; } -static void render_sharp_line(cairo_t *cairo, uint32_t color, +static void render_sharp_rectangle(cairo_t *cairo, uint32_t color, double x, double y, double width, double height) { + cairo_save(cairo); cairo_set_source_u32(cairo, color); + cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); + cairo_rectangle(cairo, x, y, width, height); + cairo_fill(cairo); + cairo_restore(cairo); +} + +static void render_sharp_line(cairo_t *cairo, uint32_t color, + double x, double y, double width, double height) { if (width > 1 && height > 1) { - cairo_rectangle(cairo, x, y, width, height); - cairo_fill(cairo); + render_sharp_rectangle(cairo, color, x, y, width, height); } else { + cairo_save(cairo); + cairo_set_source_u32(cairo, color); + cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); if (width == 1) { x += 0.5; height += y; @@ -108,14 +126,17 @@ static void render_sharp_line(cairo_t *cairo, uint32_t color, cairo_set_line_width(cairo, 1.0); cairo_line_to(cairo, width, height); cairo_stroke(cairo); + cairo_restore(cairo); } } -static enum hotspot_event_handling block_hotspot_callback(struct swaybar_output *output, - int x, int y, enum x11_button button, void *data) { +static enum hotspot_event_handling block_hotspot_callback( + struct swaybar_output *output, struct swaybar_hotspot *hotspot, + int x, int y, uint32_t button, void *data) { struct i3bar_block *block = data; struct status_line *status = output->bar->status; - return i3bar_block_send_click(status, block, x, y, button); + return i3bar_block_send_click(status, block, x, y, x - hotspot->x, + y - hotspot->y, hotspot->width, hotspot->height, button); } static void i3bar_block_unref_callback(void *data) { @@ -136,7 +157,7 @@ static uint32_t render_status_block(cairo_t *cairo, output->scale, block->markup, "%s", block->full_text); int margin = 3 * output->scale; - int ws_vertical_padding = WS_VERTICAL_PADDING * 2; + double ws_vertical_padding = config->status_padding * output->scale; int width = text_width; if (width < block->min_width) { @@ -146,37 +167,40 @@ static uint32_t render_status_block(cairo_t *cairo, 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->height < ideal_surface_height) { + if (!output->bar->config->height && + output->height < ideal_surface_height) { return ideal_surface_height; } *x -= width; - if (block->border && block->border_left > 0) { - *x -= (block->border_left + margin); - block_width += block->border_left + margin; + 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->border_right > 0) { - *x -= (block->border_right + margin); - block_width += block->border_right + 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->height < _ideal_surface_height) { + if (!output->bar->config->height && + output->height < _ideal_surface_height) { return _ideal_surface_height; } - if (sep_width > block->separator_block_width) { - block->separator_block_width = sep_width + margin * 2; + if (sep_width > sep_block_width) { + sep_block_width = sep_width + margin * 2; } } - *x -= block->separator_block_width; - } else { - *x -= margin; + *x -= sep_block_width; + } else if (config->status_edge_padding) { + *x -= config->status_edge_padding * output->scale; } uint32_t height = output->height * output->scale; @@ -193,53 +217,55 @@ static uint32_t render_status_block(cairo_t *cairo, wl_list_insert(&output->hotspots, &hotspot->link); } - double pos = *x; - if (block->background) { - cairo_set_source_u32(cairo, block->background); - cairo_rectangle(cairo, pos - 0.5 * output->scale, - output->scale, width, height); - cairo_fill(cairo); + double x_pos = *x; + double y_pos = ws_vertical_padding; + double render_height = height - ws_vertical_padding * 2; + + uint32_t bg_color = block->urgent + ? config->colors.urgent_workspace.background : block->background; + if (bg_color) { + render_sharp_rectangle(cairo, bg_color, x_pos, y_pos, + block_width, render_height); } - if (block->border && block->border_top > 0) { - render_sharp_line(cairo, block->border, - pos - 0.5 * output->scale, output->scale, - block_width, block->border_top); + uint32_t border_color = block->urgent + ? config->colors.urgent_workspace.border : block->border; + if (border_color && block->border_top > 0) { + render_sharp_line(cairo, border_color, x_pos, y_pos, + block_width, block->border_top * output->scale); } - if (block->border && block->border_bottom > 0) { - render_sharp_line(cairo, block->border, - pos - 0.5 * output->scale, - height - output->scale - block->border_bottom, - block_width, block->border_bottom); + if (border_color && block->border_bottom > 0) { + render_sharp_line(cairo, border_color, x_pos, + y_pos + render_height - block->border_bottom * output->scale, + block_width, block->border_bottom * output->scale); } - if (block->border != 0 && block->border_left > 0) { - render_sharp_line(cairo, block->border, - pos - 0.5 * output->scale, output->scale, - block->border_left, height); - pos += block->border_left + margin; + if (border_color && block->border_left > 0) { + render_sharp_line(cairo, border_color, x_pos, y_pos, + block->border_left * output->scale, render_height); + x_pos += block->border_left * output->scale + margin; } double offset = 0; if (strncmp(block->align, "left", 5) == 0) { - offset = pos; + offset = x_pos; } else if (strncmp(block->align, "right", 5) == 0) { - offset = pos + width - text_width; + offset = x_pos + width - text_width; } else if (strncmp(block->align, "center", 6) == 0) { - offset = pos + (width - text_width) / 2; + offset = x_pos + (width - text_width) / 2; } cairo_move_to(cairo, offset, height / 2.0 - text_height / 2.0); uint32_t color = block->color ? *block->color : config->colors.statusline; + 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); - pos += width; + x_pos += width; if (block->border && block->border_right > 0) { - pos += margin; - render_sharp_line(cairo, block->border, - pos - 0.5 * output->scale, output->scale, - block->border_right, height); - pos += block->border_right; + x_pos += margin; + render_sharp_line(cairo, border_color, x_pos, y_pos, + block->border_right * output->scale, render_height); + x_pos += block->border_right * output->scale; } if (!edge && block->separator) { @@ -249,16 +275,14 @@ static uint32_t render_status_block(cairo_t *cairo, cairo_set_source_u32(cairo, config->colors.separator); } if (config->sep_symbol) { - offset = pos + (block->separator_block_width - sep_width) / 2; + offset = x_pos + (sep_block_width - sep_width) / 2; cairo_move_to(cairo, offset, height / 2.0 - sep_height / 2.0); pango_printf(cairo, config->font, output->scale, false, "%s", config->sep_symbol); } else { cairo_set_line_width(cairo, 1); - cairo_move_to(cairo, - pos + block->separator_block_width / 2, margin); - cairo_line_to(cairo, - pos + block->separator_block_width / 2, height - margin); + cairo_move_to(cairo, x_pos + sep_block_width / 2, margin); + cairo_line_to(cairo, x_pos + sep_block_width / 2, height - margin); cairo_stroke(cairo); } } @@ -268,7 +292,7 @@ static uint32_t render_status_block(cairo_t *cairo, static uint32_t render_status_line_i3bar(cairo_t *cairo, struct swaybar_output *output, double *x) { uint32_t max_height = 0; - bool edge = true; + bool edge = *x == output->width * output->scale; struct i3bar_block *block; wl_list_for_each(block, &output->bar->status->blocks, link) { uint32_t h = render_status_block(cairo, output, block, x, edge); @@ -314,7 +338,8 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, uint32_t ideal_height = text_height + ws_vertical_padding * 2 + border_width * 2; uint32_t ideal_surface_height = ideal_height / output->scale; - if (output->height < ideal_surface_height) { + if (!output->bar->config->height && + output->height < ideal_surface_height) { return ideal_surface_height; } uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; @@ -342,22 +367,10 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, return output->height; } -static const char *strip_workspace_number(const char *ws_name) { - size_t len = strlen(ws_name); - for (size_t i = 0; i < len; ++i) { - if (ws_name[i] < '0' || ws_name[i] > '9') { - if (':' == ws_name[i] && i < len - 1 && i > 0) { - return ws_name + i + 1; - } - return ws_name; - } - } - return ws_name; -} - -static enum hotspot_event_handling workspace_hotspot_callback(struct swaybar_output *output, - int x, int y, enum x11_button button, void *data) { - if (button != LEFT) { +static enum hotspot_event_handling workspace_hotspot_callback( + struct swaybar_output *output, struct swaybar_hotspot *hotspot, + int x, int y, uint32_t button, void *data) { + if (button != BTN_LEFT) { return HOTSPOT_PROCESS; } ipc_send_workspace_command(output->bar, (const char *)data); @@ -368,11 +381,6 @@ static uint32_t render_workspace_button(cairo_t *cairo, struct swaybar_output *output, struct swaybar_workspace *ws, double *x) { struct swaybar_config *config = output->bar->config; - const char *name = ws->name; - if (config->strip_workspace_numbers) { - name = strip_workspace_number(ws->name); - } - struct box_colors box_colors; if (ws->urgent) { box_colors = config->colors.urgent_workspace; @@ -388,7 +396,7 @@ static uint32_t render_workspace_button(cairo_t *cairo, int text_width, text_height; get_text_size(cairo, config->font, &text_width, &text_height, NULL, - output->scale, config->pango_markup, "%s", name); + 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; @@ -397,7 +405,8 @@ static uint32_t render_workspace_button(cairo_t *cairo, uint32_t ideal_height = ws_vertical_padding * 2 + text_height + border_width * 2; uint32_t ideal_surface_height = ideal_height / output->scale; - if (output->height < ideal_surface_height) { + if (!output->bar->config->height && + output->height < ideal_surface_height) { return ideal_surface_height; } @@ -421,7 +430,7 @@ static uint32_t render_workspace_button(cairo_t *cairo, cairo_set_source_u32(cairo, box_colors.text); cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); pango_printf(cairo, config->font, output->scale, config->pango_markup, - "%s", name); + "%s", ws->label); struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); hotspot->x = *x; @@ -459,6 +468,12 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) { * utilize the available space. */ double x = output->width * output->scale; +#if HAVE_TRAY + if (bar->tray) { + uint32_t h = render_tray(cairo, output, &x); + max_height = h > max_height ? h : max_height; + } +#endif if (bar->status) { uint32_t h = render_status_line(cairo, output, &x); max_height = h > max_height ? h : max_height; @@ -518,12 +533,17 @@ void render_frame(struct swaybar_output *output) { cairo_restore(cairo); uint32_t height = render_to_cairo(cairo, output); int config_height = output->bar->config->height; - if (config_height >= 0 && height < (uint32_t)config_height) { + if (config_height > 0) { height = config_height; } if (height != output->height || output->width == 0) { // Reconfigure surface zwlr_layer_surface_v1_set_size(output->layer_surface, 0, height); + zwlr_layer_surface_v1_set_margin(output->layer_surface, + output->bar->config->gaps.top, + output->bar->config->gaps.right, + output->bar->config->gaps.bottom, + output->bar->config->gaps.left); if (strcmp(output->bar->config->mode, "dock") == 0) { zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, height); } |