From 129e1a9b8e23007026d19c970941ccbc8ee2f0ca Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 6 May 2022 20:05:04 +0200 Subject: [PATCH] Add support for xdg_toplevel.wm_capabilities See https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/122 --- CHANGELOG.md | 3 +++ render.c | 6 ++++-- wayland.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- wayland.h | 5 +++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6823e16b..b82cfa00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,12 +56,15 @@ `key-bindings.unicode-input` and `search-bindings.unicode-input` key bindings. Note that there is no visual feedback, as the preferred way of entering Unicode characters is with an IME ([#1116][1116]). +* Support for `xdg_toplevel.wm_capabilities`, to adapt the client-side + decoration buttons to the compositor capabilities ([#1061][1061]). [1058]: https://codeberg.org/dnkl/foot/issues/1058 [1070]: https://codeberg.org/dnkl/foot/issues/1070 [30]: https://codeberg.org/dnkl/foot/issues/30 [1112]: https://codeberg.org/dnkl/foot/issues/1112 [1116]: https://codeberg.org/dnkl/foot/issues/1116 +[1061]: https://codeberg.org/dnkl/foot/pulls/1061 ### Changed diff --git a/render.c b/render.c index 9333deb7..ff82802e 100644 --- a/render.c +++ b/render.c @@ -1726,10 +1726,12 @@ get_csd_data(const struct terminal *term, enum csd_surface surf_idx) const int button_close_width = term->width >= 1 * button_width ? button_width : 0; - const int button_maximize_width = term->width >= 2 * button_width + const int button_maximize_width = + term->width >= 2 * button_width && term->window->wm_capabilities.maximize ? button_width : 0; - const int button_minimize_width = term->width >= 3 * button_width + const int button_minimize_width = + term->width >= 3 * button_width && term->window->wm_capabilities.minimize ? button_width : 0; switch (surf_idx) { diff --git a/wayland.c b/wayland.c index 2d7c303f..fb41cf7d 100644 --- a/wayland.c +++ b/wayland.c @@ -714,10 +714,38 @@ xdg_toplevel_configure_bounds(void *data, /* TODO: ensure we don't pick a bigger size */ } +#if defined(XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION) +static void +xdg_toplevel_wm_capabilities(void *data, + struct xdg_toplevel *xdg_toplevel, + struct wl_array *caps) +{ + struct wl_window *win = data; + + win->wm_capabilities.maximize = false; + win->wm_capabilities.minimize = false; + + uint32_t *cap_ptr; + wl_array_for_each(cap_ptr, caps) { + switch (*cap_ptr) { + case XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE: + win->wm_capabilities.maximize = true; + break; + case XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE: + win->wm_capabilities.minimize = true; + break; + } + } +} +#endif + static const struct xdg_toplevel_listener xdg_toplevel_listener = { .configure = &xdg_toplevel_configure, /*.close = */&xdg_toplevel_close, /* epoll-shim defines a macro ‘close’... */ .configure_bounds = &xdg_toplevel_configure_bounds, +#if defined(XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION) + .wm_capabilities = xdg_toplevel_wm_capabilities, +#endif }; static void @@ -905,13 +933,22 @@ handle_global(void *data, struct wl_registry *registry, return; /* - * We *require* version 1, but _can_ use version 2. Version 2 + * We *require* version 1, but _can_ use version 5. Version 2 * adds 'tiled' window states. We use that information to - * restore the window size when window is un-tiled. + * restore the window size when window is un-tiled. Version 5 + * adds 'wm_capabilities'. We use that information to draw + * window decorations. */ +#if defined(XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION) + const uint32_t preferred = XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION; +#elif defined(XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION) + const uint32_t preferred = XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION; +#else + const uint32_t preferred = required; +#endif wayl->shell = wl_registry_bind( - wayl->registry, name, &xdg_wm_base_interface, min(version, 4)); + wayl->registry, name, &xdg_wm_base_interface, min(version, preferred)); xdg_wm_base_add_listener(wayl->shell, &xdg_wm_base_listener, wayl); } @@ -1427,6 +1464,9 @@ wayl_win_init(struct terminal *term, const char *token) win->csd.move_timeout_fd = -1; win->resize_timeout_fd = -1; + win->wm_capabilities.maximize = true; + win->wm_capabilities.minimize = true; + win->surface = wl_compositor_create_surface(wayl->compositor); if (win->surface == NULL) { LOG_ERR("failed to create wayland surface"); diff --git a/wayland.h b/wayland.h index 803fe390..e86c6a3d 100644 --- a/wayland.h +++ b/wayland.h @@ -339,6 +339,11 @@ struct wl_window { uint32_t serial; } csd; + struct { + bool maximize:1; + bool minimize:1; + } wm_capabilities; + struct wl_surf_subsurf search; struct wl_surf_subsurf scrollback_indicator; struct wl_surf_subsurf render_timer;