diff options
Diffstat (limited to 'swaybar')
-rw-r--r-- | swaybar/bar.c | 112 | ||||
-rw-r--r-- | swaybar/i3bar.c | 17 | ||||
-rw-r--r-- | swaybar/render.c | 5 |
3 files changed, 88 insertions, 46 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c index 3ae730f7..69069f40 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -48,8 +48,13 @@ static void swaybar_output_free(struct swaybar_output *output) { | |||
48 | return; | 48 | return; |
49 | } | 49 | } |
50 | wlr_log(WLR_DEBUG, "Removing output %s", output->name); | 50 | wlr_log(WLR_DEBUG, "Removing output %s", output->name); |
51 | zwlr_layer_surface_v1_destroy(output->layer_surface); | 51 | if (output->layer_surface != NULL) { |
52 | wl_surface_destroy(output->surface); | 52 | zwlr_layer_surface_v1_destroy(output->layer_surface); |
53 | } | ||
54 | if (output->surface != NULL) { | ||
55 | wl_surface_destroy(output->surface); | ||
56 | } | ||
57 | zxdg_output_v1_destroy(output->xdg_output); | ||
53 | wl_output_destroy(output->output); | 58 | wl_output_destroy(output->output); |
54 | destroy_buffer(&output->buffers[0]); | 59 | destroy_buffer(&output->buffers[0]); |
55 | destroy_buffer(&output->buffers[1]); | 60 | destroy_buffer(&output->buffers[1]); |
@@ -283,6 +288,37 @@ const struct wl_seat_listener seat_listener = { | |||
283 | .name = seat_handle_name, | 288 | .name = seat_handle_name, |
284 | }; | 289 | }; |
285 | 290 | ||
291 | static void add_layer_surface(struct swaybar_output *output) { | ||
292 | if (output->surface != NULL) { | ||
293 | return; | ||
294 | } | ||
295 | struct swaybar *bar = output->bar; | ||
296 | |||
297 | output->surface = wl_compositor_create_surface(bar->compositor); | ||
298 | assert(output->surface); | ||
299 | output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( | ||
300 | bar->layer_shell, output->surface, output->output, | ||
301 | ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); | ||
302 | assert(output->layer_surface); | ||
303 | zwlr_layer_surface_v1_add_listener(output->layer_surface, | ||
304 | &layer_surface_listener, output); | ||
305 | zwlr_layer_surface_v1_set_anchor(output->layer_surface, | ||
306 | bar->config->position); | ||
307 | } | ||
308 | |||
309 | static bool bar_uses_output(struct swaybar *bar, const char *name) { | ||
310 | if (bar->config->all_outputs) { | ||
311 | return true; | ||
312 | } | ||
313 | struct config_output *coutput; | ||
314 | wl_list_for_each(coutput, &bar->config->outputs, link) { | ||
315 | if (strcmp(coutput->name, name) == 0) { | ||
316 | return true; | ||
317 | } | ||
318 | } | ||
319 | return false; | ||
320 | } | ||
321 | |||
286 | static void output_geometry(void *data, struct wl_output *output, int32_t x, | 322 | static void output_geometry(void *data, struct wl_output *output, int32_t x, |
287 | int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, | 323 | int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, |
288 | const char *make, const char *model, int32_t transform) { | 324 | const char *make, const char *model, int32_t transform) { |
@@ -326,7 +362,22 @@ static void xdg_output_handle_logical_size(void *data, | |||
326 | 362 | ||
327 | static void xdg_output_handle_done(void *data, | 363 | static void xdg_output_handle_done(void *data, |
328 | struct zxdg_output_v1 *xdg_output) { | 364 | struct zxdg_output_v1 *xdg_output) { |
329 | // Who cares | 365 | struct swaybar_output *output = data; |
366 | struct swaybar *bar = output->bar; | ||
367 | |||
368 | assert(output->name != NULL); | ||
369 | if (!bar_uses_output(bar, output->name)) { | ||
370 | swaybar_output_free(output); | ||
371 | return; | ||
372 | } | ||
373 | |||
374 | if (wl_list_empty(&output->link)) { | ||
375 | wl_list_remove(&output->link); | ||
376 | wl_list_insert(&bar->outputs, &output->link); | ||
377 | |||
378 | add_layer_surface(output); | ||
379 | render_frame(bar, output); | ||
380 | } | ||
330 | } | 381 | } |
331 | 382 | ||
332 | static void xdg_output_handle_name(void *data, | 383 | static void xdg_output_handle_name(void *data, |
@@ -349,17 +400,15 @@ struct zxdg_output_v1_listener xdg_output_listener = { | |||
349 | .description = xdg_output_handle_description, | 400 | .description = xdg_output_handle_description, |
350 | }; | 401 | }; |
351 | 402 | ||
352 | static bool bar_uses_output(struct swaybar *bar, const char *name) { | 403 | static void add_xdg_output(struct swaybar_output *output) { |
353 | if (bar->config->all_outputs) { | 404 | if (output->xdg_output != NULL) { |
354 | return true; | 405 | return; |
355 | } | ||
356 | struct config_output *coutput; | ||
357 | wl_list_for_each(coutput, &bar->config->outputs, link) { | ||
358 | if (strcmp(coutput->name, name) == 0) { | ||
359 | return true; | ||
360 | } | ||
361 | } | 406 | } |
362 | return false; | 407 | assert(output->bar->xdg_output_manager != NULL); |
408 | output->xdg_output = zxdg_output_manager_v1_get_xdg_output( | ||
409 | output->bar->xdg_output_manager, output->output); | ||
410 | zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, | ||
411 | output); | ||
363 | } | 412 | } |
364 | 413 | ||
365 | static void handle_global(void *data, struct wl_registry *registry, | 414 | static void handle_global(void *data, struct wl_registry *registry, |
@@ -386,7 +435,10 @@ static void handle_global(void *data, struct wl_registry *registry, | |||
386 | output->wl_name = name; | 435 | output->wl_name = name; |
387 | wl_list_init(&output->workspaces); | 436 | wl_list_init(&output->workspaces); |
388 | wl_list_init(&output->hotspots); | 437 | wl_list_init(&output->hotspots); |
389 | wl_list_insert(&bar->outputs, &output->link); | 438 | wl_list_init(&output->link); |
439 | if (bar->xdg_output_manager != NULL) { | ||
440 | add_xdg_output(output); | ||
441 | } | ||
390 | } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { | 442 | } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { |
391 | bar->layer_shell = wl_registry_bind( | 443 | bar->layer_shell = wl_registry_bind( |
392 | registry, name, &zwlr_layer_shell_v1_interface, 1); | 444 | registry, name, &zwlr_layer_shell_v1_interface, 1); |
@@ -416,7 +468,9 @@ static const struct wl_registry_listener registry_listener = { | |||
416 | static void render_all_frames(struct swaybar *bar) { | 468 | static void render_all_frames(struct swaybar *bar) { |
417 | struct swaybar_output *output; | 469 | struct swaybar_output *output; |
418 | wl_list_for_each(output, &bar->outputs, link) { | 470 | wl_list_for_each(output, &bar->outputs, link) { |
419 | render_frame(bar, output); | 471 | if (output->surface != NULL) { |
472 | render_frame(bar, output); | ||
473 | } | ||
420 | } | 474 | } |
421 | } | 475 | } |
422 | 476 | ||
@@ -443,23 +497,10 @@ void bar_setup(struct swaybar *bar, | |||
443 | 497 | ||
444 | struct swaybar_output *output; | 498 | struct swaybar_output *output; |
445 | wl_list_for_each(output, &bar->outputs, link) { | 499 | wl_list_for_each(output, &bar->outputs, link) { |
446 | output->xdg_output = zxdg_output_manager_v1_get_xdg_output( | 500 | add_xdg_output(output); |
447 | bar->xdg_output_manager, output->output); | ||
448 | zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, | ||
449 | output); | ||
450 | } | 501 | } |
451 | wl_display_roundtrip(bar->display); | 502 | wl_display_roundtrip(bar->display); |
452 | 503 | ||
453 | struct swaybar_output *output_tmp; | ||
454 | wl_list_for_each_safe(output, output_tmp, &bar->outputs, link) { | ||
455 | if (!bar_uses_output(bar, output->name)) { | ||
456 | zxdg_output_v1_destroy(output->xdg_output); | ||
457 | wl_output_destroy(output->output); | ||
458 | wl_list_remove(&output->link); | ||
459 | free(output); | ||
460 | } | ||
461 | } | ||
462 | |||
463 | struct swaybar_pointer *pointer = &bar->pointer; | 504 | struct swaybar_pointer *pointer = &bar->pointer; |
464 | 505 | ||
465 | int max_scale = 1; | 506 | int max_scale = 1; |
@@ -479,18 +520,6 @@ void bar_setup(struct swaybar *bar, | |||
479 | pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); | 520 | pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); |
480 | assert(pointer->cursor_surface); | 521 | assert(pointer->cursor_surface); |
481 | 522 | ||
482 | wl_list_for_each(output, &bar->outputs, link) { | ||
483 | output->surface = wl_compositor_create_surface(bar->compositor); | ||
484 | assert(output->surface); | ||
485 | output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( | ||
486 | bar->layer_shell, output->surface, output->output, | ||
487 | ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); | ||
488 | assert(output->layer_surface); | ||
489 | zwlr_layer_surface_v1_add_listener(output->layer_surface, | ||
490 | &layer_surface_listener, output); | ||
491 | zwlr_layer_surface_v1_set_anchor(output->layer_surface, | ||
492 | bar->config->position); | ||
493 | } | ||
494 | ipc_get_workspaces(bar); | 523 | ipc_get_workspaces(bar); |
495 | render_all_frames(bar); | 524 | render_all_frames(bar); |
496 | } | 525 | } |
@@ -529,6 +558,7 @@ void bar_run(struct swaybar *bar) { | |||
529 | } | 558 | } |
530 | while (1) { | 559 | while (1) { |
531 | event_loop_poll(); | 560 | event_loop_poll(); |
561 | wl_display_flush(bar->display); | ||
532 | } | 562 | } |
533 | } | 563 | } |
534 | 564 | ||
diff --git a/swaybar/i3bar.c b/swaybar/i3bar.c index 88404703..325aa61a 100644 --- a/swaybar/i3bar.c +++ b/swaybar/i3bar.c | |||
@@ -117,7 +117,9 @@ bool i3bar_handle_readable(struct status_line *status) { | |||
117 | memmove(status->buffer, &status->buffer[c], status->buffer_index); | 117 | memmove(status->buffer, &status->buffer[c], status->buffer_index); |
118 | break; | 118 | break; |
119 | } else if (!isspace(status->buffer[c])) { | 119 | } else if (!isspace(status->buffer[c])) { |
120 | status_error(status, "[invalid json]"); | 120 | wlr_log(WLR_DEBUG, "Invalid i3bar json: expected '[' but encountered '%c'", |
121 | status->buffer[c]); | ||
122 | status_error(status, "[invalid i3bar json]"); | ||
121 | return true; | 123 | return true; |
122 | } | 124 | } |
123 | } | 125 | } |
@@ -155,6 +157,8 @@ bool i3bar_handle_readable(struct status_line *status) { | |||
155 | ++buffer_pos; | 157 | ++buffer_pos; |
156 | break; | 158 | break; |
157 | } else if (!isspace(status->buffer[buffer_pos])) { | 159 | } else if (!isspace(status->buffer[buffer_pos])) { |
160 | wlr_log(WLR_DEBUG, "Invalid i3bar json: expected ',' but encountered '%c'", | ||
161 | status->buffer[buffer_pos]); | ||
158 | status_error(status, "[invalid i3bar json]"); | 162 | status_error(status, "[invalid i3bar json]"); |
159 | return true; | 163 | return true; |
160 | } | 164 | } |
@@ -166,7 +170,8 @@ bool i3bar_handle_readable(struct status_line *status) { | |||
166 | } else { | 170 | } else { |
167 | test_object = json_tokener_parse_ex(status->tokener, | 171 | test_object = json_tokener_parse_ex(status->tokener, |
168 | &status->buffer[buffer_pos], status->buffer_index - buffer_pos); | 172 | &status->buffer[buffer_pos], status->buffer_index - buffer_pos); |
169 | if (json_tokener_get_error(status->tokener) == json_tokener_success) { | 173 | enum json_tokener_error err = json_tokener_get_error(status->tokener); |
174 | if (err == json_tokener_success) { | ||
170 | if (json_object_get_type(test_object) == json_type_array) { | 175 | if (json_object_get_type(test_object) == json_type_array) { |
171 | if (last_object) { | 176 | if (last_object) { |
172 | json_object_put(last_object); | 177 | json_object_put(last_object); |
@@ -198,12 +203,14 @@ bool i3bar_handle_readable(struct status_line *status) { | |||
198 | continue; // look for comma without reading more input | 203 | continue; // look for comma without reading more input |
199 | } | 204 | } |
200 | buffer_pos = status->buffer_index = 0; | 205 | buffer_pos = status->buffer_index = 0; |
201 | } else if (json_tokener_get_error(status->tokener) == json_tokener_continue) { | 206 | } else if (err == json_tokener_continue) { |
207 | json_tokener_reset(status->tokener); | ||
202 | if (status->buffer_index < status->buffer_size) { | 208 | if (status->buffer_index < status->buffer_size) { |
203 | // move the object to the start of the buffer | 209 | // move the object to the start of the buffer |
204 | status->buffer_index -= buffer_pos; | 210 | status->buffer_index -= buffer_pos; |
205 | memmove(status->buffer, &status->buffer[buffer_pos], | 211 | memmove(status->buffer, &status->buffer[buffer_pos], |
206 | status->buffer_index); | 212 | status->buffer_index); |
213 | buffer_pos = 0; | ||
207 | } else { | 214 | } else { |
208 | // expand buffer | 215 | // expand buffer |
209 | status->buffer_size *= 2; | 216 | status->buffer_size *= 2; |
@@ -217,6 +224,10 @@ bool i3bar_handle_readable(struct status_line *status) { | |||
217 | } | 224 | } |
218 | } | 225 | } |
219 | } else { | 226 | } else { |
227 | char last_char = status->buffer[status->buffer_index - 1]; | ||
228 | status->buffer[status->buffer_index - 1] = '\0'; | ||
229 | wlr_log(WLR_DEBUG, "Failed to parse i3bar json - %s: '%s%c'", | ||
230 | json_tokener_error_desc(err), &status->buffer[buffer_pos], last_char); | ||
220 | status_error(status, "[failed to parse i3bar json]"); | 231 | status_error(status, "[failed to parse i3bar json]"); |
221 | return true; | 232 | return true; |
222 | } | 233 | } |
diff --git a/swaybar/render.c b/swaybar/render.c index 97690338..26db80cb 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> |
@@ -480,6 +481,8 @@ static uint32_t render_to_cairo(cairo_t *cairo, | |||
480 | } | 481 | } |
481 | 482 | ||
482 | void render_frame(struct swaybar *bar, struct swaybar_output *output) { | 483 | void render_frame(struct swaybar *bar, struct swaybar_output *output) { |
484 | assert(output->surface != NULL); | ||
485 | |||
483 | struct swaybar_hotspot *hotspot, *tmp; | 486 | struct swaybar_hotspot *hotspot, *tmp; |
484 | wl_list_for_each_safe(hotspot, tmp, &output->hotspots, link) { | 487 | wl_list_for_each_safe(hotspot, tmp, &output->hotspots, link) { |
485 | if (hotspot->destroy) { | 488 | if (hotspot->destroy) { |
@@ -507,7 +510,6 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) { | |||
507 | // TODO: this could infinite loop if the compositor assigns us a | 510 | // TODO: this could infinite loop if the compositor assigns us a |
508 | // different height than what we asked for | 511 | // different height than what we asked for |
509 | wl_surface_commit(output->surface); | 512 | wl_surface_commit(output->surface); |
510 | wl_display_roundtrip(bar->display); | ||
511 | } else if (height > 0) { | 513 | } else if (height > 0) { |
512 | // Replay recording into shm and send it off | 514 | // Replay recording into shm and send it off |
513 | output->current_buffer = get_next_buffer(bar->shm, | 515 | output->current_buffer = get_next_buffer(bar->shm, |
@@ -533,7 +535,6 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) { | |||
533 | wl_surface_damage(output->surface, 0, 0, | 535 | wl_surface_damage(output->surface, 0, 0, |
534 | output->width, output->height); | 536 | output->width, output->height); |
535 | wl_surface_commit(output->surface); | 537 | wl_surface_commit(output->surface); |
536 | wl_display_roundtrip(bar->display); | ||
537 | } | 538 | } |
538 | cairo_surface_destroy(recorder); | 539 | cairo_surface_destroy(recorder); |
539 | cairo_destroy(cairo); | 540 | cairo_destroy(cairo); |