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;
|
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];
|
struct epoll_event ep[16];
|
||||||
uint32_t num = epoll_wait(efd, ep, 16, -1);
|
uint32_t num = epoll_wait(efd, ep, 16, -1);
|
||||||
for (uint32_t i = 0; i < num; ++i) {
|
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) {
|
if (wayland->input.code != wayland->input.last_code) {
|
||||||
struct window *window;
|
wl_list_for_each(window, &wayland->windows, link) {
|
||||||
wl_list_for_each(window, &wayland->windows, link) {
|
bm_wl_window_schedule_render(window);
|
||||||
bm_wl_window_render(window, wayland->display, menu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wayland->input.last_code = wayland->input.code;
|
wayland->input.last_code = wayland->input.code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,6 +270,7 @@ constructor(struct bm_menu *menu)
|
|||||||
goto fail;
|
goto fail;
|
||||||
window->notify.render = bm_cairo_paint;
|
window->notify.render = bm_cairo_paint;
|
||||||
window->max_height = output->height;
|
window->max_height = output->height;
|
||||||
|
window->render_pending = true;
|
||||||
wl_list_insert(&wayland->windows, &window->link);
|
wl_list_insert(&wayland->windows, &window->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +84,7 @@ struct window {
|
|||||||
uint32_t displayed;
|
uint32_t displayed;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
bool bottom;
|
bool bottom;
|
||||||
|
bool render_pending;
|
||||||
|
|
||||||
struct {
|
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);
|
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);
|
void bm_wl_repeat(struct wayland *wayland);
|
||||||
bool bm_wl_registry_register(struct wayland *wayland);
|
bool bm_wl_registry_register(struct wayland *wayland);
|
||||||
void bm_wl_registry_destroy(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_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_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);
|
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;
|
struct window *window = data;
|
||||||
wl_callback_destroy(callback);
|
wl_callback_destroy(callback);
|
||||||
window->frame_cb = NULL;
|
window->frame_cb = NULL;
|
||||||
|
window->render_pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_callback_listener listener = {
|
static const struct wl_callback_listener listener = {
|
||||||
frame_callback
|
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
|
void
|
||||||
bm_wl_window_render(struct window *window, struct wl_display *display, const struct bm_menu *menu)
|
bm_wl_window_render(struct window *window, struct wl_display *display, const struct bm_menu *menu)
|
||||||
{
|
{
|
||||||
assert(window && menu);
|
assert(window && menu);
|
||||||
|
|
||||||
struct buffer *buffer;
|
struct buffer *buffer;
|
||||||
for (int tries = 0; tries < 2; ++tries) {
|
for (int tries = 0; tries < 2; ++tries) {
|
||||||
if (!(buffer = next_buffer(window))) {
|
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);
|
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_damage(window->surface, 0, 0, buffer->width, buffer->height);
|
||||||
wl_surface_attach(window->surface, buffer->buffer, 0, 0);
|
wl_surface_attach(window->surface, buffer->buffer, 0, 0);
|
||||||
wl_surface_commit(window->surface);
|
wl_surface_commit(window->surface);
|
||||||
buffer->busy = true;
|
buffer->busy = true;
|
||||||
|
window->render_pending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user