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.
This commit is contained in:
Benjamin Otte
2023-04-01 12:48:26 +02:00
parent 2fb11765c7
commit 54e8bd898a
5 changed files with 50 additions and 9 deletions

View File

@@ -509,6 +509,14 @@ gdk_registry_handle_global (void *data,
&xdg_activation_v1_interface,
MIN (version, XDG_ACTIVATION_VERSION));
}
else if (strcmp (interface, "wp_fractional_scale_manager_v1") == 0)
{
display_wayland->fractional_scale =
wl_registry_bind (display_wayland->wl_registry, id,
&wp_fractional_scale_manager_v1_interface,
MIN (version, 1));
}
g_hash_table_insert (display_wayland->known_globals,
GUINT_TO_POINTER (id), g_strdup (interface));

View File

@@ -37,6 +37,7 @@
#include <gdk/wayland/idle-inhibit-unstable-v1-client-protocol.h>
#include <gdk/wayland/primary-selection-unstable-v1-client-protocol.h>
#include <gdk/wayland/xdg-activation-v1-client-protocol.h>
#include <gdk/wayland/fractional-scale-v1-client-protocol.h>
#include <glib.h>
#include <gdk/gdkkeys.h>
@@ -111,6 +112,7 @@ struct _GdkWaylandDisplay
struct zxdg_output_manager_v1 *xdg_output_manager;
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
struct xdg_activation_v1 *xdg_activation;
struct wp_fractional_scale_manager_v1 *fractional_scale;
GList *async_roundtrips;

View File

@@ -35,6 +35,7 @@ struct _GdkWaylandSurface
struct xdg_surface *xdg_surface;
struct zxdg_surface_v6 *zxdg_surface_v6;
struct wl_egl_window *egl_window;
struct wp_fractional_scale_v1 *fractional_scale;
} display_server;
struct wl_event_queue *event_queue;

View File

@@ -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)
{
@@ -797,6 +798,24 @@ gdk_wayland_surface_sync_buffer_scale (GdkSurface *surface)
impl->buffer_scale_dirty = FALSE;
}
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,
@@ -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);

View File

@@ -65,6 +65,7 @@ proto_sources = [
['xdg-output', 'unstable', 'v1', ],
['idle-inhibit', 'unstable', 'v1', ],
['xdg-activation', 'staging', 'v1', ],
['fractional-scale', 'staging', 'v1', ],
]
gdk_wayland_gen_headers = []