From fc2e385d876f53b260d1f8d80db2517b9f2e6e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 30 Apr 2020 17:22:57 +0200 Subject: [PATCH] term: don't enable ptmx FDM callback until Wayland window has been configured The way things works right now, we cannot enable the ptmx FDM callback right away. We need to wait for the Wayland window to have been configured. Before the window is configured, we don't have a size, and no grid. Thus, if we try to process ptmx data we'll crash since we have no where to write it to. So, registering the ptmx fd with the FDM is now delayed until we've received the first 'configure' event from Wayland. --- terminal.c | 25 +++++++++++++++++++++---- terminal.h | 1 + wayland.c | 4 ++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/terminal.c b/terminal.c index 02d175c6..633503d3 100644 --- a/terminal.c +++ b/terminal.c @@ -737,8 +737,13 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl, goto err; } - if (!fdm_add(fdm, ptmx, EPOLLIN, &fdm_ptmx, term) || - !fdm_add(fdm, flash_fd, EPOLLIN, &fdm_flash, term) || + /* + * Enable all FDM callbackes *except* ptmx - we can't do that + * until the window has been 'configured' since we don't have a + * size (and thus no grid) before then. + */ + + if (!fdm_add(fdm, flash_fd, EPOLLIN, &fdm_flash, term) || !fdm_add(fdm, blink_fd, EPOLLIN, &fdm_blink, term) || !fdm_add(fdm, cursor_blink_fd, EPOLLIN, &fdm_cursor_blink, term) || !fdm_add(fdm, delay_lower_fd, EPOLLIN, &fdm_delayed_render, term) || @@ -905,7 +910,7 @@ err: return NULL; close_fds: - fdm_del(fdm, ptmx); + close(ptmx); fdm_del(fdm, flash_fd); fdm_del(fdm, blink_fd); fdm_del(fdm, cursor_blink_fd); @@ -917,6 +922,14 @@ close_fds: return NULL; } +void +term_window_configured(struct terminal *term) +{ + /* Enable ptmx FDM callback */ + assert(term->window->is_configured); + fdm_add(term->fdm, term->ptmx, EPOLLIN, &fdm_ptmx, term); +} + static bool fdm_shutdown(struct fdm *fdm, int fd, int events, void *data) { @@ -978,7 +991,11 @@ term_shutdown(struct terminal *term) fdm_del(term->fdm, term->cursor_blink.fd); fdm_del(term->fdm, term->blink.fd); fdm_del(term->fdm, term->flash.fd); - fdm_del(term->fdm, term->ptmx); + + if (term->window != NULL && term->window->is_configured) + fdm_del(term->fdm, term->ptmx); + else + close(term->ptmx); term->render.app_sync_updates.timer_fd = -1; term->delayed_render_timer.lower_fd = -1; diff --git a/terminal.h b/terminal.h index 7fcede70..7152bc23 100644 --- a/terminal.h +++ b/terminal.h @@ -444,6 +444,7 @@ bool term_font_size_reset(struct terminal *term); bool term_font_dpi_changed(struct terminal *term); void term_font_subpixel_changed(struct terminal *term); +void term_window_configured(struct terminal *term); void term_damage_rows(struct terminal *term, int start, int end); void term_damage_rows_in_view(struct terminal *term, int start, int end); diff --git a/wayland.c b/wayland.c index 594e78cd..5619c7e6 100644 --- a/wayland.c +++ b/wayland.c @@ -454,6 +454,7 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, struct wl_window *win = data; struct terminal *term = win->term; + bool wasnt_configured = !win->is_configured; win->is_configured = true; win->is_maximized = win->configure.is_maximized; @@ -481,6 +482,9 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, */ wl_surface_commit(win->surface); } + + if (wasnt_configured) + term_window_configured(term); } static const struct xdg_surface_listener xdg_surface_listener = {