diff options
Diffstat (limited to 'swaybar/render.c')
-rw-r--r-- | swaybar/render.c | 81 |
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 | ||
161 | static enum hotspot_event_handling block_hotspot_callback( | 160 | static 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 | ||
174 | static void i3bar_block_unref_callback(void *data) { | 173 | static 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 | ||
600 | static enum hotspot_event_handling workspace_hotspot_callback( | 599 | static 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); |