From 7e3da3007bb2459900d2c88d3ec11aecd1956849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 9 Jan 2024 22:51:17 -0600 Subject: [PATCH] wayland: use wl_compositor version 6 when available --- terminal.c | 25 ++++++++++++++++++------- terminal.h | 1 + wayland.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- wayland.h | 3 +++ 4 files changed, 66 insertions(+), 10 deletions(-) diff --git a/terminal.c b/terminal.c index 5d0dc01d..7a51257d 100644 --- a/terminal.c +++ b/terminal.c @@ -2071,6 +2071,12 @@ term_fractional_scaling(const struct terminal *term) return term->wl->fractional_scale_manager != NULL && term->window->scale > 0.; } +bool +term_preferred_buffer_scale(const struct terminal *term) +{ + return term->wl->has_wl_compositor_v6; +} + bool term_update_scale(struct terminal *term) { @@ -2081,6 +2087,9 @@ term_update_scale(struct terminal *term) * the scale in the following order: * * - “preferred” scale, from the fractional-scale-v1 protocol + * - "preferred" scale, from wl_compositor version 6. + NOTE: if the compositor advertises version 6 we must use 1.0 + until wl_surface.preferred_buffer_scale is sent * - scaling factor of output we most recently were mapped on * - if we're not mapped, use the last known scaling factor * - if we're not mapped, and we don't have a last known scaling @@ -2090,13 +2099,15 @@ term_update_scale(struct terminal *term) */ const float new_scale = (term_fractional_scaling(term) ? win->scale - : tll_length(win->on_outputs) > 0 - ? tll_back(win->on_outputs)->scale - : term->scale_before_unmap > 0. - ? term->scale_before_unmap - : tll_length(term->wl->monitors) > 0 - ? tll_front(term->wl->monitors).scale - : 1.); + : term_preferred_buffer_scale(term) + ? win->preferred_buffer_scale + : tll_length(win->on_outputs) > 0 + ? tll_back(win->on_outputs)->scale + : term->scale_before_unmap > 0. + ? term->scale_before_unmap + : tll_length(term->wl->monitors) > 0 + ? tll_front(term->wl->monitors).scale + : 1.); if (new_scale == term->scale) return false; diff --git a/terminal.h b/terminal.h index ddd4f1ea..0dca0f48 100644 --- a/terminal.h +++ b/terminal.h @@ -743,6 +743,7 @@ bool term_paste_data_to_slave( struct terminal *term, const void *data, size_t len); bool term_fractional_scaling(const struct terminal *term); +bool term_preferred_buffer_scale(const struct terminal *term); bool term_update_scale(struct terminal *term); bool term_font_size_increase(struct terminal *term); bool term_font_size_decrease(struct terminal *term); diff --git a/wayland.c b/wayland.c index 34050d18..24d70235 100644 --- a/wayland.c +++ b/wayland.c @@ -705,9 +705,37 @@ surface_leave(void *data, struct wl_surface *wl_surface, LOG_WARN("unmapped from unknown output"); } +#if defined(WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION) +static void +surface_preferred_buffer_scale(void *data, struct wl_surface *surface, + int32_t scale) +{ + struct wl_window *win = data; + + if (win->preferred_buffer_scale == scale) + return; + + LOG_DBG("wl_surface preferred scale: %d -> %d", win->preferred_buffer_scale, scale); + + win->preferred_buffer_scale = scale; + update_term_for_output_change(win->term); +} + +static void +surface_preferred_buffer_transform(void *data, struct wl_surface *surface, + uint32_t transform) +{ + +} +#endif + static const struct wl_surface_listener surface_listener = { .enter = &surface_enter, .leave = &surface_leave, +#if defined(WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION) + .preferred_buffer_scale = &surface_preferred_buffer_scale, + .preferred_buffer_transform = &surface_preferred_buffer_transform, +#endif }; static void @@ -1057,8 +1085,14 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; +#if defined (WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION) + const uint32_t preferred = WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION; + wayl->has_wl_compositor_v6 = version >= WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION; +#else + const uint32_t preferred = required; +#endif wayl->compositor = wl_registry_bind( - wayl->registry, name, &wl_compositor_interface, required); + wayl->registry, name, &wl_compositor_interface, min(version, preferred)); } else if (strcmp(interface, wl_subcompositor_interface.name) == 0) { @@ -1700,6 +1734,10 @@ wayl_win_init(struct terminal *term, const char *token) win->fractional_scale, &fractional_scale_listener, win); } + if (wayl->has_wl_compositor_v6) { + win->preferred_buffer_scale = 1; + } + win->xdg_surface = xdg_wm_base_get_xdg_surface(wayl->shell, win->surface.surf); xdg_surface_add_listener(win->xdg_surface, &xdg_surface_listener, win); @@ -2020,8 +2058,11 @@ surface_scale_explicit_width_height( wp_viewport_set_destination( surf->viewport, roundf(width / scale), roundf(height / scale)); } else { - LOG_DBG("scaling by a factor of %.2f using legacy mode " - "(width=%d, height=%d)", scale, width, height); + const char *mode = term_preferred_buffer_scale(win->term) + ? "wl_surface.preferred_buffer_scale" + : "legacy mode"; + LOG_DBG("scaling by a factor of %.2f using %s " + "(width=%d, height=%d)" , scale, mode, width, height); xassert(scale == floorf(scale)); const int iscale = (int)floorf(scale); diff --git a/wayland.h b/wayland.h index 67aadec2..145e480d 100644 --- a/wayland.h +++ b/wayland.h @@ -363,6 +363,7 @@ struct wl_window { bool unmapped; float scale; + int preferred_buffer_scale; struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration; @@ -429,6 +430,8 @@ struct wayland { struct wl_subcompositor *sub_compositor; struct wl_shm *shm; + bool has_wl_compositor_v6; + struct zxdg_output_manager_v1 *xdg_output_manager; struct xdg_wm_base *shell;