diff --git a/terminal.c b/terminal.c index 6d2f7a04..463ceb90 100644 --- a/terminal.c +++ b/terminal.c @@ -659,9 +659,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl, /* Let the Wayland backend know we exist */ tll_push_back(wayl->terms, term); - - /* Roundtrip to ensure the wayland window have been configured */ - wl_display_roundtrip(term->wl->display); + wayl_roundtrip(term->wl); term_set_window_title(term, "foot"); diff --git a/wayland.c b/wayland.c index 3d0a7061..abe7329f 100644 --- a/wayland.c +++ b/wayland.c @@ -559,10 +559,17 @@ static bool fdm_wayl(struct fdm *fdm, int fd, int events, void *data) { struct wayland *wayl = data; - int event_count = wl_display_dispatch(wayl->display); + int event_count = 0; + + if (events & EPOLLIN) + wl_display_read_events(wayl->display); + + while (wl_display_prepare_read(wayl->display) != 0) + wl_display_dispatch_pending(wayl->display); if (events & EPOLLHUP) { LOG_WARN("disconnected from Wayland"); + wl_display_cancel_read(wayl->display); return false; } @@ -711,6 +718,11 @@ wayl_init(const struct config *conf, struct fdm *fdm) goto out; } + if (wl_display_prepare_read(wayl->display) != 0) { + LOG_ERRNO("failed to prepare for reading wayland events"); + goto out; + } + if (!fdm_add(fdm, wl_display_get_fd(wayl->display), EPOLLIN, &fdm_wayl, wayl) || !fdm_add(fdm, wayl->kbd.repeat.fd, EPOLLIN, &fdm_repeat, wayl)) { @@ -889,12 +901,12 @@ wayl_win_destroy(struct wl_window *win) /* Scrollback search */ wl_surface_attach(win->search_surface, NULL, 0, 0); wl_surface_commit(win->search_surface); - wl_display_roundtrip(win->term->wl->display); + wayl_roundtrip(win->term->wl); /* Main window */ wl_surface_attach(win->surface, NULL, 0, 0); wl_surface_commit(win->surface); - wl_display_roundtrip(win->term->wl->display); + wayl_roundtrip(win->term->wl); tll_free(win->on_outputs); if (win->search_sub_surface != NULL) @@ -912,8 +924,7 @@ wayl_win_destroy(struct wl_window *win) if (win->surface != NULL) wl_surface_destroy(win->surface); - wl_display_roundtrip(win->term->wl->display); - + wayl_roundtrip(win->term->wl); free(win); } @@ -1006,3 +1017,14 @@ wayl_terminal_from_surface(struct wayland *wayl, struct wl_surface *surface) LOG_WARN("surface %p doesn't map to a terminal", surface); return NULL; } + +void +wayl_roundtrip(struct wayland *wayl) +{ + wl_display_cancel_read(wayl->display); + wl_display_roundtrip(wayl->display); + + while (wl_display_prepare_read(wayl->display) != 0) + wl_display_dispatch_pending(wayl->display); + wl_display_flush(wayl->display); +} diff --git a/wayland.h b/wayland.h index fd0c36e2..eda9e009 100644 --- a/wayland.h +++ b/wayland.h @@ -178,6 +178,8 @@ struct wayland { struct wayland *wayl_init(const struct config *conf, struct fdm *fdm); void wayl_destroy(struct wayland *wayl); +void wayl_roundtrip(struct wayland *wayl); + struct terminal *wayl_terminal_from_surface( struct wayland *wayl, struct wl_surface *surface);