diff options
Diffstat (limited to 'swaybar/render.c')
-rw-r--r-- | swaybar/render.c | 146 |
1 files changed, 85 insertions, 61 deletions
diff --git a/swaybar/render.c b/swaybar/render.c index 97690338..dc31a5ea 100644 --- a/swaybar/render.c +++ b/swaybar/render.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <assert.h> | ||
2 | #include <limits.h> | 3 | #include <limits.h> |
3 | #include <stdlib.h> | 4 | #include <stdlib.h> |
4 | #include <stdint.h> | 5 | #include <stdint.h> |
@@ -9,6 +10,7 @@ | |||
9 | #include "pool-buffer.h" | 10 | #include "pool-buffer.h" |
10 | #include "swaybar/bar.h" | 11 | #include "swaybar/bar.h" |
11 | #include "swaybar/config.h" | 12 | #include "swaybar/config.h" |
13 | #include "swaybar/i3bar.h" | ||
12 | #include "swaybar/ipc.h" | 14 | #include "swaybar/ipc.h" |
13 | #include "swaybar/render.h" | 15 | #include "swaybar/render.h" |
14 | #include "swaybar/status_line.h" | 16 | #include "swaybar/status_line.h" |
@@ -19,47 +21,47 @@ static const double WS_VERTICAL_PADDING = 1.5; | |||
19 | static const double BORDER_WIDTH = 1; | 21 | static const double BORDER_WIDTH = 1; |
20 | 22 | ||
21 | static uint32_t render_status_line_error(cairo_t *cairo, | 23 | static uint32_t render_status_line_error(cairo_t *cairo, |
22 | struct swaybar_output *output, struct swaybar_config *config, | 24 | struct swaybar_output *output, double *x) { |
23 | const char *error, double *x, uint32_t surface_height) { | 25 | const char *error = output->bar->status->text; |
24 | if (!error) { | 26 | if (!error) { |
25 | return 0; | 27 | return 0; |
26 | } | 28 | } |
27 | 29 | ||
28 | uint32_t height = surface_height * output->scale; | 30 | uint32_t height = output->height * output->scale; |
29 | 31 | ||
30 | cairo_set_source_u32(cairo, 0xFF0000FF); | 32 | cairo_set_source_u32(cairo, 0xFF0000FF); |
31 | 33 | ||
32 | int margin = 3 * output->scale; | 34 | int margin = 3 * output->scale; |
33 | int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; | 35 | int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; |
34 | 36 | ||
37 | char *font = output->bar->config->font; | ||
35 | int text_width, text_height; | 38 | int text_width, text_height; |
36 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 39 | get_text_size(cairo, font, &text_width, &text_height, NULL, |
37 | output->scale, false, "%s", error); | 40 | output->scale, false, "%s", error); |
38 | 41 | ||
39 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 42 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
40 | uint32_t ideal_surface_height = ideal_height / output->scale; | 43 | uint32_t ideal_surface_height = ideal_height / output->scale; |
41 | if (surface_height < ideal_surface_height) { | 44 | if (output->height < ideal_surface_height) { |
42 | return ideal_surface_height; | 45 | return ideal_surface_height; |
43 | } | 46 | } |
44 | *x -= text_width + margin; | 47 | *x -= text_width + margin; |
45 | 48 | ||
46 | double text_y = height / 2.0 - text_height / 2.0; | 49 | double text_y = height / 2.0 - text_height / 2.0; |
47 | cairo_move_to(cairo, *x, (int)floor(text_y)); | 50 | cairo_move_to(cairo, *x, (int)floor(text_y)); |
48 | pango_printf(cairo, config->font, output->scale, false, "%s", error); | 51 | pango_printf(cairo, font, output->scale, false, "%s", error); |
49 | *x -= margin; | 52 | *x -= margin; |
50 | return surface_height; | 53 | return output->height; |
51 | } | 54 | } |
52 | 55 | ||
53 | static uint32_t render_status_line_text(cairo_t *cairo, | 56 | static uint32_t render_status_line_text(cairo_t *cairo, |
54 | struct swaybar_output *output, struct swaybar_config *config, | 57 | struct swaybar_output *output, double *x) { |
55 | const char *text, bool focused, double *x, uint32_t surface_height) { | 58 | const char *text = output->bar->status->text; |
56 | if (!text) { | 59 | if (!text) { |
57 | return 0; | 60 | return 0; |
58 | } | 61 | } |
59 | 62 | ||
60 | uint32_t height = surface_height * output->scale; | 63 | struct swaybar_config *config = output->bar->config; |
61 | 64 | cairo_set_source_u32(cairo, output->focused ? | |
62 | cairo_set_source_u32(cairo, focused ? | ||
63 | config->colors.focused_statusline : config->colors.statusline); | 65 | config->colors.focused_statusline : config->colors.statusline); |
64 | 66 | ||
65 | int text_width, text_height; | 67 | int text_width, text_height; |
@@ -71,17 +73,18 @@ static uint32_t render_status_line_text(cairo_t *cairo, | |||
71 | 73 | ||
72 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 74 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
73 | uint32_t ideal_surface_height = ideal_height / output->scale; | 75 | uint32_t ideal_surface_height = ideal_height / output->scale; |
74 | if (surface_height < ideal_surface_height) { | 76 | if (output->height < ideal_surface_height) { |
75 | return ideal_surface_height; | 77 | return ideal_surface_height; |
76 | } | 78 | } |
77 | 79 | ||
78 | *x -= text_width + margin; | 80 | *x -= text_width + margin; |
81 | uint32_t height = output->height * output->scale; | ||
79 | double text_y = height / 2.0 - text_height / 2.0; | 82 | double text_y = height / 2.0 - text_height / 2.0; |
80 | cairo_move_to(cairo, *x, (int)floor(text_y)); | 83 | cairo_move_to(cairo, *x, (int)floor(text_y)); |
81 | pango_printf(cairo, config->font, output->scale, | 84 | pango_printf(cairo, config->font, output->scale, |
82 | config->pango_markup, "%s", text); | 85 | config->pango_markup, "%s", text); |
83 | *x -= margin; | 86 | *x -= margin; |
84 | return surface_height; | 87 | return output->height; |
85 | } | 88 | } |
86 | 89 | ||
87 | static void render_sharp_line(cairo_t *cairo, uint32_t color, | 90 | static void render_sharp_line(cairo_t *cairo, uint32_t color, |
@@ -121,12 +124,11 @@ static void i3bar_block_unref_callback(void *data) { | |||
121 | 124 | ||
122 | static uint32_t render_status_block(cairo_t *cairo, | 125 | static uint32_t render_status_block(cairo_t *cairo, |
123 | struct swaybar_output *output, struct i3bar_block *block, double *x, | 126 | struct swaybar_output *output, struct i3bar_block *block, double *x, |
124 | uint32_t surface_height, bool focused, bool edge) { | 127 | bool edge) { |
125 | if (!block->full_text || !*block->full_text) { | 128 | if (!block->full_text || !*block->full_text) { |
126 | return 0; | 129 | return 0; |
127 | } | 130 | } |
128 | 131 | ||
129 | uint32_t height = surface_height * output->scale; | ||
130 | struct swaybar_config *config = output->bar->config; | 132 | struct swaybar_config *config = output->bar->config; |
131 | 133 | ||
132 | int text_width, text_height; | 134 | int text_width, text_height; |
@@ -144,7 +146,7 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
144 | double block_width = width; | 146 | double block_width = width; |
145 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 147 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
146 | uint32_t ideal_surface_height = ideal_height / output->scale; | 148 | uint32_t ideal_surface_height = ideal_height / output->scale; |
147 | if (surface_height < ideal_surface_height) { | 149 | if (output->height < ideal_surface_height) { |
148 | return ideal_surface_height; | 150 | return ideal_surface_height; |
149 | } | 151 | } |
150 | 152 | ||
@@ -165,7 +167,7 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
165 | output->scale, false, "%s", config->sep_symbol); | 167 | output->scale, false, "%s", config->sep_symbol); |
166 | uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; | 168 | uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; |
167 | uint32_t _ideal_surface_height = _ideal_height / output->scale; | 169 | uint32_t _ideal_surface_height = _ideal_height / output->scale; |
168 | if (surface_height < _ideal_surface_height) { | 170 | if (output->height < _ideal_surface_height) { |
169 | return _ideal_surface_height; | 171 | return _ideal_surface_height; |
170 | } | 172 | } |
171 | if (sep_width > block->separator_block_width) { | 173 | if (sep_width > block->separator_block_width) { |
@@ -177,6 +179,7 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
177 | *x -= margin; | 179 | *x -= margin; |
178 | } | 180 | } |
179 | 181 | ||
182 | uint32_t height = output->height * output->scale; | ||
180 | if (output->bar->status->click_events) { | 183 | if (output->bar->status->click_events) { |
181 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); | 184 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); |
182 | hotspot->x = *x; | 185 | hotspot->x = *x; |
@@ -240,7 +243,7 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
240 | } | 243 | } |
241 | 244 | ||
242 | if (!edge && block->separator) { | 245 | if (!edge && block->separator) { |
243 | if (focused) { | 246 | if (output->focused) { |
244 | cairo_set_source_u32(cairo, config->colors.focused_separator); | 247 | cairo_set_source_u32(cairo, config->colors.focused_separator); |
245 | } else { | 248 | } else { |
246 | cairo_set_source_u32(cairo, config->colors.separator); | 249 | cairo_set_source_u32(cairo, config->colors.separator); |
@@ -259,19 +262,16 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
259 | cairo_stroke(cairo); | 262 | cairo_stroke(cairo); |
260 | } | 263 | } |
261 | } | 264 | } |
262 | return surface_height; | 265 | return output->height; |
263 | } | 266 | } |
264 | 267 | ||
265 | static uint32_t render_status_line_i3bar(cairo_t *cairo, | 268 | static uint32_t render_status_line_i3bar(cairo_t *cairo, |
266 | struct swaybar_config *config, struct swaybar_output *output, | 269 | struct swaybar_output *output, double *x) { |
267 | struct status_line *status, bool focused, | ||
268 | double *x, uint32_t surface_height) { | ||
269 | uint32_t max_height = 0; | 270 | uint32_t max_height = 0; |
270 | bool edge = true; | 271 | bool edge = true; |
271 | struct i3bar_block *block; | 272 | struct i3bar_block *block; |
272 | wl_list_for_each(block, &status->blocks, link) { | 273 | wl_list_for_each(block, &output->bar->status->blocks, link) { |
273 | uint32_t h = render_status_block(cairo, output, | 274 | uint32_t h = render_status_block(cairo, output, block, x, edge); |
274 | block, x, surface_height, focused, edge); | ||
275 | max_height = h > max_height ? h : max_height; | 275 | max_height = h > max_height ? h : max_height; |
276 | edge = false; | 276 | edge = false; |
277 | } | 277 | } |
@@ -279,19 +279,15 @@ static uint32_t render_status_line_i3bar(cairo_t *cairo, | |||
279 | } | 279 | } |
280 | 280 | ||
281 | static uint32_t render_status_line(cairo_t *cairo, | 281 | static uint32_t render_status_line(cairo_t *cairo, |
282 | struct swaybar_config *config, struct swaybar_output *output, | 282 | struct swaybar_output *output, double *x) { |
283 | struct status_line *status, bool focused, | 283 | struct status_line *status = output->bar->status; |
284 | double *x, uint32_t surface_height) { | ||
285 | switch (status->protocol) { | 284 | switch (status->protocol) { |
286 | case PROTOCOL_ERROR: | 285 | case PROTOCOL_ERROR: |
287 | return render_status_line_error(cairo, output, config, | 286 | return render_status_line_error(cairo, output, x); |
288 | status->text, x, surface_height); | ||
289 | case PROTOCOL_TEXT: | 287 | case PROTOCOL_TEXT: |
290 | return render_status_line_text(cairo, output, config, | 288 | return render_status_line_text(cairo, output, x); |
291 | status->text, focused, x, surface_height); | ||
292 | case PROTOCOL_I3BAR: | 289 | case PROTOCOL_I3BAR: |
293 | return render_status_line_i3bar(cairo, config, output, | 290 | return render_status_line_i3bar(cairo, output, x); |
294 | status, focused, x, surface_height); | ||
295 | case PROTOCOL_UNDEF: | 291 | case PROTOCOL_UNDEF: |
296 | return 0; | 292 | return 0; |
297 | } | 293 | } |
@@ -299,10 +295,9 @@ static uint32_t render_status_line(cairo_t *cairo, | |||
299 | } | 295 | } |
300 | 296 | ||
301 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, | 297 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, |
302 | struct swaybar_output *output, struct swaybar_config *config, | 298 | struct swaybar_output *output, double x) { |
303 | const char *mode, double x, uint32_t surface_height) { | 299 | struct swaybar_config *config = output->bar->config; |
304 | uint32_t height = surface_height * output->scale; | 300 | const char *mode = config->mode; |
305 | |||
306 | int text_width, text_height; | 301 | int text_width, text_height; |
307 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 302 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, |
308 | output->scale, config->mode_pango_markup, | 303 | output->scale, config->mode_pango_markup, |
@@ -315,11 +310,12 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, | |||
315 | uint32_t ideal_height = text_height + ws_vertical_padding * 2 | 310 | uint32_t ideal_height = text_height + ws_vertical_padding * 2 |
316 | + border_width * 2; | 311 | + border_width * 2; |
317 | uint32_t ideal_surface_height = ideal_height / output->scale; | 312 | uint32_t ideal_surface_height = ideal_height / output->scale; |
318 | if (surface_height < ideal_surface_height) { | 313 | if (output->height < ideal_surface_height) { |
319 | return ideal_surface_height; | 314 | return ideal_surface_height; |
320 | } | 315 | } |
321 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; | 316 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; |
322 | 317 | ||
318 | uint32_t height = output->height * output->scale; | ||
323 | cairo_set_source_u32(cairo, config->colors.binding_mode.background); | 319 | cairo_set_source_u32(cairo, config->colors.binding_mode.background); |
324 | cairo_rectangle(cairo, x, 0, width, height); | 320 | cairo_rectangle(cairo, x, 0, width, height); |
325 | cairo_fill(cairo); | 321 | cairo_fill(cairo); |
@@ -339,7 +335,7 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, | |||
339 | cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); | 335 | cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); |
340 | pango_printf(cairo, config->font, output->scale, config->mode_pango_markup, | 336 | pango_printf(cairo, config->font, output->scale, config->mode_pango_markup, |
341 | "%s", mode); | 337 | "%s", mode); |
342 | return surface_height; | 338 | return output->height; |
343 | } | 339 | } |
344 | 340 | ||
345 | static const char *strip_workspace_number(const char *ws_name) { | 341 | static const char *strip_workspace_number(const char *ws_name) { |
@@ -365,8 +361,9 @@ static enum hotspot_event_handling workspace_hotspot_callback(struct swaybar_out | |||
365 | } | 361 | } |
366 | 362 | ||
367 | static uint32_t render_workspace_button(cairo_t *cairo, | 363 | static uint32_t render_workspace_button(cairo_t *cairo, |
368 | struct swaybar_output *output, struct swaybar_config *config, | 364 | struct swaybar_output *output, |
369 | struct swaybar_workspace *ws, double *x, uint32_t surface_height) { | 365 | struct swaybar_workspace *ws, double *x) { |
366 | struct swaybar_config *config = output->bar->config; | ||
370 | const char *name = ws->name; | 367 | const char *name = ws->name; |
371 | if (config->strip_workspace_numbers) { | 368 | if (config->strip_workspace_numbers) { |
372 | name = strip_workspace_number(ws->name); | 369 | name = strip_workspace_number(ws->name); |
@@ -383,7 +380,7 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
383 | box_colors = config->colors.inactive_workspace; | 380 | box_colors = config->colors.inactive_workspace; |
384 | } | 381 | } |
385 | 382 | ||
386 | uint32_t height = surface_height * output->scale; | 383 | uint32_t height = output->height * output->scale; |
387 | 384 | ||
388 | int text_width, text_height; | 385 | int text_width, text_height; |
389 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 386 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, |
@@ -396,7 +393,7 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
396 | uint32_t ideal_height = ws_vertical_padding * 2 + text_height | 393 | uint32_t ideal_height = ws_vertical_padding * 2 + text_height |
397 | + border_width * 2; | 394 | + border_width * 2; |
398 | uint32_t ideal_surface_height = ideal_height / output->scale; | 395 | uint32_t ideal_surface_height = ideal_height / output->scale; |
399 | if (surface_height < ideal_surface_height) { | 396 | if (output->height < ideal_surface_height) { |
400 | return ideal_surface_height; | 397 | return ideal_surface_height; |
401 | } | 398 | } |
402 | 399 | ||
@@ -433,11 +430,11 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
433 | wl_list_insert(&output->hotspots, &hotspot->link); | 430 | wl_list_insert(&output->hotspots, &hotspot->link); |
434 | 431 | ||
435 | *x += width; | 432 | *x += width; |
436 | return surface_height; | 433 | return output->height; |
437 | } | 434 | } |
438 | 435 | ||
439 | static uint32_t render_to_cairo(cairo_t *cairo, | 436 | static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) { |
440 | struct swaybar *bar, struct swaybar_output *output) { | 437 | struct swaybar *bar = output->bar; |
441 | struct swaybar_config *config = bar->config; | 438 | struct swaybar_config *config = bar->config; |
442 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | 439 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); |
443 | if (output->focused) { | 440 | if (output->focused) { |
@@ -457,29 +454,43 @@ static uint32_t render_to_cairo(cairo_t *cairo, | |||
457 | */ | 454 | */ |
458 | double x = output->width * output->scale; | 455 | double x = output->width * output->scale; |
459 | if (bar->status) { | 456 | if (bar->status) { |
460 | uint32_t h = render_status_line(cairo, config, output, | 457 | uint32_t h = render_status_line(cairo, output, &x); |
461 | bar->status, output->focused, &x, output->height); | ||
462 | max_height = h > max_height ? h : max_height; | 458 | max_height = h > max_height ? h : max_height; |
463 | } | 459 | } |
464 | x = 0; | 460 | x = 0; |
465 | if (config->workspace_buttons) { | 461 | if (config->workspace_buttons) { |
466 | struct swaybar_workspace *ws; | 462 | struct swaybar_workspace *ws; |
467 | wl_list_for_each_reverse(ws, &output->workspaces, link) { | 463 | wl_list_for_each_reverse(ws, &output->workspaces, link) { |
468 | uint32_t h = render_workspace_button(cairo, | 464 | uint32_t h = render_workspace_button(cairo, output, ws, &x); |
469 | output, config, ws, &x, output->height); | ||
470 | max_height = h > max_height ? h : max_height; | 465 | max_height = h > max_height ? h : max_height; |
471 | } | 466 | } |
472 | } | 467 | } |
473 | if (config->binding_mode_indicator && config->mode) { | 468 | if (config->binding_mode_indicator && config->mode) { |
474 | uint32_t h = render_binding_mode_indicator(cairo, | 469 | uint32_t h = render_binding_mode_indicator(cairo, output, x); |
475 | output, config, config->mode, x, output->height); | ||
476 | max_height = h > max_height ? h : max_height; | 470 | max_height = h > max_height ? h : max_height; |
477 | } | 471 | } |
478 | 472 | ||
479 | return max_height > output->height ? max_height : output->height; | 473 | return max_height > output->height ? max_height : output->height; |
480 | } | 474 | } |
481 | 475 | ||
482 | void render_frame(struct swaybar *bar, struct swaybar_output *output) { | 476 | static void output_frame_handle_done(void *data, struct wl_callback *callback, |
477 | uint32_t time) { | ||
478 | wl_callback_destroy(callback); | ||
479 | struct swaybar_output *output = data; | ||
480 | output->frame_scheduled = false; | ||
481 | if (output->dirty) { | ||
482 | render_frame(output); | ||
483 | output->dirty = false; | ||
484 | } | ||
485 | } | ||
486 | |||
487 | static const struct wl_callback_listener output_frame_listener = { | ||
488 | .done = output_frame_handle_done | ||
489 | }; | ||
490 | |||
491 | void render_frame(struct swaybar_output *output) { | ||
492 | assert(output->surface != NULL); | ||
493 | |||
483 | struct swaybar_hotspot *hotspot, *tmp; | 494 | struct swaybar_hotspot *hotspot, *tmp; |
484 | wl_list_for_each_safe(hotspot, tmp, &output->hotspots, link) { | 495 | wl_list_for_each_safe(hotspot, tmp, &output->hotspots, link) { |
485 | if (hotspot->destroy) { | 496 | if (hotspot->destroy) { |
@@ -492,13 +503,21 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) { | |||
492 | cairo_surface_t *recorder = cairo_recording_surface_create( | 503 | cairo_surface_t *recorder = cairo_recording_surface_create( |
493 | CAIRO_CONTENT_COLOR_ALPHA, NULL); | 504 | CAIRO_CONTENT_COLOR_ALPHA, NULL); |
494 | cairo_t *cairo = cairo_create(recorder); | 505 | cairo_t *cairo = cairo_create(recorder); |
506 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); | ||
507 | cairo_font_options_t *fo = cairo_font_options_create(); | ||
508 | cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); | ||
509 | cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); | ||
510 | cairo_font_options_set_subpixel_order(fo, to_cairo_subpixel_order(output->subpixel)); | ||
511 | cairo_set_font_options(cairo, fo); | ||
512 | cairo_font_options_destroy(fo); | ||
495 | cairo_save(cairo); | 513 | cairo_save(cairo); |
496 | cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); | 514 | cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); |
497 | cairo_paint(cairo); | 515 | cairo_paint(cairo); |
498 | cairo_restore(cairo); | 516 | cairo_restore(cairo); |
499 | uint32_t height = render_to_cairo(cairo, bar, output); | 517 | uint32_t height = render_to_cairo(cairo, output); |
500 | if (bar->config->height >= 0 && height < (uint32_t)bar->config->height) { | 518 | int config_height = output->bar->config->height; |
501 | height = bar->config->height; | 519 | if (config_height >= 0 && height < (uint32_t)config_height) { |
520 | height = config_height; | ||
502 | } | 521 | } |
503 | if (height != output->height) { | 522 | if (height != output->height) { |
504 | // Reconfigure surface | 523 | // Reconfigure surface |
@@ -507,14 +526,15 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) { | |||
507 | // TODO: this could infinite loop if the compositor assigns us a | 526 | // TODO: this could infinite loop if the compositor assigns us a |
508 | // different height than what we asked for | 527 | // different height than what we asked for |
509 | wl_surface_commit(output->surface); | 528 | wl_surface_commit(output->surface); |
510 | wl_display_roundtrip(bar->display); | ||
511 | } else if (height > 0) { | 529 | } else if (height > 0) { |
512 | // Replay recording into shm and send it off | 530 | // Replay recording into shm and send it off |
513 | output->current_buffer = get_next_buffer(bar->shm, | 531 | output->current_buffer = get_next_buffer(output->bar->shm, |
514 | output->buffers, | 532 | output->buffers, |
515 | output->width * output->scale, | 533 | output->width * output->scale, |
516 | output->height * output->scale); | 534 | output->height * output->scale); |
517 | if (!output->current_buffer) { | 535 | if (!output->current_buffer) { |
536 | cairo_surface_destroy(recorder); | ||
537 | cairo_destroy(cairo); | ||
518 | return; | 538 | return; |
519 | } | 539 | } |
520 | cairo_t *shm = output->current_buffer->cairo; | 540 | cairo_t *shm = output->current_buffer->cairo; |
@@ -532,8 +552,12 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) { | |||
532 | output->current_buffer->buffer, 0, 0); | 552 | output->current_buffer->buffer, 0, 0); |
533 | wl_surface_damage(output->surface, 0, 0, | 553 | wl_surface_damage(output->surface, 0, 0, |
534 | output->width, output->height); | 554 | output->width, output->height); |
555 | |||
556 | struct wl_callback *frame_callback = wl_surface_frame(output->surface); | ||
557 | wl_callback_add_listener(frame_callback, &output_frame_listener, output); | ||
558 | output->frame_scheduled = true; | ||
559 | |||
535 | wl_surface_commit(output->surface); | 560 | wl_surface_commit(output->surface); |
536 | wl_display_roundtrip(bar->display); | ||
537 | } | 561 | } |
538 | cairo_surface_destroy(recorder); | 562 | cairo_surface_destroy(recorder); |
539 | cairo_destroy(cairo); | 563 | cairo_destroy(cairo); |