swaybar: separate adjacent borders

This commit decouples the surface height from the usable height, making it
possible to draw a separator between the workspace/mode and window borders
on top (for bottom bars) or bottom (for top bars). The workspace and mode
borders also get separated.

This behavior is consistent with i3bar.
This commit is contained in:
Konstantin Pospelov 2025-03-29 22:48:46 +01:00
parent 7e7994dbb2
commit 381c01a622
5 changed files with 85 additions and 67 deletions

View file

@ -53,6 +53,6 @@ struct swaybar_sni {
struct swaybar_sni *create_sni(char *id, struct swaybar_tray *tray); struct swaybar_sni *create_sni(char *id, struct swaybar_tray *tray);
void destroy_sni(struct swaybar_sni *sni); void destroy_sni(struct swaybar_sni *sni);
uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x, uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
struct swaybar_sni *sni); uint32_t height, struct swaybar_sni *sni);
#endif #endif

View file

@ -37,6 +37,7 @@ struct swaybar_tray {
struct swaybar_tray *create_tray(struct swaybar *bar); struct swaybar_tray *create_tray(struct swaybar *bar);
void destroy_tray(struct swaybar_tray *tray); void destroy_tray(struct swaybar_tray *tray);
void tray_in(int fd, short mask, void *data); void tray_in(int fd, short mask, void *data);
uint32_t render_tray(cairo_t *cairo, struct swaybar_output *output, double *x); uint32_t render_tray(cairo_t *cairo, struct swaybar_output *output,
double *x, uint32_t height);
#endif #endif

View file

@ -20,6 +20,7 @@
static const int WS_HORIZONTAL_PADDING = 5; static const int WS_HORIZONTAL_PADDING = 5;
static const double WS_VERTICAL_PADDING = 1.5; static const double WS_VERTICAL_PADDING = 1.5;
static const uint32_t WS_SEPARATOR = 1;
static const int BORDER_WIDTH = 1; static const int BORDER_WIDTH = 1;
struct render_context { struct render_context {
@ -46,15 +47,14 @@ static void choose_text_aa_mode(struct render_context *ctx, uint32_t fontcolor)
cairo_set_operator(ctx->cairo, op); cairo_set_operator(ctx->cairo, op);
} }
static uint32_t render_status_line_error(struct render_context *ctx, double *x) { static uint32_t render_status_line_error(struct render_context *ctx,
double *x, uint32_t height) {
struct swaybar_output *output = ctx->output; struct swaybar_output *output = ctx->output;
const char *error = output->bar->status->text; const char *error = output->bar->status->text;
if (!error) { if (!error) {
return 0; return 0;
} }
uint32_t height = output->height;
cairo_t *cairo = ctx->cairo; cairo_t *cairo = ctx->cairo;
cairo_set_source_u32(cairo, 0xFF0000FF); cairo_set_source_u32(cairo, 0xFF0000FF);
@ -69,7 +69,7 @@ static uint32_t render_status_line_error(struct render_context *ctx, double *x)
uint32_t ideal_height = text_height + ws_vertical_padding * 2; uint32_t ideal_height = text_height + ws_vertical_padding * 2;
uint32_t ideal_surface_height = ideal_height; uint32_t ideal_surface_height = ideal_height;
if (!output->bar->config->height && if (!output->bar->config->height &&
output->height < ideal_surface_height) { height < ideal_surface_height) {
return ideal_surface_height; return ideal_surface_height;
} }
*x -= text_width + margin; *x -= text_width + margin;
@ -79,10 +79,11 @@ static uint32_t render_status_line_error(struct render_context *ctx, double *x)
choose_text_aa_mode(ctx, 0xFF0000FF); choose_text_aa_mode(ctx, 0xFF0000FF);
render_text(cairo, font, 1, false, "%s", error); render_text(cairo, font, 1, false, "%s", error);
*x -= margin; *x -= margin;
return output->height; return height;
} }
static uint32_t render_status_line_text(struct render_context *ctx, double *x) { static uint32_t render_status_line_text(struct render_context *ctx,
double *x, uint32_t height) {
struct swaybar_output *output = ctx->output; struct swaybar_output *output = ctx->output;
const char *text = output->bar->status->text; const char *text = output->bar->status->text;
if (!text) { if (!text) {
@ -105,18 +106,17 @@ static uint32_t render_status_line_text(struct render_context *ctx, double *x) {
uint32_t ideal_height = text_height + ws_vertical_padding * 2; uint32_t ideal_height = text_height + ws_vertical_padding * 2;
uint32_t ideal_surface_height = ideal_height; uint32_t ideal_surface_height = ideal_height;
if (!output->bar->config->height && if (!output->bar->config->height &&
output->height < ideal_surface_height) { height < ideal_surface_height) {
return ideal_surface_height; return ideal_surface_height;
} }
*x -= text_width + margin; *x -= text_width + margin;
uint32_t height = output->height;
double text_y = height / 2.0 - text_height / 2.0; double text_y = height / 2.0 - text_height / 2.0;
cairo_move_to(cairo, *x, (int)floor(text_y)); cairo_move_to(cairo, *x, (int)floor(text_y));
choose_text_aa_mode(ctx, fontcolor); choose_text_aa_mode(ctx, fontcolor);
render_text(cairo, config->font_description, 1, config->pango_markup, "%s", text); render_text(cairo, config->font_description, 1, config->pango_markup, "%s", text);
*x -= margin; *x -= margin;
return output->height; return height;
} }
static void render_sharp_rectangle(cairo_t *cairo, uint32_t color, static void render_sharp_rectangle(cairo_t *cairo, uint32_t color,
@ -175,7 +175,8 @@ static void i3bar_block_unref_callback(void *data) {
} }
static uint32_t render_status_block(struct render_context *ctx, static uint32_t render_status_block(struct render_context *ctx,
struct i3bar_block *block, double *x, bool edge, bool use_short_text) { struct i3bar_block *block, double *x, uint32_t height, bool edge,
bool use_short_text) {
if (!block->full_text || !*block->full_text) { if (!block->full_text || !*block->full_text) {
return 0; return 0;
} }
@ -210,7 +211,7 @@ static uint32_t render_status_block(struct render_context *ctx,
uint32_t ideal_height = text_height + ws_vertical_padding * 2; uint32_t ideal_height = text_height + ws_vertical_padding * 2;
uint32_t ideal_surface_height = ideal_height; uint32_t ideal_surface_height = ideal_height;
if (!output->bar->config->height && if (!output->bar->config->height &&
output->height < ideal_surface_height) { height < ideal_surface_height) {
return ideal_surface_height; return ideal_surface_height;
} }
@ -233,7 +234,7 @@ static uint32_t render_status_block(struct render_context *ctx,
uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; uint32_t _ideal_height = sep_height + ws_vertical_padding * 2;
uint32_t _ideal_surface_height = _ideal_height; uint32_t _ideal_surface_height = _ideal_height;
if (!output->bar->config->height && if (!output->bar->config->height &&
output->height < _ideal_surface_height) { height < _ideal_surface_height) {
return _ideal_surface_height; return _ideal_surface_height;
} }
if (block->separator && sep_width > sep_block_width) { if (block->separator && sep_width > sep_block_width) {
@ -245,7 +246,6 @@ static uint32_t render_status_block(struct render_context *ctx,
*x -= config->status_edge_padding; *x -= config->status_edge_padding;
} }
uint32_t height = output->height;
if (output->bar->status->click_events) { if (output->bar->status->click_events) {
struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot));
hotspot->x = *x; hotspot->x = *x;
@ -341,12 +341,12 @@ static uint32_t render_status_block(struct render_context *ctx,
cairo_stroke(cairo); cairo_stroke(cairo);
} }
} }
return output->height; return height;
} }
static void predict_status_block_pos(cairo_t *cairo, static void predict_status_block_pos(cairo_t *cairo,
struct swaybar_output *output, struct i3bar_block *block, double *x, struct swaybar_output *output, struct i3bar_block *block, double *x,
bool edge) { uint32_t height, bool edge) {
if (!block->full_text || !*block->full_text) { if (!block->full_text || !*block->full_text) {
return; return;
} }
@ -375,7 +375,7 @@ static void predict_status_block_pos(cairo_t *cairo,
uint32_t ideal_height = text_height + ws_vertical_padding * 2; uint32_t ideal_height = text_height + ws_vertical_padding * 2;
uint32_t ideal_surface_height = ideal_height; uint32_t ideal_surface_height = ideal_height;
if (!output->bar->config->height && if (!output->bar->config->height &&
output->height < ideal_surface_height) { height < ideal_surface_height) {
return; return;
} }
@ -396,7 +396,7 @@ static void predict_status_block_pos(cairo_t *cairo,
uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; uint32_t _ideal_height = sep_height + ws_vertical_padding * 2;
uint32_t _ideal_surface_height = _ideal_height; uint32_t _ideal_surface_height = _ideal_height;
if (!output->bar->config->height && if (!output->bar->config->height &&
output->height < _ideal_surface_height) { height < _ideal_surface_height) {
return; return;
} }
if (sep_width > sep_block_width) { if (sep_width > sep_block_width) {
@ -410,11 +410,11 @@ static void predict_status_block_pos(cairo_t *cairo,
} }
static double predict_status_line_pos(cairo_t *cairo, static double predict_status_line_pos(cairo_t *cairo,
struct swaybar_output *output, double x) { struct swaybar_output *output, double x, uint32_t height) {
bool edge = x == output->width; bool edge = x == output->width;
struct i3bar_block *block; struct i3bar_block *block;
wl_list_for_each(block, &output->bar->status->blocks, link) { wl_list_for_each(block, &output->bar->status->blocks, link) {
predict_status_block_pos(cairo, output, block, &x, edge); predict_status_block_pos(cairo, output, block, &x, height, edge);
edge = false; edge = false;
} }
return x; return x;
@ -422,7 +422,8 @@ static double predict_status_line_pos(cairo_t *cairo,
static uint32_t predict_workspace_button_length(cairo_t *cairo, static uint32_t predict_workspace_button_length(cairo_t *cairo,
struct swaybar_output *output, struct swaybar_output *output,
struct swaybar_workspace *ws) { struct swaybar_workspace *ws,
uint32_t height) {
struct swaybar_config *config = output->bar->config; struct swaybar_config *config = output->bar->config;
int text_width, text_height; int text_width, text_height;
@ -437,7 +438,7 @@ static uint32_t predict_workspace_button_length(cairo_t *cairo,
+ border_width * 2; + border_width * 2;
uint32_t ideal_surface_height = ideal_height; uint32_t ideal_surface_height = ideal_height;
if (!output->bar->config->height && if (!output->bar->config->height &&
output->height < ideal_surface_height) { height < ideal_surface_height) {
return 0; return 0;
} }
@ -449,19 +450,19 @@ static uint32_t predict_workspace_button_length(cairo_t *cairo,
} }
static uint32_t predict_workspace_buttons_length(cairo_t *cairo, static uint32_t predict_workspace_buttons_length(cairo_t *cairo,
struct swaybar_output *output) { struct swaybar_output *output, uint32_t height) {
uint32_t width = 0; uint32_t width = 0;
if (output->bar->config->workspace_buttons) { if (output->bar->config->workspace_buttons) {
struct swaybar_workspace *ws; struct swaybar_workspace *ws;
wl_list_for_each(ws, &output->workspaces, link) { wl_list_for_each(ws, &output->workspaces, link) {
width += predict_workspace_button_length(cairo, output, ws); width += predict_workspace_button_length(cairo, output, ws, height);
} }
} }
return width; return width;
} }
static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo, static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo,
struct swaybar_output *output) { struct swaybar_output *output, uint32_t height) {
const char *mode = output->bar->mode; const char *mode = output->bar->mode;
if (!mode) { if (!mode) {
return 0; return 0;
@ -486,7 +487,7 @@ static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo,
+ border_width * 2; + border_width * 2;
uint32_t ideal_surface_height = ideal_height; uint32_t ideal_surface_height = ideal_height;
if (!output->bar->config->height && if (!output->bar->config->height &&
output->height < ideal_surface_height) { height < ideal_surface_height) {
return 0; return 0;
} }
uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2;
@ -496,7 +497,8 @@ static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo,
return width; return width;
} }
static uint32_t render_status_line_i3bar(struct render_context *ctx, double *x) { static uint32_t render_status_line_i3bar(struct render_context *ctx,
double *x, uint32_t height) {
struct swaybar_output *output = ctx->output; struct swaybar_output *output = ctx->output;
uint32_t max_height = 0; uint32_t max_height = 0;
bool edge = *x == output->width; bool edge = *x == output->width;
@ -505,19 +507,19 @@ static uint32_t render_status_line_i3bar(struct render_context *ctx, double *x)
cairo_t *cairo = ctx->cairo; cairo_t *cairo = ctx->cairo;
double reserved_width = double reserved_width =
predict_workspace_buttons_length(cairo, output) + predict_workspace_buttons_length(cairo, output, height) +
predict_binding_mode_indicator_length(cairo, output) + predict_binding_mode_indicator_length(cairo, output, height) +
3; // require a bit of space for margin 3; // require a bit of space for margin
double predicted_full_pos = double predicted_full_pos =
predict_status_line_pos(cairo, output, *x); predict_status_line_pos(cairo, output, *x, height);
if (predicted_full_pos < reserved_width) { if (predicted_full_pos < reserved_width) {
use_short_text = true; use_short_text = true;
} }
wl_list_for_each(block, &output->bar->status->blocks, link) { wl_list_for_each(block, &output->bar->status->blocks, link) {
uint32_t h = render_status_block(ctx, block, x, edge, uint32_t h = render_status_block(ctx, block, x, height, edge,
use_short_text); use_short_text);
max_height = h > max_height ? h : max_height; max_height = h > max_height ? h : max_height;
edge = false; edge = false;
@ -525,23 +527,25 @@ static uint32_t render_status_line_i3bar(struct render_context *ctx, double *x)
return max_height; return max_height;
} }
static uint32_t render_status_line(struct render_context *ctx, double *x) { static uint32_t render_status_line(struct render_context *ctx,
double *x, uint32_t height) {
struct status_line *status = ctx->output->bar->status; struct status_line *status = ctx->output->bar->status;
switch (status->protocol) { switch (status->protocol) {
case PROTOCOL_ERROR: case PROTOCOL_ERROR:
return render_status_line_error(ctx, x); return render_status_line_error(ctx, x, height);
case PROTOCOL_TEXT: case PROTOCOL_TEXT:
return render_status_line_text(ctx, x); return render_status_line_text(ctx, x, height);
case PROTOCOL_I3BAR: case PROTOCOL_I3BAR:
return render_status_line_i3bar(ctx, x); return render_status_line_i3bar(ctx, x, height);
case PROTOCOL_UNDEF: case PROTOCOL_UNDEF:
return 0; return 0;
} }
return 0; return 0;
} }
static struct box_size render_box(struct render_context *ctx, double x, static struct box_size render_box(struct render_context *ctx,
struct box_colors colors, const char *label, bool pango_markup) { double x, uint32_t height, struct box_colors colors,
const char *label, bool pango_markup) {
struct swaybar_output *output = ctx->output; struct swaybar_output *output = ctx->output;
struct swaybar_config *config = output->bar->config; struct swaybar_config *config = output->bar->config;
cairo_t *cairo = ctx->cairo; cairo_t *cairo = ctx->cairo;
@ -557,16 +561,14 @@ static struct box_size render_box(struct render_context *ctx, double x,
uint32_t ideal_height = text_height + WS_VERTICAL_PADDING * 2 uint32_t ideal_height = text_height + WS_VERTICAL_PADDING * 2
+ BORDER_WIDTH * 2; + BORDER_WIDTH * 2;
uint32_t ideal_surface_height = ideal_height;
if (!output->bar->config->height && if (!output->bar->config->height &&
output->height < ideal_surface_height) { height < ideal_height) {
return (struct box_size) { return (struct box_size) {
.width = width, .width = width + WS_SEPARATOR,
.height = ideal_surface_height, .height = ideal_height,
}; };
} }
uint32_t height = output->height;
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
cairo_set_source_u32(cairo, colors.background); cairo_set_source_u32(cairo, colors.background);
ctx->background_color = colors.background; ctx->background_color = colors.background;
@ -591,21 +593,22 @@ static struct box_size render_box(struct render_context *ctx, double x,
render_text(cairo, config->font_description, 1, pango_markup, render_text(cairo, config->font_description, 1, pango_markup,
"%s", label); "%s", label);
return (struct box_size) { return (struct box_size) {
.width = width, .width = width + WS_SEPARATOR,
.height = output->height, .height = height,
}; };
} }
static uint32_t render_binding_mode_indicator(struct render_context *ctx, static uint32_t render_binding_mode_indicator(struct render_context *ctx,
double x) { double x, uint32_t height) {
struct swaybar_output *output = ctx->output; struct swaybar_output *output = ctx->output;
const char *mode = output->bar->mode; const char *mode = output->bar->mode;
if (!mode) { if (!mode) {
return 0; return 0;
} }
struct box_size size = render_box(ctx, x, output->bar->config->colors.binding_mode, struct box_size size = render_box(ctx, x, height,
output->bar->config->colors.binding_mode,
mode, output->bar->mode_pango_markup); mode, output->bar->mode_pango_markup);
return size.height; return size.height;
} }
@ -626,7 +629,7 @@ static enum hotspot_event_handling workspace_hotspot_callback(
} }
static uint32_t render_workspace_button(struct render_context *ctx, static uint32_t render_workspace_button(struct render_context *ctx,
struct swaybar_workspace *ws, double *x) { struct swaybar_workspace *ws, double *x, uint32_t height) {
struct swaybar_output *output = ctx->output; struct swaybar_output *output = ctx->output;
struct swaybar_config *config = output->bar->config; struct swaybar_config *config = output->bar->config;
@ -641,7 +644,7 @@ static uint32_t render_workspace_button(struct render_context *ctx,
box_colors = config->colors.inactive_workspace; box_colors = config->colors.inactive_workspace;
} }
struct box_size size = render_box(ctx, *x, box_colors, struct box_size size = render_box(ctx, *x, height, box_colors,
ws->label, config->pango_markup); ws->label, config->pango_markup);
struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot));
@ -658,7 +661,7 @@ static uint32_t render_workspace_button(struct render_context *ctx,
return size.height; return size.height;
} }
static uint32_t render_to_cairo(struct render_context *ctx) { static uint32_t render_to_cairo(struct render_context *ctx, uint32_t height) {
cairo_t *cairo = ctx->cairo; cairo_t *cairo = ctx->cairo;
struct swaybar_output *output = ctx->output; struct swaybar_output *output = ctx->output;
struct swaybar *bar = output->bar; struct swaybar *bar = output->bar;
@ -667,6 +670,7 @@ static uint32_t render_to_cairo(struct render_context *ctx) {
int th; int th;
get_text_size(cairo, config->font_description, NULL, &th, NULL, 1, false, ""); get_text_size(cairo, config->font_description, NULL, &th, NULL, 1, false, "");
uint32_t max_height = (th + WS_VERTICAL_PADDING * 4); uint32_t max_height = (th + WS_VERTICAL_PADDING * 4);
/* /*
* Each render_* function takes the actual height of the bar, and returns * Each render_* function takes the actual height of the bar, and returns
* the ideal height. If the actual height is too short, the render function * the ideal height. If the actual height is too short, the render function
@ -677,28 +681,28 @@ static uint32_t render_to_cairo(struct render_context *ctx) {
double x = output->width; double x = output->width;
#if HAVE_TRAY #if HAVE_TRAY
if (bar->tray) { if (bar->tray) {
uint32_t h = render_tray(cairo, output, &x); uint32_t h = render_tray(cairo, output, &x, height);
max_height = h > max_height ? h : max_height; max_height = h > max_height ? h : max_height;
} }
#endif #endif
if (bar->status) { if (bar->status) {
uint32_t h = render_status_line(ctx, &x); uint32_t h = render_status_line(ctx, &x, height);
max_height = h > max_height ? h : max_height; max_height = h > max_height ? h : max_height;
} }
x = 0; x = 0;
if (config->workspace_buttons) { if (config->workspace_buttons) {
struct swaybar_workspace *ws; struct swaybar_workspace *ws;
wl_list_for_each(ws, &output->workspaces, link) { wl_list_for_each(ws, &output->workspaces, link) {
uint32_t h = render_workspace_button(ctx, ws, &x); uint32_t h = render_workspace_button(ctx, ws, &x, height);
max_height = h > max_height ? h : max_height; max_height = h > max_height ? h : max_height;
} }
} }
if (config->binding_mode_indicator) { if (config->binding_mode_indicator) {
uint32_t h = render_binding_mode_indicator(ctx, x); uint32_t h = render_binding_mode_indicator(ctx, x, height);
max_height = h > max_height ? h : max_height; max_height = h > max_height ? h : max_height;
} }
return max_height > output->height ? max_height : output->height; return max_height > height ? max_height : height;
} }
static void output_frame_handle_done(void *data, struct wl_callback *callback, static void output_frame_handle_done(void *data, struct wl_callback *callback,
@ -763,11 +767,23 @@ void render_frame(struct swaybar_output *output) {
cairo_set_source_u32(cairo, background_color); cairo_set_source_u32(cairo, background_color);
cairo_paint(cairo); cairo_paint(cairo);
uint32_t height = render_to_cairo(&ctx); // Render bottom bar lower to separate borders
if (output->bar->config->position & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM) {
cairo_translate(cairo, 0, WS_SEPARATOR);
}
// The output height is 0 if not configured
uint32_t usable_height = output->height >= WS_SEPARATOR ?
output->height - WS_SEPARATOR : output->height;
uint32_t height = render_to_cairo(&ctx, usable_height);
int config_height = output->bar->config->height; int config_height = output->bar->config->height;
if (config_height > 0) { if (config_height > 0) {
height = config_height; height = config_height;
} else {
height += WS_SEPARATOR;
} }
if (height != output->height || output->width == 0) { if (height != output->height || output->width == 0) {
// Reconfigure surface // Reconfigure surface
zwlr_layer_surface_v1_set_size(output->layer_surface, 0, height); zwlr_layer_surface_v1_set_size(output->layer_surface, 0, height);

View file

@ -458,10 +458,10 @@ static void reload_sni(struct swaybar_sni *sni, char *icon_theme,
} }
uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x, uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
struct swaybar_sni *sni) { uint32_t height, struct swaybar_sni *sni) {
uint32_t height = output->height * output->scale; uint32_t scaled_height = height * output->scale;
int padding = output->bar->config->tray_padding; int padding = output->bar->config->tray_padding;
int target_size = height - 2*padding; int target_size = scaled_height - 2*padding;
if (target_size != sni->target_size && sni_ready(sni)) { if (target_size != sni->target_size && sni_ready(sni)) {
// check if another icon should be loaded // check if another icon should be loaded
if (target_size < sni->min_size || target_size > sni->max_size) { if (target_size < sni->min_size || target_size > sni->max_size) {
@ -508,7 +508,7 @@ uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
int size = descaled_icon_size + 2 * descaled_padding; int size = descaled_icon_size + 2 * descaled_padding;
*x -= size; *x -= size;
int icon_y = floor((output->height - size) / 2.0); int icon_y = floor((height - size) / 2.0);
cairo_operator_t op = cairo_get_operator(cairo); cairo_operator_t op = cairo_get_operator(cairo);
cairo_set_operator(cairo, CAIRO_OPERATOR_OVER); cairo_set_operator(cairo, CAIRO_OPERATOR_OVER);
@ -532,11 +532,11 @@ uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
hotspot->x = *x; hotspot->x = *x;
hotspot->y = 0; hotspot->y = 0;
hotspot->width = size; hotspot->width = size;
hotspot->height = output->height; hotspot->height = height;
hotspot->callback = icon_hotspot_callback; hotspot->callback = icon_hotspot_callback;
hotspot->destroy = free; hotspot->destroy = free;
hotspot->data = strdup(sni->watcher_id); hotspot->data = strdup(sni->watcher_id);
wl_list_insert(&output->hotspots, &hotspot->link); wl_list_insert(&output->hotspots, &hotspot->link);
return output->height; return height;
} }

View file

@ -116,7 +116,8 @@ static int cmp_output(const void *item, const void *cmp_to) {
return strcmp(item, output->name); return strcmp(item, output->name);
} }
uint32_t render_tray(cairo_t *cairo, struct swaybar_output *output, double *x) { uint32_t render_tray(cairo_t *cairo, struct swaybar_output *output,
double *x, uint32_t height) {
struct swaybar_config *config = output->bar->config; struct swaybar_config *config = output->bar->config;
if (config->tray_outputs) { if (config->tray_outputs) {
if (list_seq_find(config->tray_outputs, cmp_output, output) == -1) { if (list_seq_find(config->tray_outputs, cmp_output, output) == -1) {
@ -124,14 +125,14 @@ uint32_t render_tray(cairo_t *cairo, struct swaybar_output *output, double *x) {
} }
} // else display on all } // else display on all
if ((int)(output->height * output->scale) <= 2 * config->tray_padding) { if ((int)(height * output->scale) <= 2 * config->tray_padding) {
return (2 * config->tray_padding + 1) / output->scale; return (2 * config->tray_padding + 1) / output->scale;
} }
uint32_t max_height = 0; uint32_t max_height = 0;
struct swaybar_tray *tray = output->bar->tray; struct swaybar_tray *tray = output->bar->tray;
for (int i = 0; i < tray->items->length; ++i) { for (int i = 0; i < tray->items->length; ++i) {
uint32_t h = render_sni(cairo, output, x, tray->items->items[i]); uint32_t h = render_sni(cairo, output, x, height, tray->items->items[i]);
if (h > max_height) { if (h > max_height) {
max_height = h; max_height = h;
} }