From de1a8c8d892e66bad916da776f7a6803161ce5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 4 Aug 2020 16:52:20 +0200 Subject: [PATCH] wayland: Add support for xdg_toplevel.bounds The GdkToplevelSize struct already has the concept of "bounds", which means the largest size a window should reasonably have. It's practically the equivalent of the monitor the window is intended to be mapped on, with the "struts" (e.g. panels) cut out. It's used by GTK to use this information to calculate a default window size that is "lagom" (swedish; not too large, not too small). --- gdk/wayland/gdkdisplay-wayland.c | 2 +- gdk/wayland/gdksurface-wayland.c | 53 +++++++++++++++++++++++++++----- meson.build | 2 +- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 64d61a8983..9079c6ddd3 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -623,7 +623,7 @@ _gdk_wayland_display_open (const char *display_name) wl_registry_bind (display_wayland->wl_registry, display_wayland->xdg_wm_base_id, &xdg_wm_base_interface, - MIN (display_wayland->xdg_wm_base_version, 3)); + MIN (display_wayland->xdg_wm_base_version, 4)); xdg_wm_base_add_listener (display_wayland->xdg_wm_base, &xdg_wm_base_listener, display_wayland); diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 0b3315075e..d35ffb2299 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -168,6 +168,10 @@ struct _GdkWaylandSurface struct { GdkToplevelLayout *layout; + + int bounds_width; + int bounds_height; + gboolean has_bounds; } toplevel; struct { @@ -182,6 +186,10 @@ struct _GdkWaylandSurface int height; GdkToplevelState state; gboolean is_resizing; + + int bounds_width; + int bounds_height; + gboolean has_bounds; } toplevel; struct { @@ -1394,19 +1402,28 @@ configure_toplevel_geometry (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); GdkDisplay *display = gdk_surface_get_display (surface); - GdkMonitor *monitor; - GdkRectangle monitor_geometry; int bounds_width, bounds_height; GdkToplevelSize size; GdkToplevelLayout *layout; GdkGeometry geometry; GdkSurfaceHints mask; - monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0); - gdk_monitor_get_geometry (monitor, &monitor_geometry); - g_object_unref (monitor); - bounds_width = monitor_geometry.width; - bounds_height = monitor_geometry.height; + if (impl->toplevel.has_bounds) + { + bounds_width = impl->toplevel.bounds_width; + bounds_height = impl->toplevel.bounds_height; + } + else + { + GdkMonitor *monitor; + GdkRectangle monitor_geometry; + + monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0); + gdk_monitor_get_geometry (monitor, &monitor_geometry); + bounds_width = monitor_geometry.width; + bounds_height = monitor_geometry.height; + g_object_unref (monitor); + } gdk_toplevel_size_init (&size, bounds_width, bounds_height); gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size); @@ -1508,6 +1525,13 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface) is_resizing = impl->pending.toplevel.is_resizing; impl->pending.toplevel.is_resizing = FALSE; + if (impl->pending.toplevel.has_bounds) + { + impl->toplevel.bounds_width = impl->pending.toplevel.bounds_width; + impl->toplevel.bounds_height = impl->pending.toplevel.bounds_height; + impl->toplevel.has_bounds = TRUE; + } + fixed_size = new_state & (GDK_TOPLEVEL_STATE_MAXIMIZED | GDK_TOPLEVEL_STATE_FULLSCREEN | @@ -1847,9 +1871,24 @@ xdg_toplevel_close (void *data, gdk_wayland_surface_handle_close (surface); } +static void +xdg_toplevel_configure_bounds (void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height) +{ + GdkSurface *surface = GDK_SURFACE (data); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + impl->pending.toplevel.bounds_width = width; + impl->pending.toplevel.bounds_height = height; + impl->pending.toplevel.has_bounds = TRUE; +} + static const struct xdg_toplevel_listener xdg_toplevel_listener = { xdg_toplevel_configure, xdg_toplevel_close, + xdg_toplevel_configure_bounds, }; static void diff --git a/meson.build b/meson.build index b7a6cb742f..896a1bba60 100644 --- a/meson.build +++ b/meson.build @@ -17,7 +17,7 @@ fribidi_req = '>= 0.19.7' cairo_req = '>= 1.14.0' gdk_pixbuf_req = '>= 2.30.0' introspection_req = '>= 1.39.0' -wayland_proto_req = '>= 1.23' +wayland_proto_req = '>= 1.25' wayland_req = '>= 1.20.0' graphene_req = '>= 1.9.1' epoxy_req = '>= 1.4'