summaryrefslogtreecommitdiff
path: root/swaybar/render.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/render.c')
-rw-r--r--swaybar/render.c190
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);
}