diff --git a/hosts/Khanda/default.nix b/hosts/Khanda/default.nix index e090267..d021fd0 100644 --- a/hosts/Khanda/default.nix +++ b/hosts/Khanda/default.nix @@ -55,7 +55,10 @@ in ui = { desktops.gnome = { enable = true; - experimental.tripleBuffering.enable = true; + experimental = { + tripleBuffering.enable = true; + vrr.enable = true; + }; }; flatpak = { # Enable Flatpak support. diff --git a/hosts/Shura/default.nix b/hosts/Shura/default.nix index 4b206a4..702c57d 100644 --- a/hosts/Shura/default.nix +++ b/hosts/Shura/default.nix @@ -108,7 +108,10 @@ in }; desktops.gnome = { enable = true; - experimental.fractionalScaling.enable = true; + experimental = { + fractionalScaling.enable = true; + vrr.enable = true; + }; }; }; users = { diff --git a/modules/ui/desktops/gnome.nix b/modules/ui/desktops/gnome.nix index 473766c..9b77497 100644 --- a/modules/ui/desktops/gnome.nix +++ b/modules/ui/desktops/gnome.nix @@ -18,6 +18,7 @@ in experimental = { fractionalScaling.enable = lib.mkEnableOption "Enables fractional scaling."; tripleBuffering.enable = lib.mkEnableOption "Enables dynamic triple buffering for xwayland applications."; + vrr.enable = lib.mkEnableOption "Enables variable refresh rate (VRR)."; }; }; }; @@ -35,14 +36,21 @@ in desktopManager.gnome = { enable = true; - # Enable fractional scaling - extraGSettingsOverrides = lib.mkIf cfg.experimental.fractionalScaling.enable '' - [org.gnome.mutter] - experimental-features=['scale-monitor-framebuffer'] + # Enable experimental features + extraGSettingsOverrides = '' + [org.gnome.mutter] + experimental-features = ${ + lib.strings.concatStrings [ + "[ " + (lib.mkIf cfg.experimental.fractionalScaling.enable "'scale-monitor-framebuffer', ").content + (lib.mkIf cfg.experimental.vrr.enable "'variable-refresh-rate'").content + " ]" + ] + } ''; - extraGSettingsOverridePackages = lib.mkIf cfg.experimental.fractionalScaling.enable [ - pkgs.gnome.mutter - ]; + extraGSettingsOverridePackages = lib.mkIf ( + config.services.xserver.desktopManager.gnome.extraGSettingsOverrides != "" + ) [ pkgs.gnome.mutter ]; }; displayManager.gdm.enable = true; }; @@ -122,7 +130,6 @@ in gnome = prev.gnome.overrideScope ( gnomeFinal: gnomePrev: { mutter = gnomePrev.mutter.overrideAttrs (old: { - # Triple buffering src = inputs.gnome-triplebuffering; }); } diff --git a/modules/ui/desktops/patches/gnome-mutter-xwayland-scaling.patch b/modules/ui/desktops/patches/gnome-mutter-xwayland-scaling.patch deleted file mode 100644 index d584ec6..0000000 --- a/modules/ui/desktops/patches/gnome-mutter-xwayland-scaling.patch +++ /dev/null @@ -1,2124 +0,0 @@ -From 39c3bed5b3b755192f935b88ed0759d91231d13e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Tue, 12 Dec 2023 22:41:20 +0100 -Subject: [PATCH 1/6] x11-display: Expose UI scaling factor via D-Bus - -This replaces the `legacy-ui-scaling-factor` entry in -`org.gnome.Mutter.DisplayConfig`, with the motivation being to no longer -expose X11 specific state via the monitor configuration API. ---- - .../org.gnome.Mutter.DisplayConfig.xml | 4 -- - data/dbus-interfaces/org.gnome.Mutter.X11.xml | 8 +++ - src/backends/meta-monitor-manager.c | 7 -- - src/meson.build | 5 ++ - src/x11/meta-x11-display.c | 64 ++++++++++++++++++- - 5 files changed, 76 insertions(+), 12 deletions(-) - create mode 100644 data/dbus-interfaces/org.gnome.Mutter.X11.xml - -diff --git a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml -index b05337d74..7294c57a8 100644 ---- a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml -+++ b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml -@@ -426,10 +426,6 @@ - always use the same scale. Absence of - this means logical monitor scales can - differ. -- * "legacy-ui-scaling-factor" (i): The legacy scaling factor traditionally -- used to scale X11 clients (commonly -- communicated via the -- Gdk/WindowScalingFactor XSetting entry). - --> - - -diff --git a/data/dbus-interfaces/org.gnome.Mutter.X11.xml b/data/dbus-interfaces/org.gnome.Mutter.X11.xml -new file mode 100644 -index 000000000..3d3c8a42f ---- /dev/null -+++ b/data/dbus-interfaces/org.gnome.Mutter.X11.xml -@@ -0,0 +1,8 @@ -+ -+ -+ -+ -+ -+ -diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c -index 77743bc72..7f98c2d98 100644 ---- a/src/backends/meta-monitor-manager.c -+++ b/src/backends/meta-monitor-manager.c -@@ -2051,14 +2051,12 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, - GDBusMethodInvocation *invocation, - MetaMonitorManager *manager) - { -- MetaSettings *settings = meta_backend_get_settings (manager->backend); - GVariantBuilder monitors_builder; - GVariantBuilder logical_monitors_builder; - GVariantBuilder properties_builder; - GList *l; - int i; - MetaMonitorManagerCapability capabilities; -- int ui_scaling_factor; - int max_screen_width, max_screen_height; - - g_variant_builder_init (&monitors_builder, -@@ -2261,11 +2259,6 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, - g_variant_new_boolean (TRUE)); - } - -- ui_scaling_factor = meta_settings_get_ui_scaling_factor (settings); -- g_variant_builder_add (&properties_builder, "{sv}", -- "legacy-ui-scaling-factor", -- g_variant_new_int32 (ui_scaling_factor)); -- - if (meta_monitor_manager_get_max_screen_size (manager, - &max_screen_width, - &max_screen_height)) -diff --git a/src/meson.build b/src/meson.build -index 05df3bfd2..e658f98ca 100644 ---- a/src/meson.build -+++ b/src/meson.build -@@ -949,6 +949,11 @@ dbus_interfaces = [ - 'interface': 'org.gnome.Mutter.DebugControl.xml', - 'prefix': 'org.gnome.Mutter', - }, -+ { -+ 'name': 'meta-dbus-x11', -+ 'interface': 'org.gnome.Mutter.X11.xml', -+ 'prefix': 'org.gnome.Mutter', -+ }, - ] - - if have_profiler -diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c -index 3cbf82844..fe152d20b 100644 ---- a/src/x11/meta-x11-display.c -+++ b/src/x11/meta-x11-display.c -@@ -70,7 +70,7 @@ - #include "wayland/meta-xwayland-private.h" - #endif - --G_DEFINE_TYPE (MetaX11Display, meta_x11_display, G_TYPE_OBJECT) -+#include "meta-dbus-x11.h" - - static GQuark quark_x11_display_logical_monitor_data = 0; - -@@ -89,6 +89,14 @@ typedef struct _MetaX11DisplayLogicalMonitorData - int xinerama_index; - } MetaX11DisplayLogicalMonitorData; - -+typedef struct _MetaX11DisplayPrivate -+{ -+ MetaDBusX11 *dbus_api; -+ guint dbus_name_id; -+} MetaX11DisplayPrivate; -+ -+G_DEFINE_TYPE_WITH_PRIVATE (MetaX11Display, meta_x11_display, G_TYPE_OBJECT) -+ - static char *get_screen_name (Display *xdisplay, - int number); - -@@ -151,13 +159,46 @@ meta_x11_event_filter_free (MetaX11EventFilter *filter) - g_free (filter); - } - -+static void -+on_bus_acquired (GDBusConnection *connection, -+ const char *name, -+ gpointer user_data) -+{ -+ MetaX11Display *x11_display = user_data; -+ MetaX11DisplayPrivate *priv = -+ meta_x11_display_get_instance_private (x11_display); -+ -+ g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_api), -+ connection, -+ "/org/gnome/Mutter/X11", -+ NULL); -+} -+ -+static void -+update_ui_scaling_factor (MetaX11Display *x11_display) -+{ -+ MetaX11DisplayPrivate *priv = -+ meta_x11_display_get_instance_private (x11_display); -+ MetaBackend *backend = backend_from_x11_display (x11_display); -+ MetaSettings *settings = meta_backend_get_settings (backend); -+ int ui_scaling_factor; -+ -+ ui_scaling_factor = meta_settings_get_ui_scaling_factor (settings); -+ meta_dbus_x11_set_ui_scaling_factor (priv->dbus_api, ui_scaling_factor); -+} -+ - static void - meta_x11_display_dispose (GObject *object) - { - MetaX11Display *x11_display = META_X11_DISPLAY (object); -+ MetaX11DisplayPrivate *priv = -+ meta_x11_display_get_instance_private (x11_display); - - x11_display->closing = TRUE; - -+ g_clear_handle_id (&priv->dbus_name_id, g_bus_unown_name); -+ g_clear_object (&priv->dbus_api); -+ - g_clear_pointer (&x11_display->alarm_filters, g_ptr_array_unref); - - g_clear_list (&x11_display->event_funcs, -@@ -1196,6 +1237,23 @@ meta_x11_display_init_frames_client (MetaX11Display *x11_display) - on_frames_client_died, x11_display); - } - -+static void -+initialize_dbus_interface (MetaX11Display *x11_display) -+{ -+ MetaX11DisplayPrivate *priv = -+ meta_x11_display_get_instance_private (x11_display); -+ -+ priv->dbus_api = meta_dbus_x11_skeleton_new (); -+ priv->dbus_name_id = -+ g_bus_own_name (G_BUS_TYPE_SESSION, -+ "org.gnome.Mutter.X11", -+ G_BUS_NAME_OWNER_FLAGS_NONE, -+ on_bus_acquired, -+ NULL, NULL, -+ x11_display, NULL); -+ update_ui_scaling_factor (x11_display); -+} -+ - /** - * meta_x11_display_new: - * -@@ -1290,6 +1348,8 @@ meta_x11_display_new (MetaDisplay *display, - x11_display = g_object_new (META_TYPE_X11_DISPLAY, NULL); - x11_display->display = display; - -+ initialize_dbus_interface (x11_display); -+ - /* here we use XDisplayName which is what the user - * probably put in, vs. DisplayString(display) which is - * canonicalized by XOpenDisplay() -@@ -1951,6 +2011,8 @@ on_monitors_changed_internal (MetaMonitorManager *monitor_manager, - } - - x11_display->has_xinerama_indices = FALSE; -+ -+ update_ui_scaling_factor (x11_display); - } - - static Bool --- -2.45.2 - - -From 56b2d879990f6660c75b3c8a65ab65c4920f36b1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= -Date: Tue, 20 Feb 2024 23:51:48 +0100 -Subject: [PATCH 2/6] Add an experimental feature for letting Xwayland clients - scale natively - -With the next commits we'll introduce a new mode for scaling of Xwayland apps, -we'll want to put this mode behind an experimental setting though, so add -that setting. ---- - data/org.gnome.mutter.gschema.xml.in | 7 +++++++ - src/backends/meta-settings-private.h | 1 + - src/backends/meta-settings.c | 2 ++ - 3 files changed, 10 insertions(+) - -diff --git a/data/org.gnome.mutter.gschema.xml.in b/data/org.gnome.mutter.gschema.xml.in -index 92c97b12e..18abd8d51 100644 ---- a/data/org.gnome.mutter.gschema.xml.in -+++ b/data/org.gnome.mutter.gschema.xml.in -@@ -5,6 +5,7 @@ - - - -+ - - - - - -diff --git a/src/backends/meta-settings-private.h b/src/backends/meta-settings-private.h -index afbba054a..2081a81b1 100644 ---- a/src/backends/meta-settings-private.h -+++ b/src/backends/meta-settings-private.h -@@ -32,6 +32,7 @@ typedef enum _MetaExperimentalFeature - META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS = (1 << 1), - META_EXPERIMENTAL_FEATURE_AUTOCLOSE_XWAYLAND = (1 << 2), - META_EXPERIMENTAL_FEATURE_VARIABLE_REFRESH_RATE = (1 << 3), -+ META_EXPERIMENTAL_FEATURE_XWAYLAND_NATIVE_SCALING = (1 << 4), - } MetaExperimentalFeature; - - typedef enum _MetaXwaylandExtension -diff --git a/src/backends/meta-settings.c b/src/backends/meta-settings.c -index 3703b23b0..1ae59d636 100644 ---- a/src/backends/meta-settings.c -+++ b/src/backends/meta-settings.c -@@ -296,6 +296,8 @@ experimental_features_handler (GVariant *features_variant, - feature = META_EXPERIMENTAL_FEATURE_AUTOCLOSE_XWAYLAND; - else if (g_str_equal (feature_str, "variable-refresh-rate")) - feature = META_EXPERIMENTAL_FEATURE_VARIABLE_REFRESH_RATE; -+ else if (g_str_equal (feature_str, "xwayland-native-scaling")) -+ feature = META_EXPERIMENTAL_FEATURE_XWAYLAND_NATIVE_SCALING; - - if (feature) - g_message ("Enabling experimental feature '%s'", feature_str); --- -2.45.2 - - -From 19f23f78db32963f6b00697b0e55a155d7572459 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Tue, 12 Dec 2023 22:42:46 +0100 -Subject: [PATCH 3/6] context: Put Wayland compositor getter in the context - header - ---- - src/meta/meta-context.h | 5 +++++ - src/meta/meta-wayland-compositor.h | 3 --- - src/meta/types.h | 4 ++++ - 3 files changed, 9 insertions(+), 3 deletions(-) - -diff --git a/src/meta/meta-context.h b/src/meta/meta-context.h -index ef36bd2c3..2adb9b07e 100644 ---- a/src/meta/meta-context.h -+++ b/src/meta/meta-context.h -@@ -101,3 +101,8 @@ gboolean meta_context_raise_rlimit_nofile (MetaContext *context, - META_EXPORT - gboolean meta_context_restore_rlimit_nofile (MetaContext *context, - GError **error); -+ -+#ifdef HAVE_WAYLAND -+META_EXPORT -+MetaWaylandCompositor * meta_context_get_wayland_compositor (MetaContext *context); -+#endif -diff --git a/src/meta/meta-wayland-compositor.h b/src/meta/meta-wayland-compositor.h -index 7f4a50705..3df92fda5 100644 ---- a/src/meta/meta-wayland-compositor.h -+++ b/src/meta/meta-wayland-compositor.h -@@ -31,9 +31,6 @@ G_DECLARE_FINAL_TYPE (MetaWaylandCompositor, - META, WAYLAND_COMPOSITOR, - GObject) - --META_EXPORT --MetaWaylandCompositor *meta_context_get_wayland_compositor (MetaContext *context); -- - META_EXPORT - struct wl_display *meta_wayland_compositor_get_wayland_display (MetaWaylandCompositor *compositor); - -diff --git a/src/meta/types.h b/src/meta/types.h -index cbe2a9a3d..8fba4a839 100644 ---- a/src/meta/types.h -+++ b/src/meta/types.h -@@ -38,3 +38,7 @@ typedef struct _MetaSettings MetaSettings; - - typedef struct _MetaWorkspaceManager MetaWorkspaceManager; - typedef struct _MetaSelection MetaSelection; -+ -+#ifdef HAVE_WAYLAND -+typedef struct _MetaWaylandCompositor MetaWaylandCompositor; -+#endif --- -2.45.2 - - -From 4b665dee351d554e5e9aabb3048b768832421311 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Tue, 12 Dec 2023 22:52:44 +0100 -Subject: [PATCH 4/6] Add experimental mode to use native scaling of Xwayland - clients - -Allow scale-aware Xwayland clients to scale by an integer scale -themselves, instead of letting them render them at 1x scale and then -scaling up the texture, making it look blurry. - -When monitor framebuffers are scaled, this special cases Xwayland and -sends output regions in a way that Xwayland think everything is N times -as large as the logical region, where N is the ceil of the max monitor -scale. - -This is done by introducing a "stage" vs "protocol" coordinate space for -X11, where the "protocol" coordinate space is "stage" multiplied by a -scaling factor. - -We're guarding this behind a new experimental feature -"xwayland-native-scaling", which can only come into effect when enabled -together with "scale-monitor-framebuffer". ---- - src/backends/meta-monitor-manager-private.h | 2 + - src/backends/meta-monitor-manager.c | 6 + - src/compositor/meta-window-actor-x11.c | 22 +- - src/core/frame.c | 93 ++++-- - src/wayland/meta-wayland-cursor-surface.c | 52 ++-- - src/wayland/meta-wayland-outputs.c | 42 ++- - src/wayland/meta-wayland-pointer.c | 14 + - src/wayland/meta-wayland-private.h | 2 + - src/wayland/meta-wayland-surface.c | 30 +- - src/wayland/meta-window-xwayland.c | 71 ++++- - src/wayland/meta-xwayland-private.h | 1 + - src/wayland/meta-xwayland-surface.c | 10 +- - src/wayland/meta-xwayland.c | 56 ++++ - src/wayland/meta-xwayland.h | 2 + - src/x11/meta-x11-display.c | 196 +++++++++++-- - src/x11/window-props.c | 108 ++++++- - src/x11/window-x11.c | 305 ++++++++++++++++---- - src/x11/window-x11.h | 38 +++ - 18 files changed, 886 insertions(+), 164 deletions(-) - -diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h -index 0760a341a..6ed3fc2c3 100644 ---- a/src/backends/meta-monitor-manager-private.h -+++ b/src/backends/meta-monitor-manager-private.h -@@ -436,3 +436,5 @@ gboolean meta_monitor_manager_apply_monitors_config (MetaMonitorManager * - MetaMonitorsConfig *config, - MetaMonitorsConfigMethod method, - GError **error); -+ -+MetaLogicalMonitorLayoutMode meta_monitor_manager_get_layout_mode (MetaMonitorManager *manager); -diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c -index 7f98c2d98..45033d966 100644 ---- a/src/backends/meta-monitor-manager.c -+++ b/src/backends/meta-monitor-manager.c -@@ -4116,3 +4116,9 @@ meta_monitor_manager_get_virtual_monitors (MetaMonitorManager *manager) - - return priv->virtual_monitors; - } -+ -+MetaLogicalMonitorLayoutMode -+meta_monitor_manager_get_layout_mode (MetaMonitorManager *manager) -+{ -+ return manager->layout_mode; -+} -diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c -index 19827af33..7df10e6c1 100644 ---- a/src/compositor/meta-window-actor-x11.c -+++ b/src/compositor/meta-window-actor-x11.c -@@ -688,11 +688,23 @@ meta_window_actor_x11_process_damage (MetaWindowActorX11 *actor_x11, - - surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); - if (surface) -- meta_surface_actor_process_damage (surface, -- event->area.x, -- event->area.y, -- event->area.width, -- event->area.height); -+ { -+ MetaWindow *window = -+ meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); -+ MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); -+ MtkRectangle damage; -+ -+ meta_window_x11_protocol_to_stage (window_x11, -+ event->area.x, event->area.y, -+ event->area.width, event->area.height, -+ &damage.x, &damage.y, -+ &damage.width, &damage.height); -+ meta_surface_actor_process_damage (surface, -+ damage.x, -+ damage.y, -+ damage.width, -+ damage.height); -+ } - - meta_window_actor_notify_damaged (META_WINDOW_ACTOR (actor_x11)); - } -diff --git a/src/core/frame.c b/src/core/frame.c -index 7a09f89f1..5e8c10e76 100644 ---- a/src/core/frame.c -+++ b/src/core/frame.c -@@ -33,6 +33,7 @@ - #include "x11/meta-x11-display-private.h" - #include "x11/window-x11-private.h" - #include "x11/window-props.h" -+#include "x11/window-x11.h" - - #include - #include -@@ -235,6 +236,8 @@ meta_window_destroy_frame (MetaWindow *window) - - if (!x11_display->closing) - { -+ int child_x, child_y; -+ - if (!window->unmanaging) - { - meta_stack_tracker_record_add (window->display->stack_tracker, -@@ -242,6 +245,14 @@ meta_window_destroy_frame (MetaWindow *window) - XNextRequest (x11_display->xdisplay)); - } - -+ meta_window_x11_stage_to_protocol (META_WINDOW_X11 (window), -+ frame->rect.x + borders.invisible.left, -+ frame->rect.y + borders.invisible.top, -+ 0, 0, -+ &child_x, -+ &child_y, -+ NULL, NULL); -+ - XReparentWindow (x11_display->xdisplay, - meta_window_x11_get_xwindow (window), - x11_display->xroot, -@@ -249,8 +260,7 @@ meta_window_destroy_frame (MetaWindow *window) - * coordinates here means we'll need to ensure a configure - * notify event is sent; see bug 399552. - */ -- frame->rect.x + borders.invisible.left, -- frame->rect.y + borders.invisible.top); -+ child_x, child_y); - window->reparents_pending += 1; - } - -@@ -297,6 +307,7 @@ meta_frame_query_borders (MetaFrame *frame, - MetaFrameBorders *borders) - { - MetaWindow *window = frame->window; -+ MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); - MetaX11Display *x11_display = window->display->x11_display; - int format, res; - Atom type; -@@ -320,12 +331,22 @@ meta_frame_query_borders (MetaFrame *frame, - if (mtk_x11_error_trap_pop_with_return (x11_display->xdisplay) == Success && - res == Success && nitems == 4) - { -- borders->invisible = (MetaFrameBorder) { -- ((long *) data)[0], -- ((long *) data)[1], -- ((long *) data)[2], -- ((long *) data)[3], -- }; -+ int left, right, top, bottom; -+ -+ meta_window_x11_protocol_to_stage (window_x11, -+ ((long *) data)[0], -+ ((long *) data)[1], -+ ((long *) data)[2], -+ ((long *) data)[3], -+ &left, -+ &right, -+ &top, -+ &bottom); -+ -+ borders->invisible.left = left; -+ borders->invisible.right = right; -+ borders->invisible.top = top; -+ borders->invisible.bottom = bottom; - } - else - { -@@ -348,12 +369,21 @@ meta_frame_query_borders (MetaFrame *frame, - if (mtk_x11_error_trap_pop_with_return (x11_display->xdisplay) == Success && - res == Success && nitems == 4) - { -- borders->visible = (MetaFrameBorder) { -- ((long *) data)[0], -- ((long *) data)[1], -- ((long *) data)[2], -- ((long *) data)[3], -- }; -+ int left, right, top, bottom; -+ -+ meta_window_x11_protocol_to_stage (window_x11, -+ ((long *) data)[0], -+ ((long *) data)[1], -+ ((long *) data)[2], -+ ((long *) data)[3], -+ &left, -+ &right, -+ &top, -+ &bottom); -+ borders->visible.left = left; -+ borders->visible.right = right; -+ borders->visible.top = top; -+ borders->visible.bottom = bottom; - } - else - { -@@ -401,7 +431,9 @@ meta_frame_sync_to_window (MetaFrame *frame, - gboolean need_resize) - { - MetaWindow *window = frame->window; -+ MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); - MetaX11Display *x11_display = window->display->x11_display; -+ MtkRectangle rect; - - meta_topic (META_DEBUG_GEOMETRY, - "Syncing frame geometry %d,%d %dx%d (SE: %d,%d)", -@@ -412,12 +444,22 @@ meta_frame_sync_to_window (MetaFrame *frame, - - mtk_x11_error_trap_push (x11_display->xdisplay); - -+ meta_window_x11_stage_to_protocol (window_x11, -+ frame->rect.x, -+ frame->rect.y, -+ frame->rect.width, -+ frame->rect.height, -+ &rect.x, -+ &rect.y, -+ &rect.width, -+ &rect.height); -+ - XMoveResizeWindow (x11_display->xdisplay, - frame->xwindow, -- frame->rect.x, -- frame->rect.y, -- frame->rect.width, -- frame->rect.height); -+ rect.x, -+ rect.y, -+ rect.width, -+ rect.height); - - mtk_x11_error_trap_pop (x11_display->xdisplay); - -@@ -454,6 +496,7 @@ static void - send_configure_notify (MetaFrame *frame) - { - MetaX11Display *x11_display = frame->window->display->x11_display; -+ MetaWindowX11 *window_x11 = META_WINDOW_X11 (frame->window); - XEvent event = { 0 }; - - /* We never get told by the frames client, just reassert the -@@ -463,10 +506,16 @@ send_configure_notify (MetaFrame *frame) - event.xconfigure.display = x11_display->xdisplay; - event.xconfigure.event = frame->xwindow; - event.xconfigure.window = frame->xwindow; -- event.xconfigure.x = frame->rect.x; -- event.xconfigure.y = frame->rect.y; -- event.xconfigure.width = frame->rect.width; -- event.xconfigure.height = frame->rect.height; -+ -+ meta_window_x11_stage_to_protocol (window_x11, -+ frame->rect.x, -+ frame->rect.y, -+ frame->rect.width, -+ frame->rect.height, -+ &event.xconfigure.x, -+ &event.xconfigure.y, -+ &event.xconfigure.width, -+ &event.xconfigure.height); - event.xconfigure.border_width = 0; - event.xconfigure.above = None; - event.xconfigure.override_redirect = False; -diff --git a/src/wayland/meta-wayland-cursor-surface.c b/src/wayland/meta-wayland-cursor-surface.c -index 87a8895c8..5a16ce7d8 100644 ---- a/src/wayland/meta-wayland-cursor-surface.c -+++ b/src/wayland/meta-wayland-cursor-surface.c -@@ -92,37 +92,29 @@ cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite, - { - MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_surface); - MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (role); -- -- if (!meta_wayland_surface_is_xwayland (surface)) -+ MetaContext *context = -+ meta_wayland_compositor_get_context (surface->compositor); -+ MetaBackend *backend = meta_context_get_backend (context); -+ MetaMonitorManager *monitor_manager = -+ meta_backend_get_monitor_manager (backend); -+ MetaLogicalMonitor *logical_monitor; -+ -+ logical_monitor = -+ meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y); -+ if (logical_monitor) - { -- MetaWaylandSurfaceRole *surface_role = -- META_WAYLAND_SURFACE_ROLE (cursor_surface); -- MetaWaylandSurface *surface = -- meta_wayland_surface_role_get_surface (surface_role); -- MetaContext *context = -- meta_wayland_compositor_get_context (surface->compositor); -- MetaBackend *backend = meta_context_get_backend (context); -- MetaMonitorManager *monitor_manager = -- meta_backend_get_monitor_manager (backend); -- MetaLogicalMonitor *logical_monitor; -- -- logical_monitor = -- meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y); -- if (logical_monitor) -- { -- int surface_scale = surface->applied_state.scale; -- float texture_scale; -- -- if (meta_backend_is_stage_views_scaled (backend)) -- texture_scale = 1.0 / surface_scale; -- else -- texture_scale = (meta_logical_monitor_get_scale (logical_monitor) / -- surface_scale); -- -- meta_cursor_sprite_set_texture_scale (cursor_sprite, texture_scale); -- meta_cursor_sprite_set_texture_transform (cursor_sprite, -- surface->buffer_transform); -- } -+ int surface_scale = surface->applied_state.scale; -+ float texture_scale; -+ -+ if (meta_backend_is_stage_views_scaled (backend)) -+ texture_scale = 1.0 / surface_scale; -+ else -+ texture_scale = (meta_logical_monitor_get_scale (logical_monitor) / -+ surface_scale); -+ -+ meta_cursor_sprite_set_texture_scale (cursor_sprite, texture_scale); -+ meta_cursor_sprite_set_texture_transform (cursor_sprite, -+ surface->buffer_transform); - } - - meta_wayland_surface_update_outputs (surface); -diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c -index 89ae86445..f957bc339 100644 ---- a/src/wayland/meta-wayland-outputs.c -+++ b/src/wayland/meta-wayland-outputs.c -@@ -31,6 +31,10 @@ - #include "backends/meta-monitor-manager-private.h" - #include "wayland/meta-wayland-private.h" - -+#ifdef HAVE_XWAYLAND -+#include "wayland/meta-xwayland.h" -+#endif -+ - #include "xdg-output-unstable-v1-server-protocol.h" - - /* Wayland protocol headers list new additions, not deprecations */ -@@ -50,6 +54,8 @@ struct _MetaWaylandOutput - { - GObject parent; - -+ MetaWaylandCompositor *compositor; -+ - struct wl_global *global; - GList *resources; - GList *xdg_output_resources; -@@ -422,6 +428,7 @@ meta_wayland_output_new (MetaWaylandCompositor *compositor, - MetaWaylandOutput *wayland_output; - - wayland_output = g_object_new (META_TYPE_WAYLAND_OUTPUT, NULL); -+ wayland_output->compositor = compositor; - wayland_output->global = wl_global_create (compositor->wayland_display, - &wl_output_interface, - META_WL_OUTPUT_VERSION, -@@ -596,6 +603,37 @@ static const struct zxdg_output_v1_interface - meta_xdg_output_destroy, - }; - -+#ifdef HAVE_XWAYLAND -+static gboolean -+is_xwayland_resource (MetaWaylandOutput *wayland_output, -+ struct wl_resource *resource) -+{ -+ MetaXWaylandManager *manager = &wayland_output->compositor->xwayland_manager; -+ -+ return resource && wl_resource_get_client (resource) == manager->client; -+} -+#endif -+ -+static void -+maybe_scale_for_xwayland (MetaWaylandOutput *wayland_output, -+ struct wl_resource *resource, -+ int *x, -+ int *y) -+{ -+#ifdef HAVE_XWAYLAND -+ if (is_xwayland_resource (wayland_output, resource)) -+ { -+ MetaXWaylandManager *xwayland_manager = -+ &wayland_output->compositor->xwayland_manager; -+ int xwayland_scale; -+ -+ xwayland_scale = meta_xwayland_get_effective_scale (xwayland_manager); -+ *x *= xwayland_scale; -+ *y *= xwayland_scale; -+ } -+#endif -+} -+ - static void - send_xdg_output_events (struct wl_resource *resource, - MetaWaylandOutput *wayland_output, -@@ -616,6 +654,7 @@ send_xdg_output_events (struct wl_resource *resource, - if (need_all_events || - old_layout.x != layout.x || old_layout.y != layout.y) - { -+ maybe_scale_for_xwayland (wayland_output, resource, &layout.x, &layout.y); - zxdg_output_v1_send_logical_position (resource, layout.x, layout.y); - need_done = TRUE; - } -@@ -623,6 +662,7 @@ send_xdg_output_events (struct wl_resource *resource, - if (need_all_events || - old_layout.width != layout.width || old_layout.height != layout.height) - { -+ maybe_scale_for_xwayland (wayland_output, resource, &layout.width, &layout.height); - zxdg_output_v1_send_logical_size (resource, layout.width, layout.height); - need_done = TRUE; - } -@@ -745,7 +785,7 @@ meta_wayland_outputs_init (MetaWaylandCompositor *compositor) - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - -- g_signal_connect (monitor_manager, "monitors-changed-internal", -+ g_signal_connect (monitor_manager, "monitors-changed", - G_CALLBACK (on_monitors_changed), compositor); - - compositor->outputs = -diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c -index cf6008064..b8c49849a 100644 ---- a/src/wayland/meta-wayland-pointer.c -+++ b/src/wayland/meta-wayland-pointer.c -@@ -1247,6 +1247,20 @@ pointer_set_cursor (struct wl_client *client, - cursor_surface = META_WAYLAND_CURSOR_SURFACE (surface->role); - meta_wayland_cursor_surface_set_renderer (cursor_surface, - cursor_renderer); -+ -+#ifdef HAVE_XWAYLAND -+ if (meta_wayland_surface_is_xwayland (surface)) -+ { -+ MetaXWaylandManager *xwayland_manager = -+ &surface->compositor->xwayland_manager; -+ int scale; -+ -+ scale = meta_xwayland_get_effective_scale (xwayland_manager); -+ hot_x = round (hot_x / (double) scale); -+ hot_y = round (hot_y / (double) scale); -+ } -+#endif -+ - meta_wayland_cursor_surface_set_hotspot (cursor_surface, - hot_x, hot_y); - -diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h -index e8d442c03..834753ffd 100644 ---- a/src/wayland/meta-wayland-private.h -+++ b/src/wayland/meta-wayland-private.h -@@ -77,6 +77,8 @@ struct _MetaXWaylandManager - int rr_error_base; - - gboolean should_enable_ei_portal; -+ -+ double highest_monitor_scale; - }; - - struct _MetaWaylandCompositor -diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c -index d8b36ff92..4ad95cd9d 100644 ---- a/src/wayland/meta-wayland-surface.c -+++ b/src/wayland/meta-wayland-surface.c -@@ -782,8 +782,19 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface, - state->buffer->type != META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL)); - } - -- if (state->scale > 0) -- surface->applied_state.scale = state->scale; -+ if (meta_wayland_surface_is_xwayland (surface)) -+ { -+#ifdef HAVE_XWAYLAND -+ MetaXWaylandManager *xwayland_manager = -+ &surface->compositor->xwayland_manager; -+ -+ surface->applied_state.scale = meta_xwayland_get_effective_scale (xwayland_manager); -+#endif -+ } -+ else if (state->scale > 0) -+ { -+ surface->applied_state.scale = state->scale; -+ } - - if (state->has_new_buffer_transform) - surface->buffer_transform = state->buffer_transform; -@@ -978,8 +989,9 @@ meta_wayland_surface_commit (MetaWaylandSurface *surface) - MetaMultiTexture *committed_texture = surface->committed_state.texture; - int committed_scale = surface->committed_state.scale; - -- if ((meta_multi_texture_get_width (committed_texture) % committed_scale != 0) || -- (meta_multi_texture_get_height (committed_texture) % committed_scale != 0)) -+ if (((meta_multi_texture_get_width (committed_texture) % committed_scale != 0) || -+ (meta_multi_texture_get_height (committed_texture) % committed_scale != 0)) && -+ !meta_wayland_surface_is_xwayland (surface)) - { - if (surface->role && !META_IS_WAYLAND_CURSOR_SURFACE (surface->role)) - { -@@ -1507,6 +1519,16 @@ meta_wayland_surface_update_outputs (MetaWaylandSurface *surface) - g_hash_table_foreach (surface->compositor->outputs, - update_surface_output_state, - surface); -+ -+ if (meta_wayland_surface_is_xwayland (surface)) -+ { -+#ifdef HAVE_XWAYLAND -+ MetaXWaylandManager *xwayland_manager = -+ &surface->compositor->xwayland_manager; -+ -+ surface->applied_state.scale = meta_xwayland_get_effective_scale (xwayland_manager); -+#endif -+ } - } - - void -diff --git a/src/wayland/meta-window-xwayland.c b/src/wayland/meta-window-xwayland.c -index 1299a351c..5fb006962 100644 ---- a/src/wayland/meta-window-xwayland.c -+++ b/src/wayland/meta-window-xwayland.c -@@ -27,8 +27,9 @@ - #include "x11/window-x11-private.h" - #include "x11/xprops.h" - #include "wayland/meta-window-xwayland.h" --#include "wayland/meta-wayland.h" -+#include "wayland/meta-wayland-private.h" - #include "wayland/meta-wayland-surface-private.h" -+#include "wayland/meta-xwayland.h" - - enum - { -@@ -315,6 +316,72 @@ meta_window_xwayland_process_property_notify (MetaWindow *window, - meta_window_queue (window, META_QUEUE_MOVE_RESIZE); - } - -+static void -+meta_window_xwayland_stage_to_protocol (MetaWindowX11 *window_x11, -+ int stage_x, -+ int stage_y, -+ int stage_width, -+ int stage_height, -+ int *protocol_x, -+ int *protocol_y, -+ int *protocol_width, -+ int *protocol_height) -+{ -+ MetaDisplay *display = meta_window_get_display (META_WINDOW (window_x11)); -+ MetaContext *context = meta_display_get_context (display); -+ MetaWaylandCompositor *wayland_compositor = -+ meta_context_get_wayland_compositor (context); -+ MetaXWaylandManager *xwayland_manager = &wayland_compositor->xwayland_manager; -+ int scale; -+ -+ scale = meta_xwayland_get_effective_scale (xwayland_manager); -+ if (protocol_x) -+ *protocol_x = stage_x * scale; -+ if (protocol_y) -+ *protocol_y = stage_y * scale; -+ if (protocol_width) -+ *protocol_width = stage_width * scale; -+ if (protocol_height) -+ *protocol_height = stage_height * scale; -+} -+ -+static void -+meta_window_xwayland_protocol_to_stage (MetaWindowX11 *window_x11, -+ int protocol_x, -+ int protocol_y, -+ int protocol_width, -+ int protocol_height, -+ int *stage_x, -+ int *stage_y, -+ int *stage_width, -+ int *stage_height) -+{ -+ MetaDisplay *display = meta_window_get_display (META_WINDOW (window_x11)); -+ MetaContext *context = meta_display_get_context (display); -+ MetaWaylandCompositor *wayland_compositor = -+ meta_context_get_wayland_compositor (context); -+ MetaXWaylandManager *xwayland_manager = &wayland_compositor->xwayland_manager; -+ MtkRectangle rect; -+ int scale; -+ -+ rect.x = protocol_x; -+ rect.y = protocol_y; -+ rect.width = protocol_width; -+ rect.height = protocol_height; -+ -+ scale = meta_xwayland_get_effective_scale (xwayland_manager); -+ mtk_rectangle_scale_double (&rect, 1.0 / scale, MTK_ROUNDING_STRATEGY_GROW, &rect); -+ -+ if (stage_x) -+ *stage_x = rect.x; -+ if (stage_y) -+ *stage_y = rect.y; -+ if (stage_width) -+ *stage_width = rect.width; -+ if (stage_height) -+ *stage_height = rect.height; -+} -+ - static void - meta_window_xwayland_class_init (MetaWindowXwaylandClass *klass) - { -@@ -331,6 +398,8 @@ meta_window_xwayland_class_init (MetaWindowXwaylandClass *klass) - window_x11_class->thaw_commits = meta_window_xwayland_thaw_commits; - window_x11_class->always_update_shape = meta_window_xwayland_always_update_shape; - window_x11_class->process_property_notify = meta_window_xwayland_process_property_notify; -+ window_x11_class->stage_to_protocol = meta_window_xwayland_stage_to_protocol; -+ window_x11_class->protocol_to_stage = meta_window_xwayland_protocol_to_stage; - - gobject_class->get_property = meta_window_xwayland_get_property; - gobject_class->set_property = meta_window_xwayland_set_property; -diff --git a/src/wayland/meta-xwayland-private.h b/src/wayland/meta-xwayland-private.h -index 7a9cb73fd..9e06f0315 100644 ---- a/src/wayland/meta-xwayland-private.h -+++ b/src/wayland/meta-xwayland-private.h -@@ -20,6 +20,7 @@ - #include - - #include "wayland/meta-wayland-private.h" -+#include "wayland/meta-xwayland.h" - - gboolean - meta_xwayland_init (MetaXWaylandManager *manager, -diff --git a/src/wayland/meta-xwayland-surface.c b/src/wayland/meta-xwayland-surface.c -index 8fa1c72a9..c6daf9b26 100644 ---- a/src/wayland/meta-xwayland-surface.c -+++ b/src/wayland/meta-xwayland-surface.c -@@ -163,13 +163,19 @@ meta_xwayland_surface_get_relative_coordinates (MetaWaylandSurfaceRole *surface_ - float *out_sy) - { - MetaXwaylandSurface *xwayland_surface = META_XWAYLAND_SURFACE (surface_role); -+ MetaWaylandSurface *surface = -+ meta_wayland_surface_role_get_surface (surface_role); -+ MetaWaylandCompositor *compositor = -+ meta_wayland_surface_get_compositor (surface); - MtkRectangle window_rect = { 0 }; -+ int xwayland_scale; - - if (xwayland_surface->window) - meta_window_get_buffer_rect (xwayland_surface->window, &window_rect); - -- *out_sx = abs_x - window_rect.x; -- *out_sy = abs_y - window_rect.y; -+ xwayland_scale = meta_xwayland_get_effective_scale (&compositor->xwayland_manager); -+ *out_sx = (abs_x - window_rect.x) * xwayland_scale; -+ *out_sy = (abs_y - window_rect.y) * xwayland_scale; - } - - static MetaWaylandSurface * -diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c -index ea9c27d74..828e6f64e 100644 ---- a/src/wayland/meta-xwayland.c -+++ b/src/wayland/meta-xwayland.c -@@ -1051,6 +1051,29 @@ meta_xwayland_shutdown (MetaWaylandCompositor *compositor) - } - } - -+static void -+update_highest_monitor_scale (MetaXWaylandManager *manager) -+{ -+ MetaWaylandCompositor *compositor = manager->compositor; -+ MetaContext *context = meta_wayland_compositor_get_context (compositor); -+ MetaBackend *backend = meta_context_get_backend (context); -+ MetaMonitorManager *monitor_manager = -+ meta_backend_get_monitor_manager (backend); -+ GList *logical_monitors; -+ GList *l; -+ double scale = 1.0; -+ -+ logical_monitors = meta_monitor_manager_get_logical_monitors (monitor_manager); -+ for (l = logical_monitors; l; l = l->next) -+ { -+ MetaLogicalMonitor *logical_monitor = l->data; -+ -+ scale = MAX (scale, meta_logical_monitor_get_scale (logical_monitor)); -+ } -+ -+ manager->highest_monitor_scale = scale; -+} -+ - gboolean - meta_xwayland_init (MetaXWaylandManager *manager, - MetaWaylandCompositor *compositor, -@@ -1058,6 +1081,9 @@ meta_xwayland_init (MetaXWaylandManager *manager, - GError **error) - { - MetaContext *context = compositor->context; -+ MetaBackend *backend = meta_context_get_backend (context); -+ MetaMonitorManager *monitor_manager = -+ meta_backend_get_monitor_manager (backend); - MetaX11DisplayPolicy policy; - int display = 0; - -@@ -1121,6 +1147,10 @@ meta_xwayland_init (MetaXWaylandManager *manager, - /* Xwayland specific protocol, needs to be filtered out for all other clients */ - meta_xwayland_grab_keyboard_init (compositor); - -+ g_signal_connect_swapped (monitor_manager, "monitors-changed-internal", -+ G_CALLBACK (update_highest_monitor_scale), manager); -+ update_highest_monitor_scale (manager); -+ - return TRUE; - } - -@@ -1312,3 +1342,29 @@ meta_xwayland_set_should_enable_ei_portal (MetaXWaylandManager *manager, - { - manager->should_enable_ei_portal = should_enable_ei_portal; - } -+ -+int -+meta_xwayland_get_effective_scale (MetaXWaylandManager *manager) -+{ -+ MetaWaylandCompositor *compositor = manager->compositor; -+ MetaContext *context = meta_wayland_compositor_get_context (compositor); -+ MetaBackend *backend = meta_context_get_backend (context); -+ MetaMonitorManager *monitor_manager = -+ meta_backend_get_monitor_manager (backend); -+ MetaSettings *settings = meta_backend_get_settings (backend); -+ -+ switch (meta_monitor_manager_get_layout_mode (monitor_manager)) -+ { -+ case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: -+ break; -+ -+ case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: -+ if (meta_settings_is_experimental_feature_enabled (settings, -+ META_EXPERIMENTAL_FEATURE_XWAYLAND_NATIVE_SCALING) && -+ meta_settings_is_experimental_feature_enabled (settings, -+ META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER)) -+ return ceil (manager->highest_monitor_scale); -+ } -+ -+ return 1; -+} -diff --git a/src/wayland/meta-xwayland.h b/src/wayland/meta-xwayland.h -index daf9d1abb..ae7a06977 100644 ---- a/src/wayland/meta-xwayland.h -+++ b/src/wayland/meta-xwayland.h -@@ -48,3 +48,5 @@ META_EXPORT_TEST - gboolean meta_xwayland_signal (MetaXWaylandManager *manager, - int signum, - GError **error); -+ -+int meta_xwayland_get_effective_scale (MetaXWaylandManager *manager); -diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c -index fe152d20b..602879aac 100644 ---- a/src/x11/meta-x11-display.c -+++ b/src/x11/meta-x11-display.c -@@ -130,6 +130,42 @@ backend_from_x11_display (MetaX11Display *x11_display) - return meta_context_get_backend (context); - } - -+static void -+stage_to_protocol (MetaX11Display *x11_display, -+ int stage_x, -+ int stage_y, -+ int *protocol_x, -+ int *protocol_y) -+{ -+ MetaDisplay *display = meta_x11_display_get_display (x11_display); -+ MetaContext *context = meta_display_get_context (display); -+ int scale = 1; -+ -+ switch (meta_context_get_compositor_type (context)) -+ { -+ case META_COMPOSITOR_TYPE_WAYLAND: -+ { -+#ifdef HAVE_XWAYLAND -+ MetaWaylandCompositor *wayland_compositor = -+ meta_context_get_wayland_compositor (context); -+ MetaXWaylandManager *xwayland_manager = -+ &wayland_compositor->xwayland_manager; -+ -+ scale = meta_xwayland_get_effective_scale (xwayland_manager); -+#endif -+ break; -+ } -+ -+ case META_COMPOSITOR_TYPE_X11: -+ break; -+ } -+ -+ if (protocol_x) -+ *protocol_x = stage_x * scale; -+ if (protocol_y) -+ *protocol_y = stage_y * scale; -+} -+ - static void - meta_x11_display_unmanage_windows (MetaX11Display *x11_display) - { -@@ -180,10 +216,32 @@ update_ui_scaling_factor (MetaX11Display *x11_display) - MetaX11DisplayPrivate *priv = - meta_x11_display_get_instance_private (x11_display); - MetaBackend *backend = backend_from_x11_display (x11_display); -- MetaSettings *settings = meta_backend_get_settings (backend); -- int ui_scaling_factor; -+ MetaContext *context = meta_backend_get_context (backend); -+ int ui_scaling_factor = 1; -+ -+ switch (meta_context_get_compositor_type (context)) -+ { -+ case META_COMPOSITOR_TYPE_WAYLAND: -+ { -+#ifdef HAVE_XWAYLAND -+ MetaWaylandCompositor *wayland_compositor = -+ meta_context_get_wayland_compositor (context); -+ MetaXWaylandManager *xwayland_manager = -+ &wayland_compositor->xwayland_manager; -+ -+ ui_scaling_factor = meta_xwayland_get_effective_scale (xwayland_manager); -+#endif -+ break; -+ } -+ case META_COMPOSITOR_TYPE_X11: -+ { -+ MetaSettings *settings = meta_backend_get_settings (backend); -+ -+ ui_scaling_factor = meta_settings_get_ui_scaling_factor (settings); -+ break; -+ } -+ } - -- ui_scaling_factor = meta_settings_get_ui_scaling_factor (settings); - meta_dbus_x11_set_ui_scaling_factor (priv->dbus_api, ui_scaling_factor); - } - -@@ -613,6 +671,9 @@ set_desktop_geometry_hint (MetaX11Display *x11_display) - return; - - meta_display_get_size (x11_display->display, &monitor_width, &monitor_height); -+ stage_to_protocol (x11_display, -+ monitor_width, monitor_height, -+ &monitor_width, &monitor_height); - - data[0] = monitor_width; - data[1] = monitor_height; -@@ -1022,14 +1083,22 @@ set_workspace_work_area_hint (MetaWorkspace *workspace, - - for (l = logical_monitors; l; l = l->next) - { -- MtkRectangle area; -+ MtkRectangle stage_area; -+ MtkRectangle protocol_area; - -- meta_workspace_get_work_area_for_logical_monitor (workspace, l->data, &area); -+ meta_workspace_get_work_area_for_logical_monitor (workspace, l->data, -+ &stage_area); - -- tmp[0] = area.x; -- tmp[1] = area.y; -- tmp[2] = area.width; -- tmp[3] = area.height; -+ stage_to_protocol (x11_display, -+ stage_area.x, stage_area.y, -+ &protocol_area.x, &protocol_area.y); -+ stage_to_protocol (x11_display, -+ stage_area.width, stage_area.height, -+ &protocol_area.width, &protocol_area.height); -+ tmp[0] = protocol_area.x; -+ tmp[1] = protocol_area.y; -+ tmp[2] = protocol_area.width; -+ tmp[3] = protocol_area.height; - - tmp += 4; - } -@@ -1058,7 +1127,6 @@ set_work_area_hint (MetaDisplay *display, - int num_workspaces; - GList *l; - unsigned long *data, *tmp; -- MtkRectangle area; - - num_workspaces = meta_workspace_manager_get_n_workspaces (workspace_manager); - data = g_new (unsigned long, num_workspaces * 4); -@@ -1067,14 +1135,22 @@ set_work_area_hint (MetaDisplay *display, - for (l = workspace_manager->workspaces; l; l = l->next) - { - MetaWorkspace *workspace = l->data; -+ MtkRectangle stage_area; -+ MtkRectangle protocol_area; - -- meta_workspace_get_work_area_all_monitors (workspace, &area); -+ meta_workspace_get_work_area_all_monitors (workspace, &stage_area); - set_workspace_work_area_hint (workspace, x11_display); - -- tmp[0] = area.x; -- tmp[1] = area.y; -- tmp[2] = area.width; -- tmp[3] = area.height; -+ stage_to_protocol (x11_display, -+ stage_area.x, stage_area.y, -+ &protocol_area.x, &protocol_area.y); -+ stage_to_protocol (x11_display, -+ stage_area.width, stage_area.height, -+ &protocol_area.width, &protocol_area.height); -+ tmp[0] = protocol_area.x; -+ tmp[1] = protocol_area.y; -+ tmp[2] = protocol_area.width; -+ tmp[3] = protocol_area.height; - - tmp += 4; - } -@@ -1254,6 +1330,41 @@ initialize_dbus_interface (MetaX11Display *x11_display) - update_ui_scaling_factor (x11_display); - } - -+static void -+experimental_features_changed (MetaSettings *settings, -+ MetaExperimentalFeature old_experimental_features, -+ MetaX11Display *x11_display) -+{ -+ gboolean was_xwayland_native_scaling; -+ gboolean was_stage_views_scaled; -+ gboolean is_xwayland_native_scaling; -+ gboolean is_stage_views_scaled; -+ -+ was_xwayland_native_scaling = -+ !!(old_experimental_features & -+ META_EXPERIMENTAL_FEATURE_XWAYLAND_NATIVE_SCALING); -+ was_stage_views_scaled = -+ !!(old_experimental_features & -+ META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER); -+ -+ is_xwayland_native_scaling = -+ meta_settings_is_experimental_feature_enabled ( -+ settings, -+ META_EXPERIMENTAL_FEATURE_XWAYLAND_NATIVE_SCALING); -+ is_stage_views_scaled = -+ meta_settings_is_experimental_feature_enabled ( -+ settings, -+ META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER); -+ -+ if (is_xwayland_native_scaling != was_xwayland_native_scaling || -+ is_stage_views_scaled != was_stage_views_scaled) -+ { -+ update_ui_scaling_factor (x11_display); -+ set_desktop_geometry_hint (x11_display); -+ set_work_area_hint (x11_display->display, x11_display); -+ } -+} -+ - /** - * meta_x11_display_new: - * -@@ -1272,6 +1383,7 @@ meta_x11_display_new (MetaDisplay *display, - MetaBackend *backend = meta_context_get_backend (context); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); -+ MetaSettings *settings = meta_backend_get_settings (backend); - g_autoptr (MetaX11Display) x11_display = NULL; - Display *xdisplay; - Screen *xscreen; -@@ -1442,7 +1554,7 @@ meta_x11_display_new (MetaDisplay *display, - "monitors-changed-internal", - G_CALLBACK (on_monitors_changed_internal), - x11_display, -- 0); -+ G_CONNECT_AFTER); - - init_leader_window (x11_display, ×tamp); - x11_display->timestamp = timestamp; -@@ -1535,6 +1647,11 @@ meta_x11_display_new (MetaDisplay *display, - - meta_prefs_add_listener (prefs_changed_callback, x11_display); - -+ g_signal_connect_object (settings, -+ "experimental-features-changed", -+ G_CALLBACK (experimental_features_changed), -+ x11_display, 0); -+ - set_work_area_hint (display, x11_display); - - g_signal_connect_object (display, "workareas-changed", -@@ -1748,16 +1865,12 @@ meta_x11_display_reload_cursor (MetaX11Display *x11_display) - } - - static void --set_cursor_theme (Display *xdisplay, -- MetaBackend *backend) -+set_cursor_theme (Display *xdisplay, -+ const char *theme, -+ int size) - { -- MetaSettings *settings = meta_backend_get_settings (backend); -- int scale; -- -- scale = meta_settings_get_ui_scaling_factor (settings); -- XcursorSetTheme (xdisplay, meta_prefs_get_cursor_theme ()); -- XcursorSetDefaultSize (xdisplay, -- meta_prefs_get_cursor_size () * scale); -+ XcursorSetTheme (xdisplay, theme); -+ XcursorSetDefaultSize (xdisplay, size); - } - - static void -@@ -1809,8 +1922,37 @@ static void - update_cursor_theme (MetaX11Display *x11_display) - { - MetaBackend *backend = backend_from_x11_display (x11_display); -+ MetaContext *context = meta_backend_get_context (backend); -+ MetaSettings *settings = meta_backend_get_settings (backend); -+ int scale = 1; -+ int size; -+ const char *theme; -+ -+ switch (meta_context_get_compositor_type (context)) -+ { -+ case META_COMPOSITOR_TYPE_WAYLAND: -+ { -+#ifdef HAVE_XWAYLAND -+ MetaWaylandCompositor *wayland_compositor = -+ meta_context_get_wayland_compositor (context); -+ MetaXWaylandManager *xwayland_manager = -+ &wayland_compositor->xwayland_manager; -+ -+ scale = meta_xwayland_get_effective_scale (xwayland_manager); -+#endif -+ break; -+ } -+ -+ case META_COMPOSITOR_TYPE_X11: -+ scale = meta_settings_get_ui_scaling_factor (settings); -+ break; -+ } -+ -+ size = meta_prefs_get_cursor_size () * scale; -+ -+ theme = meta_prefs_get_cursor_theme (); - -- set_cursor_theme (x11_display->xdisplay, backend); -+ set_cursor_theme (x11_display->xdisplay, theme, size); - schedule_reload_x11_cursor (x11_display); - - if (META_IS_BACKEND_X11 (backend)) -@@ -1818,7 +1960,7 @@ update_cursor_theme (MetaX11Display *x11_display) - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - -- set_cursor_theme (xdisplay, backend); -+ set_cursor_theme (xdisplay, theme, size); - meta_backend_x11_reload_cursor (backend_x11); - } - } -diff --git a/src/x11/window-props.c b/src/x11/window-props.c -index c18b3eab5..494fbe843 100644 ---- a/src/x11/window-props.c -+++ b/src/x11/window-props.c -@@ -305,10 +305,15 @@ reload_icon_geometry (MetaWindow *window, - { - MtkRectangle geometry; - -- geometry.x = (int)value->v.cardinal_list.cardinals[0]; -- geometry.y = (int)value->v.cardinal_list.cardinals[1]; -- geometry.width = (int)value->v.cardinal_list.cardinals[2]; -- geometry.height = (int)value->v.cardinal_list.cardinals[3]; -+ meta_window_x11_protocol_to_stage (META_WINDOW_X11 (window), -+ value->v.cardinal_list.cardinals[0], -+ value->v.cardinal_list.cardinals[1], -+ value->v.cardinal_list.cardinals[2], -+ value->v.cardinal_list.cardinals[3], -+ &geometry.x, -+ &geometry.y, -+ &geometry.width, -+ &geometry.height); - - meta_window_set_icon_geometry (window, &geometry); - } -@@ -370,11 +375,24 @@ reload_gtk_frame_extents (MetaWindow *window, - } - else - { -+ int left, right, top, bottom; - MetaFrameBorder extents; -- extents.left = (int)value->v.cardinal_list.cardinals[0]; -- extents.right = (int)value->v.cardinal_list.cardinals[1]; -- extents.top = (int)value->v.cardinal_list.cardinals[2]; -- extents.bottom = (int)value->v.cardinal_list.cardinals[3]; -+ -+ meta_window_x11_protocol_to_stage (META_WINDOW_X11 (window), -+ value->v.cardinal_list.cardinals[0], -+ value->v.cardinal_list.cardinals[1], -+ value->v.cardinal_list.cardinals[2], -+ value->v.cardinal_list.cardinals[3], -+ &left, -+ &right, -+ &top, -+ &bottom); -+ -+ extents.left = left; -+ extents.right = right; -+ extents.top = top; -+ extents.bottom = bottom; -+ - meta_window_set_custom_frame_extents (window, &extents, initial); - } - } -@@ -678,10 +696,16 @@ reload_opaque_region (MetaWindow *window, - { - MtkRectangle *rect = &rects[rect_index]; - -- rect->x = region[i++]; -- rect->y = region[i++]; -- rect->width = region[i++]; -- rect->height = region[i++]; -+ meta_window_x11_protocol_to_stage (META_WINDOW_X11 (window), -+ region[i + 0], -+ region[i + 1], -+ region[i + 2], -+ region[i + 3], -+ &rect->x, -+ &rect->y, -+ &rect->width, -+ &rect->height); -+ i += 4; - - rect_index++; - } -@@ -1245,9 +1269,65 @@ meta_set_normal_hints (MetaWindow *window, - * as if flags were zero - */ - if (hints) -- window->size_hints = *(MetaSizeHints*)(hints); -+ { -+ MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); -+ -+ window->size_hints = *(MetaSizeHints *) hints; -+ -+ meta_window_x11_protocol_to_stage (window_x11, -+ hints->x, hints->y, -+ hints->width, hints->height, -+ &window->size_hints.x, -+ &window->size_hints.y, -+ &window->size_hints.width, -+ &window->size_hints.height); -+ -+ meta_window_x11_protocol_to_stage (window_x11, -+ hints->min_width, hints->min_height, -+ 0, 0, -+ &window->size_hints.min_width, -+ &window->size_hints.min_height, -+ NULL, NULL); -+ -+ meta_window_x11_protocol_to_stage (window_x11, -+ hints->max_width, hints->max_height, -+ 0, 0, -+ &window->size_hints.max_width, -+ &window->size_hints.max_height, -+ NULL, NULL); -+ -+ meta_window_x11_protocol_to_stage (window_x11, -+ hints->width_inc, hints->height_inc, -+ 0, 0, -+ &window->size_hints.width_inc, -+ &window->size_hints.height_inc, -+ NULL, NULL); -+ -+ meta_window_x11_protocol_to_stage (window_x11, -+ hints->min_aspect.x, hints->min_aspect.y, -+ 0, 0, -+ &window->size_hints.min_aspect.x, -+ &window->size_hints.min_aspect.y, -+ NULL, NULL); -+ -+ meta_window_x11_protocol_to_stage (window_x11, -+ hints->max_aspect.x, hints->max_aspect.y, -+ 0, 0, -+ &window->size_hints.max_aspect.x, -+ &window->size_hints.max_aspect.y, -+ NULL, NULL); -+ -+ meta_window_x11_protocol_to_stage (window_x11, -+ hints->base_width, hints->base_height, -+ 0, 0, -+ &window->size_hints.base_width, -+ &window->size_hints.base_height, -+ NULL, NULL); -+ } - else -- window->size_hints.flags = 0; -+ { -+ window->size_hints.flags = 0; -+ } - - /* Put back saved ConfigureRequest. */ - window->size_hints.x = x; -diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c -index 443f40f28..b72d5b6d5 100644 ---- a/src/x11/window-x11.c -+++ b/src/x11/window-x11.c -@@ -110,6 +110,113 @@ meta_window_x11_get_private (MetaWindowX11 *window_x11) - return meta_window_x11_get_instance_private (window_x11); - } - -+static void -+meta_window_x11_real_stage_to_protocol (MetaWindowX11 *window_x11, -+ int stage_x, -+ int stage_y, -+ int stage_width, -+ int stage_height, -+ int *protocol_x, -+ int *protocol_y, -+ int *protocol_width, -+ int *protocol_height) -+{ -+ if (protocol_x) -+ *protocol_x = stage_x; -+ if (protocol_y) -+ *protocol_y = stage_y; -+ if (protocol_width) -+ *protocol_width = stage_width; -+ if (protocol_height) -+ *protocol_height = stage_height; -+} -+ -+static void -+meta_window_x11_real_protocol_to_stage (MetaWindowX11 *window_x11, -+ int protocol_x, -+ int protocol_y, -+ int protocol_width, -+ int protocol_height, -+ int *stage_x, -+ int *stage_y, -+ int *stage_width, -+ int *stage_height) -+{ -+ if (stage_x) -+ *stage_x = protocol_x; -+ if (stage_y) -+ *stage_y = protocol_y; -+ if (stage_width) -+ *stage_width = protocol_width; -+ if (stage_height) -+ *stage_height = protocol_height; -+} -+ -+void -+meta_window_x11_stage_to_protocol (MetaWindowX11 *window_x11, -+ int stage_x, -+ int stage_y, -+ int stage_width, -+ int stage_height, -+ int *protocol_x, -+ int *protocol_y, -+ int *protocol_width, -+ int *protocol_height) -+{ -+ MetaWindowX11Class *klass = META_WINDOW_X11_GET_CLASS (window_x11); -+ -+ klass->stage_to_protocol (window_x11, -+ stage_x, stage_y, -+ stage_width, stage_height, -+ protocol_x, protocol_y, -+ protocol_width, protocol_height); -+} -+ -+void -+meta_window_x11_protocol_to_stage (MetaWindowX11 *window_x11, -+ int protocol_x, -+ int protocol_y, -+ int protocol_width, -+ int protocol_height, -+ int *stage_x, -+ int *stage_y, -+ int *stage_width, -+ int *stage_height) -+{ -+ MetaWindowX11Class *klass = META_WINDOW_X11_GET_CLASS (window_x11); -+ -+ klass->protocol_to_stage (window_x11, -+ protocol_x, protocol_y, -+ protocol_width, protocol_height, -+ stage_x, stage_y, -+ stage_width, stage_height); -+} -+ -+static MtkRegion * -+region_protocol_to_stage (MtkRegion *region, -+ MetaWindowX11 *window_x11) -+{ -+ int n_rects, i; -+ MtkRectangle *rects; -+ MtkRegion *scaled_region; -+ -+ n_rects = mtk_region_num_rectangles (region); -+ MTK_RECTANGLE_CREATE_ARRAY_SCOPED (n_rects, rects); -+ for (i = 0; i < n_rects; i++) -+ { -+ rects[i] = mtk_region_get_rectangle (region, i); -+ meta_window_x11_protocol_to_stage (window_x11, -+ rects[i].x, rects[i].y, -+ rects[i].width, rects[i].height, -+ &rects[i].x, &rects[i].y, -+ &rects[i].width, &rects[i].height); -+ } -+ -+ scaled_region = mtk_region_create_rectangles (rects, n_rects); -+ -+ return scaled_region; -+} -+ - static void - send_icccm_message (MetaWindow *window, - Atom atom, -@@ -254,8 +361,13 @@ send_configure_notify (MetaWindow *window) - event.xconfigure.display = x11_display->xdisplay; - event.xconfigure.event = priv->xwindow; - event.xconfigure.window = priv->xwindow; -- event.xconfigure.x = priv->client_rect.x - priv->border_width; -- event.xconfigure.y = priv->client_rect.y - priv->border_width; -+ meta_window_x11_stage_to_protocol (window_x11, -+ priv->client_rect.x - priv->border_width, -+ priv->client_rect.y - priv->border_width, -+ 0, 0, -+ &event.xconfigure.x, -+ &event.xconfigure.y, -+ NULL, NULL); - if (window->frame) - { - if (window->withdrawn) -@@ -267,19 +379,42 @@ send_configure_notify (MetaWindow *window) - - meta_frame_calc_borders (window->frame, &borders); - -- event.xconfigure.x = window->frame->rect.x + borders.invisible.left; -- event.xconfigure.y = window->frame->rect.y + borders.invisible.top; -+ meta_window_x11_stage_to_protocol (window_x11, -+ window->frame->rect.x + borders.invisible.left, -+ window->frame->rect.y + borders.invisible.top, -+ 0, 0, -+ &event.xconfigure.x, -+ &event.xconfigure.y, -+ NULL, NULL); - } - else - { -+ int dx, dy; -+ - /* Need to be in root window coordinates */ -- event.xconfigure.x += window->frame->rect.x; -- event.xconfigure.y += window->frame->rect.y; -+ meta_window_x11_stage_to_protocol (window_x11, -+ window->frame->rect.x, -+ window->frame->rect.y, -+ 0, 0, -+ &dx, -+ &dy, -+ NULL, NULL); -+ event.xconfigure.x += dx; -+ event.xconfigure.y += dy; - } - } -- event.xconfigure.width = priv->client_rect.width; -- event.xconfigure.height = priv->client_rect.height; -- event.xconfigure.border_width = priv->border_width; /* requested not actual */ -+ meta_window_x11_stage_to_protocol (window_x11, -+ priv->client_rect.width, -+ priv->client_rect.height, -+ 0, 0, -+ &event.xconfigure.width, -+ &event.xconfigure.height, -+ NULL, NULL); -+ meta_window_x11_stage_to_protocol (window_x11, -+ priv->border_width, -+ 0, 0, 0, -+ &event.xconfigure.border_width, -+ NULL, NULL, NULL); - event.xconfigure.above = None; /* FIXME */ - event.xconfigure.override_redirect = False; - -@@ -1137,20 +1272,26 @@ static void - update_net_frame_extents (MetaWindow *window) - { - MetaX11Display *x11_display = window->display->x11_display; -- -+ int left, right, top, bottom; - unsigned long data[4]; - MetaFrameBorders borders; - Window xwindow = meta_window_x11_get_xwindow (window); - - meta_frame_calc_borders (window->frame, &borders); -- /* Left */ -- data[0] = borders.visible.left; -- /* Right */ -- data[1] = borders.visible.right; -- /* Top */ -- data[2] = borders.visible.top; -- /* Bottom */ -- data[3] = borders.visible.bottom; -+ meta_window_x11_stage_to_protocol (META_WINDOW_X11 (window), -+ borders.visible.left, -+ borders.visible.right, -+ borders.visible.top, -+ borders.visible.bottom, -+ &left, -+ &right, -+ &top, -+ &bottom); -+ -+ data[0] = left; -+ data[1] = right; -+ data[2] = top; -+ data[3] = bottom; - - meta_topic (META_DEBUG_GEOMETRY, - "Setting _NET_FRAME_EXTENTS on managed window 0x%lx " -@@ -1482,10 +1623,11 @@ meta_window_x11_move_resize_internal (MetaWindow *window, - configure_frame_first = size_dx + size_dy >= 0; - - values.border_width = 0; -- values.x = client_rect.x; -- values.y = client_rect.y; -- values.width = client_rect.width; -- values.height = client_rect.height; -+ meta_window_x11_stage_to_protocol (window_x11, -+ client_rect.x, client_rect.y, -+ client_rect.width, client_rect.height, -+ &values.x, &values.y, -+ &values.width, &values.height); - - mask = 0; - if (is_configure_request && priv->border_width != 0) -@@ -1591,6 +1733,10 @@ meta_window_x11_update_struts (MetaWindow *window) - strut_begin = struts[4+(i*2)]; - strut_end = struts[4+(i*2)+1]; - -+ meta_window_x11_protocol_to_stage (META_WINDOW_X11 (window), -+ strut_begin, strut_end, thickness, 0, -+ &strut_begin, &strut_end, &thickness, NULL); -+ - temp = g_new0 (MetaStrut, 1); - temp->side = 1 << i; /* See MetaSide def. Matches nicely, eh? */ - meta_display_get_size (window->display, -@@ -1655,6 +1801,10 @@ meta_window_x11_update_struts (MetaWindow *window) - if (thickness == 0) - continue; - -+ meta_window_x11_protocol_to_stage (META_WINDOW_X11 (window), -+ thickness, 0, 0, 0, -+ &thickness, NULL, NULL, NULL); -+ - temp = g_new0 (MetaStrut, 1); - temp->side = 1 << i; - meta_display_get_size (window->display, -@@ -2040,9 +2190,10 @@ static void - meta_window_x11_constructed (GObject *object) - { - MetaWindow *window = META_WINDOW (object); -- MetaWindowX11 *x11_window = META_WINDOW_X11 (object); -- MetaWindowX11Private *priv = meta_window_x11_get_instance_private (x11_window); -+ MetaWindowX11 *window_x11 = META_WINDOW_X11 (object); -+ MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); - XWindowAttributes attrs = priv->attributes; -+ MtkRectangle rect; - - meta_verbose ("attrs->map_state = %d (%s)", - attrs.map_state, -@@ -2057,16 +2208,17 @@ meta_window_x11_constructed (GObject *object) - window->client_type = META_WINDOW_CLIENT_TYPE_X11; - window->override_redirect = attrs.override_redirect; - -- window->rect.x = attrs.x; -- window->rect.y = attrs.y; -- window->rect.width = attrs.width; -- window->rect.height = attrs.height; -+ meta_window_x11_protocol_to_stage (window_x11, -+ attrs.x, attrs.y, attrs.width, attrs.height, -+ &rect.x, &rect.y, &rect.width, &rect.height); -+ -+ window->rect = rect; - - /* size_hints are the "request" */ -- window->size_hints.x = attrs.x; -- window->size_hints.y = attrs.y; -- window->size_hints.width = attrs.width; -- window->size_hints.height = attrs.height; -+ window->size_hints.x = rect.x; -+ window->size_hints.y = rect.y; -+ window->size_hints.width = rect.width; -+ window->size_hints.height = rect.height; - - window->depth = attrs.depth; - priv->xvisual = attrs.visual; -@@ -2076,11 +2228,11 @@ meta_window_x11_constructed (GObject *object) - - window->decorated = TRUE; - window->hidden = FALSE; -- priv->border_width = attrs.border_width; - priv->xclient_leader = None; - -- priv->keys_grabbed = FALSE; -- priv->grab_on_frame = FALSE; -+ meta_window_x11_protocol_to_stage (window_x11, -+ attrs.border_width, 0, 0, 0, -+ &priv->border_width, NULL, NULL, NULL); - - g_signal_connect (window, "notify::decorated", - G_CALLBACK (meta_window_x11_update_input_region), -@@ -2192,6 +2344,8 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) - klass->thaw_commits = meta_window_x11_impl_thaw_commits; - klass->always_update_shape = meta_window_x11_impl_always_update_shape; - klass->process_property_notify = meta_window_x11_impl_process_property_notify; -+ klass->stage_to_protocol = meta_window_x11_real_stage_to_protocol; -+ klass->protocol_to_stage = meta_window_x11_real_protocol_to_stage; - - obj_props[PROP_ATTRIBUTES] = - g_param_spec_pointer ("attributes", NULL, NULL, -@@ -2473,7 +2627,10 @@ meta_window_x11_update_input_region (MetaWindow *window) - else - { - /* Window has a custom shape. */ -- region = region_create_from_x_rectangles (rects, n_rects); -+ g_autoptr (MtkRegion) protocol_region = NULL; -+ -+ protocol_region = region_create_from_x_rectangles (rects, n_rects); -+ region = region_protocol_to_stage (protocol_region, window_x11); - } - - meta_XFree (rects); -@@ -2549,7 +2706,10 @@ meta_window_x11_update_shape_region (MetaWindow *window) - - if (rects) - { -- region = region_create_from_x_rectangles (rects, n_rects); -+ g_autoptr (MtkRegion) protocol_region = NULL; -+ -+ protocol_region = region_create_from_x_rectangles (rects, n_rects); -+ region = region_protocol_to_stage (protocol_region, window_x11); - XFree (rects); - } - } -@@ -2818,6 +2978,7 @@ meta_window_x11_configure_request (MetaWindow *window, - { - MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); - MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); -+ int new_x, new_y, new_width, new_height; - - /* Note that x, y is the corner of the window border, - * and width, height is the size of the window inside -@@ -2826,15 +2987,25 @@ meta_window_x11_configure_request (MetaWindow *window, - * requested border here. - */ - if (event->xconfigurerequest.value_mask & CWBorderWidth) -- priv->border_width = event->xconfigurerequest.border_width; -+ { -+ meta_window_x11_protocol_to_stage (window_x11, -+ event->xconfigurerequest.border_width, 0, 0, 0, -+ &priv->border_width, NULL, NULL, NULL); -+ } - -- meta_window_move_resize_request(window, -- event->xconfigurerequest.value_mask, -- window->size_hints.win_gravity, -- event->xconfigurerequest.x, -- event->xconfigurerequest.y, -- event->xconfigurerequest.width, -- event->xconfigurerequest.height); -+ meta_window_x11_protocol_to_stage (window_x11, -+ event->xconfigurerequest.x, event->xconfigurerequest.y, -+ event->xconfigurerequest.width, event->xconfigurerequest.height, -+ &new_x, &new_y, -+ &new_width, &new_height); -+ -+ meta_window_move_resize_request (window, -+ event->xconfigurerequest.value_mask, -+ window->size_hints.win_gravity, -+ new_x, -+ new_y, -+ new_width, -+ new_height); - - /* Handle stacking. We only handle raises/lowers, mostly because - * stack.c really can't deal with anything else. I guess we'll fix -@@ -3330,8 +3501,13 @@ meta_window_x11_client_message (MetaWindow *window, - guint32 timestamp; - MetaWindowDrag *window_drag; - -- x_root = event->xclient.data.l[0]; -- y_root = event->xclient.data.l[1]; -+ meta_window_x11_protocol_to_stage (window_x11, -+ event->xclient.data.l[0], -+ event->xclient.data.l[1], -+ 0, 0, -+ &x_root, -+ &y_root, -+ NULL, NULL); - action = event->xclient.data.l[2]; - button = event->xclient.data.l[3]; - -@@ -3495,6 +3671,7 @@ meta_window_x11_client_message (MetaWindow *window, - { - MetaGravity gravity; - guint value_mask; -+ int x, y, width, height; - - gravity = (MetaGravity) (event->xclient.data.l[0] & 0xff); - value_mask = (event->xclient.data.l[0] & 0xf00) >> 8; -@@ -3503,13 +3680,20 @@ meta_window_x11_client_message (MetaWindow *window, - if (gravity == 0) - gravity = window->size_hints.win_gravity; - -+ meta_window_x11_protocol_to_stage (window_x11, -+ event->xclient.data.l[1], -+ event->xclient.data.l[2], -+ event->xclient.data.l[3], -+ event->xclient.data.l[4], -+ &x, &y, &width, &height); -+ - meta_window_move_resize_request(window, - value_mask, - gravity, -- event->xclient.data.l[1], /* x */ -- event->xclient.data.l[2], /* y */ -- event->xclient.data.l[3], /* width */ -- event->xclient.data.l[4]); /* height */ -+ x, -+ y, -+ width, -+ height); - } - else if (event->xclient.message_type == - x11_display->atom__NET_ACTIVE_WINDOW && -@@ -3566,11 +3750,15 @@ meta_window_x11_client_message (MetaWindow *window, - else if (event->xclient.message_type == - x11_display->atom__GTK_SHOW_WINDOW_MENU) - { -- gulong x, y; -+ int x, y; - - /* l[0] is device_id, which we don't use */ -- x = event->xclient.data.l[1]; -- y = event->xclient.data.l[2]; -+ meta_window_x11_protocol_to_stage (window_x11, -+ event->xclient.data.l[1], -+ event->xclient.data.l[2], -+ 0, 0, -+ &x, &y, -+ NULL, NULL); - - meta_window_show_menu (window, META_WINDOW_MENU_WM, x, y); - } -@@ -4092,10 +4280,11 @@ meta_window_x11_configure_notify (MetaWindow *window, - g_assert (window->override_redirect); - g_assert (window->frame == NULL); - -- window->rect.x = event->x; -- window->rect.y = event->y; -- window->rect.width = event->width; -- window->rect.height = event->height; -+ meta_window_x11_protocol_to_stage (window_x11, -+ event->x, event->y, -+ event->width, event->height, -+ &window->rect.x, &window->rect.y, -+ &window->rect.width, &window->rect.height); - - priv->client_rect = window->rect; - window->buffer_rect = window->rect; -diff --git a/src/x11/window-x11.h b/src/x11/window-x11.h -index 205eaaa63..fa3fbea6a 100644 ---- a/src/x11/window-x11.h -+++ b/src/x11/window-x11.h -@@ -45,6 +45,24 @@ struct _MetaWindowX11Class - gboolean (*always_update_shape) (MetaWindow *window); - void (*process_property_notify) (MetaWindow *window, - XPropertyEvent *event); -+ void (*stage_to_protocol) (MetaWindowX11 *window_x11, -+ int stage_x, -+ int stage_y, -+ int stage_width, -+ int stage_height, -+ int *protocol_x, -+ int *protocol_y, -+ int *protocol_width, -+ int *protocol_height); -+ void (*protocol_to_stage) (MetaWindowX11 *window_x11, -+ int protocol_x, -+ int protocol_y, -+ int protocol_width, -+ int protocol_height, -+ int *stage_x, -+ int *stage_y, -+ int *stage_width, -+ int *stage_height); - }; - - MetaWindow * meta_window_x11_new (MetaDisplay *display, -@@ -112,3 +130,23 @@ gboolean meta_window_x11_has_alpha_channel (MetaWindow *window); - - META_EXPORT - Window meta_window_x11_get_xwindow (MetaWindow *window); -+ -+void meta_window_x11_stage_to_protocol (MetaWindowX11 *window_x11, -+ int stage_x, -+ int stage_y, -+ int stage_width, -+ int stage_heigth, -+ int *protocol_x, -+ int *protocol_y, -+ int *protocol_width, -+ int *protocol_height); -+ -+void meta_window_x11_protocol_to_stage (MetaWindowX11 *window_x11, -+ int protocol_x, -+ int protocol_y, -+ int protocol_width, -+ int protocol_height, -+ int *stage_x, -+ int *stage_y, -+ int *stage_width, -+ int *stage_heigth); --- -2.45.2 - - -From 86256022a13ace5fa149553acb790a2665878098 Mon Sep 17 00:00:00 2001 -From: HydroH -Date: Tue, 21 May 2024 19:14:55 +0800 -Subject: [PATCH 5/6] Fix incorrect value for xwayland-native-scaling in - org.gnome.mutter.gchema.xml.in - ---- - data/org.gnome.mutter.gschema.xml.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/data/org.gnome.mutter.gschema.xml.in b/data/org.gnome.mutter.gschema.xml.in -index 18abd8d51..6751a8d7a 100644 ---- a/data/org.gnome.mutter.gschema.xml.in -+++ b/data/org.gnome.mutter.gschema.xml.in -@@ -5,7 +5,7 @@ - - - -- -+ - - - -Date: Tue, 21 May 2024 19:15:36 +0800 -Subject: [PATCH 6/6] Correctly set bounding region for undecorated windows - ---- - src/x11/window-x11.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c -index b72d5b6d5..c48b91e93 100644 ---- a/src/x11/window-x11.c -+++ b/src/x11/window-x11.c -@@ -2572,8 +2572,13 @@ meta_window_x11_update_input_region (MetaWindow *window) - else - { - xwindow = priv->xwindow; -- bounding_rect.width = priv->client_rect.width; -- bounding_rect.height = priv->client_rect.height; -+ meta_window_x11_stage_to_protocol(window_x11, -+ 0, 0, -+ priv->client_rect.width, -+ priv->client_rect.height, -+ NULL, NULL, -+ &bounding_rect.width, -+ &bounding_rect.height); - } - - if (META_X11_DISPLAY_HAS_SHAPE (x11_display)) --- -2.45.2 diff --git a/modules/users/common/home-manager/gnome.nix b/modules/users/common/home-manager/gnome.nix index f187868..e9d98e1 100644 --- a/modules/users/common/home-manager/gnome.nix +++ b/modules/users/common/home-manager/gnome.nix @@ -5,11 +5,6 @@ "org/gnome/mutter" = { edge-tiling = true; workspaces-only-on-primary = false; - experimental-features = [ - "scale-monitor-framebuffer" # Fractional scaling - "xwayland-native-scaling" # Related to fractional scaline - "variable-refresh-rate" # VRR - ]; }; "org/gnome/desktop/interface" = {