From c29ba798517763c194f22c1dbaef84fa4c5efa3f Mon Sep 17 00:00:00 2001 From: Mariusz Bialonczyk Date: Sat, 30 Dec 2023 13:00:37 +0100 Subject: [PATCH] [uwac] add scaling support using `viewporter` protocol Wayland compositors can support the wp_viewporter protocol, which allows for the mapping of arbitrarily sized buffer regions to output surfaces. This result in correct scaling on HiDPI outputs with scaling enabled. --- uwac/libuwac/uwac-priv.h | 1 + uwac/libuwac/uwac-window.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/uwac/libuwac/uwac-priv.h b/uwac/libuwac/uwac-priv.h index 71b73292d..68799f4af 100644 --- a/uwac/libuwac/uwac-priv.h +++ b/uwac/libuwac/uwac-priv.h @@ -250,6 +250,7 @@ struct uwac_window ssize_t drawingBufferIdx; ssize_t pendingBufferIdx; struct wl_surface* surface; + struct wp_viewport* viewport; struct wl_shell_surface* shell_surface; struct xdg_surface* xdg_surface; struct xdg_toplevel* xdg_toplevel; diff --git a/uwac/libuwac/uwac-window.c b/uwac/libuwac/uwac-window.c index 072d53052..4a54a4bc2 100644 --- a/uwac/libuwac/uwac-window.c +++ b/uwac/libuwac/uwac-window.c @@ -87,6 +87,9 @@ static void xdg_handle_toplevel_configure(void* data, struct xdg_toplevel* xdg_t int32_t width, int32_t height, struct wl_array* states) { UwacWindow* window = (UwacWindow*)data; + int scale = window->display->actual_scale; + width *= scale; + height *= scale; UwacConfigureEvent* event; int ret, surfaceState; enum xdg_toplevel_state* state; @@ -150,6 +153,15 @@ static void xdg_handle_toplevel_configure(void* data, struct xdg_toplevel* xdg_t window->drawingBufferIdx = 0; if (window->pendingBufferIdx != -1) window->pendingBufferIdx = window->drawingBufferIdx; + + if (window->viewport) + { + wp_viewport_set_source(window->viewport, wl_fixed_from_int(0), wl_fixed_from_int(0), + wl_fixed_from_int(window->width * scale), + wl_fixed_from_int(window->height * scale)); + wp_viewport_set_destination(window->viewport, window->width * scale, + window->height * scale); + } } else { @@ -551,6 +563,10 @@ UwacWindow* UwacCreateWindowShm(UwacDisplay* display, uint32_t width, uint32_t h wl_shell_surface_set_toplevel(w->shell_surface); } + w->viewport = wp_viewporter_get_viewport(display->viewporter, w->surface); + if (display->actual_scale != 1) + wl_surface_set_buffer_scale(w->surface, display->actual_scale); + wl_list_insert(display->windows.prev, &w->link); display->last_error = UWAC_SUCCESS; UwacWindowSetDecorations(w); @@ -593,6 +609,9 @@ UwacReturnCode UwacDestroyWindow(UwacWindow** pwindow) if (w->input_region) wl_region_destroy(w->input_region); + if (w->viewport) + wp_viewport_destroy(w->viewport); + wl_surface_destroy(w->surface); wl_list_remove(&w->link); free(w);