From 9a0238bb524668c3ea24465943cd231167ae1428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 3 Jan 2020 13:37:03 +0100 Subject: [PATCH 1/7] wayland: window now keeps pointer to owning terminal, not wayland --- terminal.c | 2 +- wayland.c | 12 +++++++----- wayland.h | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/terminal.c b/terminal.c index b31d3867..d1853c18 100644 --- a/terminal.c +++ b/terminal.c @@ -654,7 +654,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl, goto err; /* Initialize the Wayland window backend */ - if ((term->window = wayl_win_init(wayl)) == NULL) + if ((term->window = wayl_win_init(term)) == NULL) goto err; /* Let the Wayland backend know we exist */ diff --git a/wayland.c b/wayland.c index 415d8292..18db638a 100644 --- a/wayland.c +++ b/wayland.c @@ -825,10 +825,12 @@ wayl_destroy(struct wayland *wayl) } struct wl_window * -wayl_win_init(struct wayland *wayl) +wayl_win_init(struct terminal *term) { + struct wayland *wayl = term->wl; + struct wl_window *win = calloc(1, sizeof(*win)); - win->wayl = wayl; + win->term = term; win->surface = wl_compositor_create_surface(wayl->compositor); if (win->surface == NULL) { @@ -887,12 +889,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->wayl->display); + wl_display_roundtrip(win->term->wl->display); /* Main window */ wl_surface_attach(win->surface, NULL, 0, 0); wl_surface_commit(win->surface); - wl_display_roundtrip(win->wayl->display); + wl_display_roundtrip(win->term->wl->display); tll_free(win->on_outputs); if (win->search_sub_surface != NULL) @@ -910,7 +912,7 @@ wayl_win_destroy(struct wl_window *win) if (win->surface != NULL) wl_surface_destroy(win->surface); - wl_display_roundtrip(win->wayl->display); + wl_display_roundtrip(win->term->wl->display); free(win); } diff --git a/wayland.h b/wayland.h index dfdcfffd..b47bf0c3 100644 --- a/wayland.h +++ b/wayland.h @@ -84,7 +84,7 @@ struct wl_primary { struct wayland; struct wl_window { - struct wayland *wayl; + struct terminal *term; struct wl_surface *surface; struct xdg_surface *xdg_surface; struct xdg_toplevel *xdg_toplevel; @@ -181,5 +181,5 @@ struct terminal *wayl_terminal_from_xdg_toplevel( /* TODO: pass something other than 'term'? Need scale... */ bool wayl_cursor_set(struct wayland *wayl, const struct terminal *term); -struct wl_window *wayl_win_init(struct wayland *wayl); +struct wl_window *wayl_win_init(struct terminal *term); void wayl_win_destroy(struct wl_window *win); From 9372fb41666f21a96c300793e7b4b6721eb1a838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 3 Jan 2020 13:40:37 +0100 Subject: [PATCH 2/7] wayland: window: pass window pointer to wl-surface callbacks --- wayland.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/wayland.c b/wayland.c index 18db638a..50e2c0ff 100644 --- a/wayland.c +++ b/wayland.c @@ -361,10 +361,10 @@ static void surface_enter(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output) { - struct wayland *wayl = data; - struct terminal *term = wayl_terminal_from_surface(wayl, wl_surface); + struct wl_window *win = data; + struct terminal *term = win->term; - tll_foreach(wayl->monitors, it) { + tll_foreach(term->wl->monitors, it) { if (it->item.output == wl_output) { LOG_DBG("mapped on %s", it->item.name); tll_push_back(term->window->on_outputs, &it->item); @@ -372,7 +372,7 @@ surface_enter(void *data, struct wl_surface *wl_surface, /* Resize, since scale-to-use may have changed */ int scale = term->scale; render_resize(term, term->width / scale, term->height / scale, true); - wayl_reload_cursor_theme(wayl, term); + wayl_reload_cursor_theme(term->wl, term); return; } } @@ -384,8 +384,8 @@ static void surface_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output) { - struct wayland *wayl = data; - struct terminal *term = wayl_terminal_from_surface(wayl, wl_surface); + struct wl_window *win = data; + struct terminal *term = win->term; tll_foreach(term->window->on_outputs, it) { if (it->item->output != wl_output) @@ -397,7 +397,7 @@ surface_leave(void *data, struct wl_surface *wl_surface, /* Resize, since scale-to-use may have changed */ int scale = term->scale; render_resize(term, term->width / scale, term->height / scale, true); - wayl_reload_cursor_theme(wayl, term); + wayl_reload_cursor_theme(term->wl, term); return; } @@ -838,7 +838,7 @@ wayl_win_init(struct terminal *term) goto out; } - wl_surface_add_listener(win->surface, &surface_listener, wayl); + wl_surface_add_listener(win->surface, &surface_listener, win); win->xdg_surface = xdg_wm_base_get_xdg_surface(wayl->shell, win->surface); xdg_surface_add_listener(win->xdg_surface, &xdg_surface_listener, wayl); From ea002ad5712f01e085c888cd551d7e03ac4435bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 3 Jan 2020 13:41:35 +0100 Subject: [PATCH 3/7] wayland: window: pass window pointer to xdg-surface-listener callbacks --- wayland.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wayland.c b/wayland.c index 50e2c0ff..2fcfb5be 100644 --- a/wayland.c +++ b/wayland.c @@ -509,8 +509,9 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, * * So, refresh here, to ensure changes take effect as soon as possible. */ - struct wayland *wayl = data; - struct terminal *term = wayl_terminal_from_xdg_surface(wayl, xdg_surface); + struct wl_window *win = data; + struct terminal *term = win->term; + if (term->width > 0 && term->height > 0) render_refresh(term); } @@ -841,7 +842,7 @@ wayl_win_init(struct terminal *term) wl_surface_add_listener(win->surface, &surface_listener, win); win->xdg_surface = xdg_wm_base_get_xdg_surface(wayl->shell, win->surface); - xdg_surface_add_listener(win->xdg_surface, &xdg_surface_listener, wayl); + xdg_surface_add_listener(win->xdg_surface, &xdg_surface_listener, win); win->xdg_toplevel = xdg_surface_get_toplevel(win->xdg_surface); xdg_toplevel_add_listener(win->xdg_toplevel, &xdg_toplevel_listener, wayl); From b0fbc064ddcd7eac46a6980b56bb8d17958aa3ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 3 Jan 2020 13:46:15 +0100 Subject: [PATCH 4/7] wayland: window: pass window pointer to xdg toplevel callbacks --- wayland.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wayland.c b/wayland.c index 2fcfb5be..51e9079f 100644 --- a/wayland.c +++ b/wayland.c @@ -467,8 +467,8 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, width, height, state_str); #endif - struct wayland *wayl = data; - struct terminal *term = wayl_terminal_from_xdg_toplevel(wayl, xdg_toplevel); + struct wl_window *win = data; + struct terminal *term = win->term; if (is_focused) term_visual_focus_in(term); @@ -481,8 +481,8 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, static void xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) { - struct wayland *wayl = data; - struct terminal *term = wayl_terminal_from_xdg_toplevel(wayl, xdg_toplevel); + struct wl_window *win = data; + struct terminal *term = win->term; LOG_DBG("xdg-toplevel: close"); term_shutdown(term); } @@ -845,7 +845,7 @@ wayl_win_init(struct terminal *term) xdg_surface_add_listener(win->xdg_surface, &xdg_surface_listener, win); win->xdg_toplevel = xdg_surface_get_toplevel(win->xdg_surface); - xdg_toplevel_add_listener(win->xdg_toplevel, &xdg_toplevel_listener, wayl); + xdg_toplevel_add_listener(win->xdg_toplevel, &xdg_toplevel_listener, win); xdg_toplevel_set_app_id(win->xdg_toplevel, "foot"); @@ -855,7 +855,7 @@ wayl_win_init(struct terminal *term) zxdg_toplevel_decoration_v1_set_mode( win->xdg_toplevel_decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); zxdg_toplevel_decoration_v1_add_listener( - win->xdg_toplevel_decoration, &xdg_toplevel_decoration_listener, wayl); + win->xdg_toplevel_decoration, &xdg_toplevel_decoration_listener, win); /* Scrollback search box */ win->search_surface = wl_compositor_create_surface(wayl->compositor); From 765fe13aff4b9e9b3b1f487a6595a421efbd26b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 3 Jan 2020 13:46:37 +0100 Subject: [PATCH 5/7] wayland: remove wayl_terminal_from_xdg_{surface,toplevel} --- wayland.c | 26 -------------------------- wayland.h | 4 ---- 2 files changed, 30 deletions(-) diff --git a/wayland.c b/wayland.c index 51e9079f..a015fdb6 100644 --- a/wayland.c +++ b/wayland.c @@ -1006,29 +1006,3 @@ wayl_terminal_from_surface(struct wayland *wayl, struct wl_surface *surface) LOG_WARN("surface %p doesn't map to a terminal", surface); return NULL; } - -struct terminal * -wayl_terminal_from_xdg_surface(struct wayland *wayl, - struct xdg_surface *surface) -{ - tll_foreach(wayl->terms, it) { - if (it->item->window->xdg_surface == surface) - return it->item; - } - - assert(false); - return NULL; -} - -struct terminal * -wayl_terminal_from_xdg_toplevel(struct wayland *wayl, - struct xdg_toplevel *toplevel) -{ - tll_foreach(wayl->terms, it) { - if (it->item->window->xdg_toplevel == toplevel) - return it->item; - } - - assert(false); - return NULL; -} diff --git a/wayland.h b/wayland.h index b47bf0c3..99b678fb 100644 --- a/wayland.h +++ b/wayland.h @@ -173,10 +173,6 @@ void wayl_destroy(struct wayland *wayl); struct terminal *wayl_terminal_from_surface( struct wayland *wayl, struct wl_surface *surface); -struct terminal *wayl_terminal_from_xdg_surface( - struct wayland *wayl, struct xdg_surface *surface); -struct terminal *wayl_terminal_from_xdg_toplevel( - struct wayland *wayl, struct xdg_toplevel *toplevel); /* TODO: pass something other than 'term'? Need scale... */ bool wayl_cursor_set(struct wayland *wayl, const struct terminal *term); From 46c434d3f10f0312211c2dc1360aed3e2ad0001b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 3 Jan 2020 13:54:44 +0100 Subject: [PATCH 6/7] wayland: window: apply all configure changes after acking the event --- wayland.c | 41 +++++++++++++++++++---------------------- wayland.h | 6 ++++++ 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/wayland.c b/wayland.c index a015fdb6..033670df 100644 --- a/wayland.c +++ b/wayland.c @@ -413,7 +413,8 @@ static void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states) { - bool is_focused = false; + bool is_activated = false; + #if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG char state_str[2048]; int state_chars = 0; @@ -434,7 +435,7 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, wl_array_for_each(state, states) { switch (*state) { case XDG_TOPLEVEL_STATE_ACTIVATED: - is_focused = true; + is_activated = true; break; case XDG_TOPLEVEL_STATE_MAXIMIZED: @@ -467,15 +468,17 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, width, height, state_str); #endif + /* + * Changes done here are ignored until the configure event has + * been ack:ed in xdg_surface_configure(). + * + * So, just store the config data and apply it later, in + * xdg_surface_configure() after we've ack:ed the event. + */ struct wl_window *win = data; - struct terminal *term = win->term; - - if (is_focused) - term_visual_focus_in(term); - else - term_visual_focus_out(term); - - render_resize(term, width, height, false); + win->configure.is_activated = is_activated; + win->configure.width = width; + win->configure.height = height; } static void @@ -499,21 +502,15 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, LOG_DBG("xdg-surface: configure"); xdg_surface_ack_configure(xdg_surface, serial); - /* - * Changes done in e.g. xdg-toplevel-configure will be ignored - * since the 'configure' event hasn't been ack:ed yet. - * - * Unfortunately, *this* function is called *last*, meaning we - * have no way of acking the configure before we resize the - * terminal in xdg-toplevel-configure. - * - * So, refresh here, to ensure changes take effect as soon as possible. - */ struct wl_window *win = data; struct terminal *term = win->term; - if (term->width > 0 && term->height > 0) - render_refresh(term); + if (win->configure.is_activated) + term_visual_focus_in(term); + else + term_visual_focus_out(term); + + render_resize(term, win->configure.width, win->configure.height, true); } static const struct xdg_surface_listener xdg_surface_listener = { diff --git a/wayland.h b/wayland.h index 99b678fb..f802bcc7 100644 --- a/wayland.h +++ b/wayland.h @@ -98,6 +98,12 @@ struct wl_window { struct wl_callback *frame_callback; tll(const struct monitor *) on_outputs; /* Outputs we're mapped on */ + + struct { + bool is_activated; + int width; + int height; + } configure; }; struct config; From d07fd7de39d588f79da307a9d112e445af86869a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 3 Jan 2020 13:56:10 +0100 Subject: [PATCH 7/7] render: remove 'refresh' from render_resize() --- render.c | 5 ++--- render.h | 2 +- terminal.c | 2 +- wayland.c | 8 ++++---- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/render.c b/render.c index e54da4b5..5e7ef233 100644 --- a/render.c +++ b/render.c @@ -960,7 +960,7 @@ reflow(struct row **new_grid, int new_cols, int new_rows, /* Move to terminal.c? */ void -render_resize(struct terminal *term, int width, int height, bool refresh) +render_resize(struct terminal *term, int width, int height) { if (width == 0 || height == 0) return; @@ -1086,8 +1086,7 @@ render_resize(struct terminal *term, int width, int height, bool refresh) term->render.last_cursor.cell = NULL; term_damage_view(term); - if (refresh) - render_refresh(term); + render_refresh(term); } void diff --git a/render.h b/render.h index e3253074..ad6b6578 100644 --- a/render.h +++ b/render.h @@ -6,7 +6,7 @@ struct font *attrs_to_font( const struct terminal *term, const struct attributes *attrs); void grid_render(struct terminal *term); -void render_resize(struct terminal *term, int width, int height, bool refresh); +void render_resize(struct terminal *term, int width, int height); void render_set_title(struct terminal *term, const char *title); void render_refresh(struct terminal *term); diff --git a/terminal.c b/terminal.c index d1853c18..88a4374a 100644 --- a/terminal.c +++ b/terminal.c @@ -679,7 +679,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl, /* Don't go below a single cell */ width = max(width, term->cell_width); height = max(height, term->cell_height); - render_resize(term, width, height, true); + render_resize(term, width, height); return term; diff --git a/wayland.c b/wayland.c index 033670df..4b419684 100644 --- a/wayland.c +++ b/wayland.c @@ -144,7 +144,7 @@ output_scale(void *data, struct wl_output *wl_output, int32_t factor) struct terminal *term = it->item; int scale = term->scale; - render_resize(term, term->width / scale, term->height / scale, true); + render_resize(term, term->width / scale, term->height / scale); wayl_reload_cursor_theme(mon->wayl, term); } } @@ -371,7 +371,7 @@ surface_enter(void *data, struct wl_surface *wl_surface, /* Resize, since scale-to-use may have changed */ int scale = term->scale; - render_resize(term, term->width / scale, term->height / scale, true); + render_resize(term, term->width / scale, term->height / scale); wayl_reload_cursor_theme(term->wl, term); return; } @@ -396,7 +396,7 @@ surface_leave(void *data, struct wl_surface *wl_surface, /* Resize, since scale-to-use may have changed */ int scale = term->scale; - render_resize(term, term->width / scale, term->height / scale, true); + render_resize(term, term->width / scale, term->height / scale); wayl_reload_cursor_theme(term->wl, term); return; } @@ -510,7 +510,7 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, else term_visual_focus_out(term); - render_resize(term, win->configure.width, win->configure.height, true); + render_resize(term, win->configure.width, win->configure.height); } static const struct xdg_surface_listener xdg_surface_listener = {