aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/render.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/render.c')
-rw-r--r--swaybar/render.c81
1 files changed, 43 insertions, 38 deletions
diff --git a/swaybar/render.c b/swaybar/render.c
index 7e2f97b7..879a4e42 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -1,4 +1,3 @@
1#define _POSIX_C_SOURCE 200809L
2#include <assert.h> 1#include <assert.h>
3#include <linux/input-event-codes.h> 2#include <linux/input-event-codes.h>
4#include <limits.h> 3#include <limits.h>
@@ -62,7 +61,7 @@ static uint32_t render_status_line_error(struct render_context *ctx, double *x)
62 int margin = 3; 61 int margin = 3;
63 double ws_vertical_padding = output->bar->config->status_padding; 62 double ws_vertical_padding = output->bar->config->status_padding;
64 63
65 char *font = output->bar->config->font; 64 PangoFontDescription *font = output->bar->config->font_description;
66 int text_width, text_height; 65 int text_width, text_height;
67 get_text_size(cairo, font, &text_width, &text_height, NULL, 66 get_text_size(cairo, font, &text_width, &text_height, NULL,
68 1, false, "%s", error); 67 1, false, "%s", error);
@@ -97,7 +96,7 @@ static uint32_t render_status_line_text(struct render_context *ctx, double *x) {
97 cairo_set_source_u32(cairo, fontcolor); 96 cairo_set_source_u32(cairo, fontcolor);
98 97
99 int text_width, text_height; 98 int text_width, text_height;
100 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 99 get_text_size(cairo, config->font_description, &text_width, &text_height, NULL,
101 1, config->pango_markup, "%s", text); 100 1, config->pango_markup, "%s", text);
102 101
103 double ws_vertical_padding = config->status_padding; 102 double ws_vertical_padding = config->status_padding;
@@ -115,7 +114,7 @@ static uint32_t render_status_line_text(struct render_context *ctx, double *x) {
115 double text_y = height / 2.0 - text_height / 2.0; 114 double text_y = height / 2.0 - text_height / 2.0;
116 cairo_move_to(cairo, *x, (int)floor(text_y)); 115 cairo_move_to(cairo, *x, (int)floor(text_y));
117 choose_text_aa_mode(ctx, fontcolor); 116 choose_text_aa_mode(ctx, fontcolor);
118 render_text(cairo, config->font, 1, config->pango_markup, "%s", text); 117 render_text(cairo, config->font_description, 1, config->pango_markup, "%s", text);
119 *x -= margin; 118 *x -= margin;
120 return output->height; 119 return output->height;
121} 120}
@@ -160,7 +159,7 @@ static void render_sharp_line(cairo_t *cairo, uint32_t color,
160 159
161static enum hotspot_event_handling block_hotspot_callback( 160static enum hotspot_event_handling block_hotspot_callback(
162 struct swaybar_output *output, struct swaybar_hotspot *hotspot, 161 struct swaybar_output *output, struct swaybar_hotspot *hotspot,
163 double x, double y, uint32_t button, void *data) { 162 double x, double y, uint32_t button, bool released, void *data) {
164 struct i3bar_block *block = data; 163 struct i3bar_block *block = data;
165 struct status_line *status = output->bar->status; 164 struct status_line *status = output->bar->status;
166 return i3bar_block_send_click(status, block, x, y, 165 return i3bar_block_send_click(status, block, x, y,
@@ -168,7 +167,7 @@ static enum hotspot_event_handling block_hotspot_callback(
168 y - (double)hotspot->y, 167 y - (double)hotspot->y,
169 (double)hotspot->width, 168 (double)hotspot->width,
170 (double)hotspot->height, 169 (double)hotspot->height,
171 output->scale, button); 170 output->scale, button, released);
172} 171}
173 172
174static void i3bar_block_unref_callback(void *data) { 173static void i3bar_block_unref_callback(void *data) {
@@ -190,7 +189,7 @@ static uint32_t render_status_block(struct render_context *ctx,
190 struct swaybar_output *output = ctx->output; 189 struct swaybar_output *output = ctx->output;
191 struct swaybar_config *config = output->bar->config; 190 struct swaybar_config *config = output->bar->config;
192 int text_width, text_height; 191 int text_width, text_height;
193 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 1, 192 get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, 1,
194 block->markup, "%s", text); 193 block->markup, "%s", text);
195 194
196 int margin = 3; 195 int margin = 3;
@@ -199,7 +198,7 @@ static uint32_t render_status_block(struct render_context *ctx,
199 int width = text_width; 198 int width = text_width;
200 if (block->min_width_str) { 199 if (block->min_width_str) {
201 int w; 200 int w;
202 get_text_size(cairo, config->font, &w, NULL, NULL, 1, block->markup, 201 get_text_size(cairo, config->font_description, &w, NULL, NULL, 1, block->markup,
203 "%s", block->min_width_str); 202 "%s", block->min_width_str);
204 block->min_width = w; 203 block->min_width = w;
205 } 204 }
@@ -229,7 +228,7 @@ static uint32_t render_status_block(struct render_context *ctx,
229 int sep_block_width = block->separator_block_width; 228 int sep_block_width = block->separator_block_width;
230 if (!edge) { 229 if (!edge) {
231 if (config->sep_symbol) { 230 if (config->sep_symbol) {
232 get_text_size(cairo, config->font, &sep_width, &sep_height, NULL, 231 get_text_size(cairo, config->font_description, &sep_width, &sep_height, NULL,
233 1, false, "%s", config->sep_symbol); 232 1, false, "%s", config->sep_symbol);
234 uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; 233 uint32_t _ideal_height = sep_height + ws_vertical_padding * 2;
235 uint32_t _ideal_surface_height = _ideal_height; 234 uint32_t _ideal_surface_height = _ideal_height;
@@ -292,7 +291,7 @@ static uint32_t render_status_block(struct render_context *ctx,
292 } 291 }
293 292
294 double offset = 0; 293 double offset = 0;
295 if (strncmp(block->align, "left", 5) == 0) { 294 if (strncmp(block->align, "left", 4) == 0) {
296 offset = x_pos; 295 offset = x_pos;
297 } else if (strncmp(block->align, "right", 5) == 0) { 296 } else if (strncmp(block->align, "right", 5) == 0) {
298 offset = x_pos + width - text_width; 297 offset = x_pos + width - text_width;
@@ -307,7 +306,7 @@ static uint32_t render_status_block(struct render_context *ctx,
307 color = block->urgent ? config->colors.urgent_workspace.text : color; 306 color = block->urgent ? config->colors.urgent_workspace.text : color;
308 cairo_set_source_u32(cairo, color); 307 cairo_set_source_u32(cairo, color);
309 choose_text_aa_mode(ctx, color); 308 choose_text_aa_mode(ctx, color);
310 render_text(cairo, config->font, 1, block->markup, "%s", text); 309 render_text(cairo, config->font_description, 1, block->markup, "%s", text);
311 x_pos += width; 310 x_pos += width;
312 311
313 if (block->border_set || block->urgent) { 312 if (block->border_set || block->urgent) {
@@ -331,7 +330,7 @@ static uint32_t render_status_block(struct render_context *ctx,
331 double sep_y = height / 2.0 - sep_height / 2.0; 330 double sep_y = height / 2.0 - sep_height / 2.0;
332 cairo_move_to(cairo, offset, (int)floor(sep_y)); 331 cairo_move_to(cairo, offset, (int)floor(sep_y));
333 choose_text_aa_mode(ctx, color); 332 choose_text_aa_mode(ctx, color);
334 render_text(cairo, config->font, 1, false, 333 render_text(cairo, config->font_description, 1, false,
335 "%s", config->sep_symbol); 334 "%s", config->sep_symbol);
336 } else { 335 } else {
337 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); 336 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
@@ -354,7 +353,7 @@ static void predict_status_block_pos(cairo_t *cairo,
354 struct swaybar_config *config = output->bar->config; 353 struct swaybar_config *config = output->bar->config;
355 354
356 int text_width, text_height; 355 int text_width, text_height;
357 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 1, 356 get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, 1,
358 block->markup, "%s", block->full_text); 357 block->markup, "%s", block->full_text);
359 358
360 int margin = 3; 359 int margin = 3;
@@ -364,7 +363,7 @@ static void predict_status_block_pos(cairo_t *cairo,
364 363
365 if (block->min_width_str) { 364 if (block->min_width_str) {
366 int w; 365 int w;
367 get_text_size(cairo, config->font, &w, NULL, NULL, 366 get_text_size(cairo, config->font_description, &w, NULL, NULL,
368 1, block->markup, "%s", block->min_width_str); 367 1, block->markup, "%s", block->min_width_str);
369 block->min_width = w; 368 block->min_width = w;
370 } 369 }
@@ -391,7 +390,7 @@ static void predict_status_block_pos(cairo_t *cairo,
391 int sep_block_width = block->separator_block_width; 390 int sep_block_width = block->separator_block_width;
392 if (!edge) { 391 if (!edge) {
393 if (config->sep_symbol) { 392 if (config->sep_symbol) {
394 get_text_size(cairo, config->font, &sep_width, &sep_height, NULL, 393 get_text_size(cairo, config->font_description, &sep_width, &sep_height, NULL,
395 1, false, "%s", config->sep_symbol); 394 1, false, "%s", config->sep_symbol);
396 uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; 395 uint32_t _ideal_height = sep_height + ws_vertical_padding * 2;
397 uint32_t _ideal_surface_height = _ideal_height; 396 uint32_t _ideal_surface_height = _ideal_height;
@@ -426,7 +425,7 @@ static uint32_t predict_workspace_button_length(cairo_t *cairo,
426 struct swaybar_config *config = output->bar->config; 425 struct swaybar_config *config = output->bar->config;
427 426
428 int text_width, text_height; 427 int text_width, text_height;
429 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 1, 428 get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, 1,
430 config->pango_markup, "%s", ws->label); 429 config->pango_markup, "%s", ws->label);
431 430
432 int ws_vertical_padding = WS_VERTICAL_PADDING; 431 int ws_vertical_padding = WS_VERTICAL_PADDING;
@@ -474,7 +473,7 @@ static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo,
474 } 473 }
475 474
476 int text_width, text_height; 475 int text_width, text_height;
477 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 476 get_text_size(cairo, config->font_description, &text_width, &text_height, NULL,
478 1, output->bar->mode_pango_markup, 477 1, output->bar->mode_pango_markup,
479 "%s", mode); 478 "%s", mode);
480 479
@@ -551,7 +550,7 @@ static uint32_t render_binding_mode_indicator(struct render_context *ctx,
551 cairo_t *cairo = ctx->cairo; 550 cairo_t *cairo = ctx->cairo;
552 struct swaybar_config *config = output->bar->config; 551 struct swaybar_config *config = output->bar->config;
553 int text_width, text_height; 552 int text_width, text_height;
554 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 553 get_text_size(cairo, config->font_description, &text_width, &text_height, NULL,
555 1, output->bar->mode_pango_markup, 554 1, output->bar->mode_pango_markup,
556 "%s", mode); 555 "%s", mode);
557 556
@@ -592,17 +591,22 @@ static uint32_t render_binding_mode_indicator(struct render_context *ctx,
592 cairo_set_source_u32(cairo, config->colors.binding_mode.text); 591 cairo_set_source_u32(cairo, config->colors.binding_mode.text);
593 cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); 592 cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y));
594 choose_text_aa_mode(ctx, config->colors.binding_mode.text); 593 choose_text_aa_mode(ctx, config->colors.binding_mode.text);
595 render_text(cairo, config->font, 1, output->bar->mode_pango_markup, 594 render_text(cairo, config->font_description, 1, output->bar->mode_pango_markup,
596 "%s", mode); 595 "%s", mode);
597 return output->height; 596 return output->height;
598} 597}
599 598
600static enum hotspot_event_handling workspace_hotspot_callback( 599static enum hotspot_event_handling workspace_hotspot_callback(
601 struct swaybar_output *output, struct swaybar_hotspot *hotspot, 600 struct swaybar_output *output, struct swaybar_hotspot *hotspot,
602 double x, double y, uint32_t button, void *data) { 601 double x, double y, uint32_t button, bool released, void *data) {
603 if (button != BTN_LEFT) { 602 if (button != BTN_LEFT) {
604 return HOTSPOT_PROCESS; 603 return HOTSPOT_PROCESS;
605 } 604 }
605 if (released) {
606 // Since we handle the pressed event, also handle the released event
607 // to block it from falling through to a binding in the bar
608 return HOTSPOT_IGNORE;
609 }
606 ipc_send_workspace_command(output->bar, (const char *)data); 610 ipc_send_workspace_command(output->bar, (const char *)data);
607 return HOTSPOT_IGNORE; 611 return HOTSPOT_IGNORE;
608} 612}
@@ -626,7 +630,7 @@ static uint32_t render_workspace_button(struct render_context *ctx,
626 630
627 cairo_t *cairo = ctx->cairo; 631 cairo_t *cairo = ctx->cairo;
628 int text_width, text_height; 632 int text_width, text_height;
629 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 633 get_text_size(cairo, config->font_description, &text_width, &text_height, NULL,
630 1, config->pango_markup, "%s", ws->label); 634 1, config->pango_markup, "%s", ws->label);
631 635
632 int ws_vertical_padding = WS_VERTICAL_PADDING; 636 int ws_vertical_padding = WS_VERTICAL_PADDING;
@@ -666,7 +670,7 @@ static uint32_t render_workspace_button(struct render_context *ctx,
666 cairo_set_source_u32(cairo, box_colors.text); 670 cairo_set_source_u32(cairo, box_colors.text);
667 cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); 671 cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y));
668 choose_text_aa_mode(ctx, box_colors.text); 672 choose_text_aa_mode(ctx, box_colors.text);
669 render_text(cairo, config->font, 1, config->pango_markup, 673 render_text(cairo, config->font_description, 1, config->pango_markup,
670 "%s", ws->label); 674 "%s", ws->label);
671 675
672 struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); 676 struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot));
@@ -688,18 +692,9 @@ static uint32_t render_to_cairo(struct render_context *ctx) {
688 struct swaybar_output *output = ctx->output; 692 struct swaybar_output *output = ctx->output;
689 struct swaybar *bar = output->bar; 693 struct swaybar *bar = output->bar;
690 struct swaybar_config *config = bar->config; 694 struct swaybar_config *config = bar->config;
691 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
692 if (output->focused) {
693 ctx->background_color = config->colors.focused_background;
694 } else {
695 ctx->background_color = config->colors.background;
696 }
697
698 cairo_set_source_u32(cairo, ctx->background_color);
699 cairo_paint(cairo);
700 695
701 int th; 696 int th;
702 get_text_size(cairo, config->font, NULL, &th, NULL, 1, false, ""); 697 get_text_size(cairo, config->font_description, NULL, &th, NULL, 1, false, "");
703 uint32_t max_height = (th + WS_VERTICAL_PADDING * 4); 698 uint32_t max_height = (th + WS_VERTICAL_PADDING * 4);
704 /* 699 /*
705 * Each render_* function takes the actual height of the bar, and returns 700 * Each render_* function takes the actual height of the bar, and returns
@@ -758,8 +753,17 @@ void render_frame(struct swaybar_output *output) {
758 753
759 free_hotspots(&output->hotspots); 754 free_hotspots(&output->hotspots);
760 755
756 uint32_t background_color;
757 if (output->focused) {
758 background_color = output->bar->config->colors.focused_background;
759 } else {
760 background_color = output->bar->config->colors.background;
761 }
762
761 struct render_context ctx = { 0 }; 763 struct render_context ctx = { 0 };
762 ctx.output = output; 764 ctx.output = output;
765 // initial background color used for deciding the best way to antialias text
766 ctx.background_color = background_color;
763 767
764 cairo_surface_t *recorder = cairo_recording_surface_create( 768 cairo_surface_t *recorder = cairo_recording_surface_create(
765 CAIRO_CONTENT_COLOR_ALPHA, NULL); 769 CAIRO_CONTENT_COLOR_ALPHA, NULL);
@@ -769,24 +773,23 @@ void render_frame(struct swaybar_output *output) {
769 ctx.cairo = cairo; 773 ctx.cairo = cairo;
770 774
771 cairo_font_options_t *fo = cairo_font_options_create(); 775 cairo_font_options_t *fo = cairo_font_options_create();
772 cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
773 cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY); 776 cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY);
774 ctx.textaa_safe = fo; 777 ctx.textaa_safe = fo;
775 if (output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) { 778 if (output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) {
776 ctx.textaa_sharp = ctx.textaa_safe; 779 ctx.textaa_sharp = ctx.textaa_safe;
777 } else { 780 } else {
778 fo = cairo_font_options_create(); 781 fo = cairo_font_options_create();
779 cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
780 cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); 782 cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL);
781 cairo_font_options_set_subpixel_order(fo, 783 cairo_font_options_set_subpixel_order(fo,
782 to_cairo_subpixel_order(output->subpixel)); 784 to_cairo_subpixel_order(output->subpixel));
783 ctx.textaa_sharp = fo; 785 ctx.textaa_sharp = fo;
784 } 786 }
785 787
786 cairo_save(cairo); 788
787 cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); 789 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
790 cairo_set_source_u32(cairo, background_color);
788 cairo_paint(cairo); 791 cairo_paint(cairo);
789 cairo_restore(cairo); 792
790 uint32_t height = render_to_cairo(&ctx); 793 uint32_t height = render_to_cairo(&ctx);
791 int config_height = output->bar->config->height; 794 int config_height = output->bar->config->height;
792 if (config_height > 0) { 795 if (config_height > 0) {
@@ -831,13 +834,15 @@ void render_frame(struct swaybar_output *output) {
831 wl_surface_damage(output->surface, 0, 0, 834 wl_surface_damage(output->surface, 0, 0,
832 output->width, output->height); 835 output->width, output->height);
833 836
834 uint32_t bg_alpha = ctx.background_color & 0xFF; 837 uint32_t bg_alpha = background_color & 0xFF;
835 if (bg_alpha == 0xFF) { 838 if (bg_alpha == 0xFF) {
836 struct wl_region *region = 839 struct wl_region *region =
837 wl_compositor_create_region(output->bar->compositor); 840 wl_compositor_create_region(output->bar->compositor);
838 wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX); 841 wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX);
839 wl_surface_set_opaque_region(output->surface, region); 842 wl_surface_set_opaque_region(output->surface, region);
840 wl_region_destroy(region); 843 wl_region_destroy(region);
844 } else {
845 wl_surface_set_opaque_region(output->surface, NULL);
841 } 846 }
842 847
843 struct wl_callback *frame_callback = wl_surface_frame(output->surface); 848 struct wl_callback *frame_callback = wl_surface_frame(output->surface);