diff --git a/lib/renderers/wayland/wayland.c b/lib/renderers/wayland/wayland.c index dd97009..a719c7d 100644 --- a/lib/renderers/wayland/wayland.c +++ b/lib/renderers/wayland/wayland.c @@ -25,6 +25,13 @@ render(const struct bm_menu *menu) return; } + struct window *window; + wl_list_for_each(window, &wayland->windows, link) { + if (window->render_pending) + bm_wl_window_render(window, wayland->display, menu); + } + wl_display_flush(wayland->display); + struct epoll_event ep[16]; uint32_t num = epoll_wait(efd, ep, 16, -1); for (uint32_t i = 0; i < num; ++i) { @@ -38,10 +45,10 @@ render(const struct bm_menu *menu) } if (wayland->input.code != wayland->input.last_code) { - struct window *window; - wl_list_for_each(window, &wayland->windows, link) { - bm_wl_window_render(window, wayland->display, menu); + wl_list_for_each(window, &wayland->windows, link) { + bm_wl_window_schedule_render(window); } + wayland->input.last_code = wayland->input.code; } } @@ -263,6 +270,7 @@ constructor(struct bm_menu *menu) goto fail; window->notify.render = bm_cairo_paint; window->max_height = output->height; + window->render_pending = true; wl_list_insert(&wayland->windows, &window->link); } diff --git a/lib/renderers/wayland/wayland.h b/lib/renderers/wayland/wayland.h index cc50feb..9defb06 100644 --- a/lib/renderers/wayland/wayland.h +++ b/lib/renderers/wayland/wayland.h @@ -84,6 +84,7 @@ struct window { uint32_t displayed; struct wl_list link; bool bottom; + bool render_pending; struct { void (*render)(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result); @@ -117,6 +118,7 @@ struct wayland { void bm_wl_repeat(struct wayland *wayland); bool bm_wl_registry_register(struct wayland *wayland); void bm_wl_registry_destroy(struct wayland *wayland); +void bm_wl_window_schedule_render(struct window *window); void bm_wl_window_render(struct window *window, struct wl_display *display, const struct bm_menu *menu); void bm_wl_window_set_bottom(struct window *window, struct wl_display *display, bool bottom); void bm_wl_window_grab_keyboard(struct window *window, struct wl_display *display, bool grab); diff --git a/lib/renderers/wayland/window.c b/lib/renderers/wayland/window.c index 1890a60..2141eff 100644 --- a/lib/renderers/wayland/window.c +++ b/lib/renderers/wayland/window.c @@ -197,17 +197,29 @@ frame_callback(void *data, struct wl_callback *callback, uint32_t time) struct window *window = data; wl_callback_destroy(callback); window->frame_cb = NULL; + window->render_pending = true; } static const struct wl_callback_listener listener = { frame_callback }; +void +bm_wl_window_schedule_render(struct window *window) +{ + assert(window); + if (window->frame_cb) + return; + + window->frame_cb = wl_surface_frame(window->surface); + wl_callback_add_listener(window->frame_cb, &listener, window); + wl_surface_commit(window->surface); +} + void bm_wl_window_render(struct window *window, struct wl_display *display, const struct bm_menu *menu) { assert(window && menu); - struct buffer *buffer; for (int tries = 0; tries < 2; ++tries) { if (!(buffer = next_buffer(window))) { @@ -232,13 +244,11 @@ bm_wl_window_render(struct window *window, struct wl_display *display, const str destroy_buffer(buffer); } - window->frame_cb = wl_surface_frame(window->surface); - wl_callback_add_listener(window->frame_cb, &listener, window); - wl_surface_damage(window->surface, 0, 0, buffer->width, buffer->height); wl_surface_attach(window->surface, buffer->buffer, 0, 0); wl_surface_commit(window->surface); buffer->busy = true; + window->render_pending = false; } void