forked from RepoMirrors/bemenu
wayland: implement a proper repaint cycle
This commit is contained in:
parent
33e540a2b0
commit
ab82afab7f
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user