diff options
author | Benjamin Otte <otte@redhat.com> | 2023-04-01 12:48:26 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2023-04-01 12:57:03 +0200 |
commit | 54e8bd898a55eec8b3ff966482400b9ec47f7a9e (patch) | |
tree | 45e88499e1e17d131285ab85cd15ad5448336c91 /gdk/wayland/gdksurface-wayland.c | |
parent | 2fb11765c78b2dc4859705de0a83b07cd88a09d2 (diff) | |
download | gtk+-54e8bd898a55eec8b3ff966482400b9ec47f7a9e.tar.gz |
wayland: Add support for the fractional scale protocol
April fools!
No, really.
The fractional scale protocol is just a way to track the surface scale,
but not a way to draw fractional content.
This commit uses it for that, so tht we don't rely on tracking outputs.
This also allows magnifiers etc to send us a larger (integer) scale if
they would like that, that is not represented by the outputs.
Diffstat (limited to 'gdk/wayland/gdksurface-wayland.c')
-rw-r--r-- | gdk/wayland/gdksurface-wayland.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 38d3cb54e0..7c952af083 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -28,7 +28,6 @@ #include "gdkmonitor-wayland.h" #include "gdkpopupprivate.h" #include "gdkprivate-wayland.h" -#include "gdkprivate-wayland.h" #include "gdkseat-wayland.h" #include "gdksurfaceprivate.h" #include "gdktoplevelprivate.h" @@ -426,12 +425,14 @@ gdk_wayland_surface_update_scale (GdkSurface *surface) guint32 scale; GSList *l; + /* We can't set the scale on this surface */ if (!impl->display_server.wl_surface || wl_surface_get_version (impl->display_server.wl_surface) < WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) - { - /* We can't set the scale on this surface */ - return; - } + return; + + /* scale is tracked by the fractional scale extension */ + if (impl->display_server.fractional_scale) + return; if (!impl->display_server.outputs) { @@ -798,6 +799,24 @@ gdk_wayland_surface_sync_buffer_scale (GdkSurface *surface) } static void +gdk_wayland_surface_fractional_scale_preferred_scale_cb (void *data, + struct wp_fractional_scale_v1 *fractional_scale, + uint32_t scale) +{ + GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (data); + GdkSurface *surface = GDK_SURFACE (self); + + /* Notify app that scale changed */ + gdk_wayland_surface_maybe_resize (surface, + surface->width, surface->height, + ceil (scale / 120.0)); +} + +static const struct wp_fractional_scale_v1_listener fractional_scale_listener = { + gdk_wayland_surface_fractional_scale_preferred_scale_cb, +}; + +static void surface_enter (void *data, struct wl_surface *wl_surface, struct wl_output *output) @@ -848,15 +867,23 @@ static const struct wl_surface_listener surface_listener = { void gdk_wayland_surface_create_wl_surface (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); struct wl_surface *wl_surface; wl_surface = wl_compositor_create_surface (display_wayland->compositor); - wl_proxy_set_queue ((struct wl_proxy *) wl_surface, impl->event_queue); - wl_surface_add_listener (wl_surface, &surface_listener, surface); + wl_proxy_set_queue ((struct wl_proxy *) wl_surface, self->event_queue); + wl_surface_add_listener (wl_surface, &surface_listener, self); + if (display_wayland->fractional_scale) + { + self->display_server.fractional_scale = + wp_fractional_scale_manager_v1_get_fractional_scale (display_wayland->fractional_scale, + wl_surface); + wp_fractional_scale_v1_add_listener (self->display_server.fractional_scale, + &fractional_scale_listener, self); + } - impl->display_server.wl_surface = wl_surface; + self->display_server.wl_surface = wl_surface; } static void @@ -1024,6 +1051,8 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) impl->initial_configure_received = FALSE; } + g_clear_pointer (&impl->display_server.fractional_scale, wp_fractional_scale_v1_destroy); + g_clear_pointer (&impl->display_server.wl_surface, wl_surface_destroy); g_slist_free (impl->display_server.outputs); |