diff --git a/include/swaynag/swaynag.h b/include/swaynag/swaynag.h index fb9e9c21..8e80b570 100644 --- a/include/swaynag/swaynag.h +++ b/include/swaynag/swaynag.h @@ -90,6 +90,7 @@ struct swaynag { struct wp_cursor_shape_manager_v1 *cursor_shape_manager; struct wl_surface *surface; + bool needs_redraw; uint32_t width; uint32_t height; int32_t scale; diff --git a/swaynag/render.c b/swaynag/render.c index 21b03289..dcc0d06a 100644 --- a/swaynag/render.c +++ b/swaynag/render.c @@ -235,12 +235,10 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaynag *swaynag) { } int border = swaynag->type->bar_border_thickness; - if (max_height > swaynag->height) { - max_height += border; - } + max_height += border; cairo_set_source_u32(cairo, swaynag->type->border_bottom); cairo_rectangle(cairo, 0, - swaynag->height - border, + max_height - border, swaynag->width, border); cairo_fill(cairo); @@ -252,6 +250,7 @@ void render_frame(struct swaynag *swaynag) { if (!swaynag->run_display) { return; } + swaynag->needs_redraw = false; cairo_surface_t *recorder = cairo_recording_surface_create( CAIRO_CONTENT_COLOR_ALPHA, NULL); @@ -262,39 +261,44 @@ void render_frame(struct swaynag *swaynag) { cairo_paint(cairo); cairo_restore(cairo); uint32_t height = render_to_cairo(cairo, swaynag); + if (swaynag->height == 0) { + // for first commit, set required size but do not attach a buffer + zwlr_layer_surface_v1_set_size(swaynag->layer_surface, 0, height); + zwlr_layer_surface_v1_set_exclusive_zone(swaynag->layer_surface, + height); + wl_surface_commit(swaynag->surface); + goto cleanup; + } if (height != swaynag->height) { zwlr_layer_surface_v1_set_size(swaynag->layer_surface, 0, height); zwlr_layer_surface_v1_set_exclusive_zone(swaynag->layer_surface, - height); - wl_surface_commit(swaynag->surface); - wl_display_roundtrip(swaynag->display); - } else { - swaynag->current_buffer = get_next_buffer(swaynag->shm, - swaynag->buffers, - swaynag->width * swaynag->scale, - swaynag->height * swaynag->scale); - if (!swaynag->current_buffer) { - sway_log(SWAY_DEBUG, "Failed to get buffer. Skipping frame."); - goto cleanup; - } - - cairo_t *shm = swaynag->current_buffer->cairo; - cairo_save(shm); - cairo_set_operator(shm, CAIRO_OPERATOR_CLEAR); - cairo_paint(shm); - cairo_restore(shm); - cairo_set_source_surface(shm, recorder, 0.0, 0.0); - cairo_paint(shm); - - wl_surface_set_buffer_scale(swaynag->surface, swaynag->scale); - wl_surface_attach(swaynag->surface, - swaynag->current_buffer->buffer, 0, 0); - wl_surface_damage(swaynag->surface, 0, 0, - swaynag->width, swaynag->height); - wl_surface_commit(swaynag->surface); - wl_display_roundtrip(swaynag->display); + height); } + swaynag->current_buffer = get_next_buffer(swaynag->shm, + swaynag->buffers, + swaynag->width * swaynag->scale, + height * swaynag->scale); + if (!swaynag->current_buffer) { + sway_log(SWAY_DEBUG, "Failed to get buffer. Skipping frame."); + goto cleanup; + } + + cairo_t *shm = swaynag->current_buffer->cairo; + cairo_save(shm); + cairo_set_operator(shm, CAIRO_OPERATOR_CLEAR); + cairo_paint(shm); + cairo_restore(shm); + cairo_set_source_surface(shm, recorder, 0.0, 0.0); + cairo_paint(shm); + + wl_surface_set_buffer_scale(swaynag->surface, swaynag->scale); + wl_surface_attach(swaynag->surface, + swaynag->current_buffer->buffer, 0, 0); + wl_surface_damage(swaynag->surface, 0, 0, + swaynag->width, swaynag->height); + wl_surface_commit(swaynag->surface); + cleanup: cairo_surface_destroy(recorder); cairo_destroy(cairo); diff --git a/swaynag/swaynag.c b/swaynag/swaynag.c index da32eeb7..ac48cdff 100644 --- a/swaynag/swaynag.c +++ b/swaynag/swaynag.c @@ -47,7 +47,7 @@ static void swaynag_button_execute(struct swaynag *swaynag, swaynag->run_display = false; } else if (button->type == SWAYNAG_ACTION_EXPAND) { swaynag->details.visible = !swaynag->details.visible; - render_frame(swaynag); + swaynag->needs_redraw = true; } else { pid_t pid = fork(); if (pid < 0) { @@ -98,7 +98,7 @@ static void layer_surface_configure(void *data, swaynag->width = width; swaynag->height = height; zwlr_layer_surface_v1_ack_configure(surface, serial); - render_frame(swaynag); + swaynag->needs_redraw = true; } static void layer_surface_closed(void *data, @@ -122,7 +122,7 @@ static void surface_enter(void *data, struct wl_surface *surface, swaynag_output->name); swaynag->output = swaynag_output; swaynag->scale = swaynag->output->scale; - render_frame(swaynag); + swaynag->needs_redraw = true; break; } }; @@ -244,7 +244,7 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, && y < button_up.y + button_up.height && swaynag->details.offset > 0) { swaynag->details.offset--; - render_frame(swaynag); + swaynag->needs_redraw = true; return; } @@ -257,7 +257,7 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, && y < button_down.y + button_down.height && swaynag->details.offset < bot) { swaynag->details.offset++; - render_frame(swaynag); + swaynag->needs_redraw = true; return; } } @@ -284,7 +284,7 @@ static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, swaynag->details.offset++; } - render_frame(swaynag); + swaynag->needs_redraw = true; } static const struct wl_pointer_listener pointer_listener = { @@ -327,7 +327,7 @@ static void output_scale(void *data, struct wl_output *output, if (!swaynag_output->swaynag->cursor_shape_manager) { update_all_cursors(swaynag_output->swaynag); } - render_frame(swaynag_output->swaynag); + swaynag_output->swaynag->needs_redraw = true; } } @@ -503,9 +503,11 @@ void swaynag_setup(struct swaynag *swaynag) { void swaynag_run(struct swaynag *swaynag) { swaynag->run_display = true; render_frame(swaynag); - while (swaynag->run_display - && wl_display_dispatch(swaynag->display) != -1) { - // This is intentionally left blank + while (wl_display_dispatch(swaynag->display) != -1 + && swaynag->run_display) { + if (swaynag->needs_redraw) { + render_frame(swaynag); + } } }