summaryrefslogtreecommitdiff
path: root/gdk/wayland/gdksurface-wayland.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2023-04-01 12:48:26 +0200
committerBenjamin Otte <otte@redhat.com>2023-04-01 12:57:03 +0200
commit54e8bd898a55eec8b3ff966482400b9ec47f7a9e (patch)
tree45e88499e1e17d131285ab85cd15ad5448336c91 /gdk/wayland/gdksurface-wayland.c
parent2fb11765c78b2dc4859705de0a83b07cd88a09d2 (diff)
downloadgtk+-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.c47
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);