|
|
fdf2dbc |
From 7d2dd5dee5873fd817c010e73535701e1d647b27 Mon Sep 17 00:00:00 2001
|
|
|
fdf2dbc |
From: Hans de Goede <hdegoede@redhat.com>
|
|
|
fdf2dbc |
Date: Tue, 3 Sep 2019 16:18:00 +0200
|
|
|
fdf2dbc |
Subject: [PATCH 2/2] window-xwayland: Add Xwayland fullscreen games workaround
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
This is a workaround for X11 games which use randr to change the resolution
|
|
|
fdf2dbc |
in combination with NET_WM_STATE_FULLSCREEN when going fullscreen.
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
Newer versions of Xwayland support the randr part of this by supporting randr
|
|
|
fdf2dbc |
resolution change emulation in combination with using WPviewport to scale the
|
|
|
fdf2dbc |
app's window (at the emulated resolution) to fill the entire monitor.
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
Apps using randr in combination with NET_WM_STATE_FULLSCREEN expect the
|
|
|
fdf2dbc |
fullscreen window to have the size of the emulated randr resolution since
|
|
|
fdf2dbc |
when running on regular Xorg the resolution will actually be changed and
|
|
|
fdf2dbc |
after that going fullscreen through NET_WM_STATE_FULLSCREEN will size
|
|
|
fdf2dbc |
the window to be equal to the new resolution.
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
We need to emulate this behavior for these games to work correctly.
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
Xwayland's emulated resolution is a per X11 client setting and Xwayland
|
|
|
fdf2dbc |
will set a special _XWAYLAND_RANDR_EMU_MONITOR_RECTS property on the
|
|
|
fdf2dbc |
toplevel windows of a client (and only those of that client), which has
|
|
|
fdf2dbc |
changed the (emulated) resolution through a randr call.
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
This commit checks for that property and if it is set adjusts the fullscreen
|
|
|
fdf2dbc |
monitor rect for this window to match the emulated resolution.
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
Here is a step-by-step of such an app going fullscreen:
|
|
|
fdf2dbc |
1. App changes monitor resolution with randr.
|
|
|
fdf2dbc |
2. Xwayland sets the _XWAYLAND_RANDR_EMU_MONITOR_RECTS property on all the
|
|
|
fdf2dbc |
apps current and future windows. This property contains the origin of the
|
|
|
fdf2dbc |
monitor for which the emulated resolution is set and the emulated
|
|
|
fdf2dbc |
resolution.
|
|
|
fdf2dbc |
3. App sets _NET_WM_FULLSCREEN.
|
|
|
fdf2dbc |
4. We check the property and adjust the app's fullscreen size to match
|
|
|
fdf2dbc |
the emulated resolution.
|
|
|
fdf2dbc |
5. Xwayland sees a Window at monitor origin fully covering the emulated
|
|
|
fdf2dbc |
monitor resolution. Xwayland sets a viewport making the emulated
|
|
|
fdf2dbc |
resolution sized window cover the full actual monitor resolution.
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
https://gitlab.gnome.org/GNOME/mutter/merge_requests/739
|
|
|
fdf2dbc |
---
|
|
|
fdf2dbc |
src/wayland/meta-window-xwayland.c | 89 ++++++++++++++++++++++++++++++
|
|
|
fdf2dbc |
src/x11/atomnames.h | 1 +
|
|
|
fdf2dbc |
2 files changed, 90 insertions(+)
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
diff --git a/src/wayland/meta-window-xwayland.c b/src/wayland/meta-window-xwayland.c
|
|
|
fdf2dbc |
index 6f073893a..9967f439a 100644
|
|
|
fdf2dbc |
--- a/src/wayland/meta-window-xwayland.c
|
|
|
fdf2dbc |
+++ b/src/wayland/meta-window-xwayland.c
|
|
|
fdf2dbc |
@@ -20,6 +20,7 @@
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
#include "x11/window-x11.h"
|
|
|
fdf2dbc |
#include "x11/window-x11-private.h"
|
|
|
fdf2dbc |
+#include "x11/xprops.h"
|
|
|
fdf2dbc |
#include "wayland/meta-window-xwayland.h"
|
|
|
fdf2dbc |
#include "wayland/meta-wayland.h"
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
@@ -53,6 +54,93 @@ meta_window_xwayland_init (MetaWindowXwayland *window_xwayland)
|
|
|
fdf2dbc |
{
|
|
|
fdf2dbc |
}
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
+/**
|
|
|
fdf2dbc |
+ * meta_window_xwayland_adjust_fullscreen_monitor_rect:
|
|
|
fdf2dbc |
+ *
|
|
|
fdf2dbc |
+ * This function implements a workaround for X11 apps which use randr to change the
|
|
|
fdf2dbc |
+ * the monitor resolution, followed by setting _NET_WM_FULLSCREEN to make the
|
|
|
fdf2dbc |
+ * window-manager fullscreen them.
|
|
|
fdf2dbc |
+ *
|
|
|
fdf2dbc |
+ * Newer versions of Xwayland support the randr part of this by supporting randr
|
|
|
fdf2dbc |
+ * resolution change emulation in combination with using WPviewport to scale the
|
|
|
fdf2dbc |
+ * app's window (at the emulated resolution) to fill the entire monitor.
|
|
|
fdf2dbc |
+ *
|
|
|
fdf2dbc |
+ * Apps using randr in combination with NET_WM_STATE_FULLSCREEN expect the
|
|
|
fdf2dbc |
+ * fullscreen window to have the size of the emulated randr resolution since
|
|
|
fdf2dbc |
+ * when running on regular Xorg the resolution will actually be changed and
|
|
|
fdf2dbc |
+ * after that going fullscreen through NET_WM_STATE_FULLSCREEN will size
|
|
|
fdf2dbc |
+ * the window to be equal to the new resolution.
|
|
|
fdf2dbc |
+ *
|
|
|
fdf2dbc |
+ * We need to emulate this behavior for these apps to work correctly.
|
|
|
fdf2dbc |
+ *
|
|
|
fdf2dbc |
+ * Xwayland's emulated resolution is a per X11 client setting and Xwayland
|
|
|
fdf2dbc |
+ * will set a special _XWAYLAND_RANDR_EMU_MONITOR_RECTS property on the
|
|
|
fdf2dbc |
+ * toplevel windows of a client (and only those of that client), which has
|
|
|
fdf2dbc |
+ * changed the (emulated) resolution through a randr call.
|
|
|
fdf2dbc |
+ *
|
|
|
fdf2dbc |
+ * Here we check for that property and if it is set we adjust the fullscreen
|
|
|
fdf2dbc |
+ * monitor rect for this window to match the emulated resolution.
|
|
|
fdf2dbc |
+ *
|
|
|
fdf2dbc |
+ * Here is a step-by-step of such an app going fullscreen:
|
|
|
fdf2dbc |
+ * 1. App changes monitor resolution with randr.
|
|
|
fdf2dbc |
+ * 2. Xwayland sets the _XWAYLAND_RANDR_EMU_MONITOR_RECTS property on all the
|
|
|
fdf2dbc |
+ * apps current and future windows. This property contains the origin of the
|
|
|
fdf2dbc |
+ * monitor for which the emulated resolution is set and the emulated
|
|
|
fdf2dbc |
+ * resolution.
|
|
|
fdf2dbc |
+ * 3. App sets _NET_WM_FULLSCREEN.
|
|
|
fdf2dbc |
+ * 4. We check the property and adjust the app's fullscreen size to match
|
|
|
fdf2dbc |
+ * the emulated resolution.
|
|
|
fdf2dbc |
+ * 5. Xwayland sees a Window at monitor origin fully covering the emulated
|
|
|
fdf2dbc |
+ * monitor resolution. Xwayland sets a viewport making the emulated
|
|
|
fdf2dbc |
+ * resolution sized window cover the full actual monitor resolution.
|
|
|
fdf2dbc |
+ */
|
|
|
fdf2dbc |
+static void
|
|
|
fdf2dbc |
+meta_window_xwayland_adjust_fullscreen_monitor_rect (MetaWindow *window,
|
|
|
fdf2dbc |
+ MetaRectangle *fs_monitor_rect)
|
|
|
fdf2dbc |
+{
|
|
|
fdf2dbc |
+ MetaX11Display *x11_display = window->display->x11_display;
|
|
|
fdf2dbc |
+ MetaRectangle win_monitor_rect;
|
|
|
fdf2dbc |
+ cairo_rectangle_int_t *rects;
|
|
|
fdf2dbc |
+ uint32_t *list = NULL;
|
|
|
fdf2dbc |
+ int i, n_items = 0;
|
|
|
fdf2dbc |
+
|
|
|
fdf2dbc |
+ if (!window->monitor)
|
|
|
fdf2dbc |
+ {
|
|
|
fdf2dbc |
+ g_warning ("MetaWindow does not have a monitor");
|
|
|
fdf2dbc |
+ return;
|
|
|
fdf2dbc |
+ }
|
|
|
fdf2dbc |
+
|
|
|
fdf2dbc |
+ win_monitor_rect = meta_logical_monitor_get_layout (window->monitor);
|
|
|
fdf2dbc |
+
|
|
|
fdf2dbc |
+ if (!meta_prop_get_cardinal_list (x11_display,
|
|
|
fdf2dbc |
+ window->xwindow,
|
|
|
fdf2dbc |
+ x11_display->atom__XWAYLAND_RANDR_EMU_MONITOR_RECTS,
|
|
|
fdf2dbc |
+ &list, &n_items))
|
|
|
fdf2dbc |
+ return;
|
|
|
fdf2dbc |
+
|
|
|
fdf2dbc |
+ if (n_items % 4)
|
|
|
fdf2dbc |
+ {
|
|
|
fdf2dbc |
+ meta_verbose ("_XWAYLAND_RANDR_EMU_MONITOR_RECTS on %s has %d values which is not a multiple of 4",
|
|
|
fdf2dbc |
+ window->desc, n_items);
|
|
|
fdf2dbc |
+ g_free (list);
|
|
|
fdf2dbc |
+ return;
|
|
|
fdf2dbc |
+ }
|
|
|
fdf2dbc |
+
|
|
|
fdf2dbc |
+ rects = (cairo_rectangle_int_t *) list;
|
|
|
fdf2dbc |
+ n_items = n_items / 4;
|
|
|
fdf2dbc |
+ for (i = 0; i < n_items; i++)
|
|
|
fdf2dbc |
+ {
|
|
|
fdf2dbc |
+ if (rects[i].x == win_monitor_rect.x && rects[i].y == win_monitor_rect.y)
|
|
|
fdf2dbc |
+ {
|
|
|
fdf2dbc |
+ fs_monitor_rect->width = rects[i].width;
|
|
|
fdf2dbc |
+ fs_monitor_rect->height = rects[i].height;
|
|
|
fdf2dbc |
+ break;
|
|
|
fdf2dbc |
+ }
|
|
|
fdf2dbc |
+ }
|
|
|
fdf2dbc |
+
|
|
|
fdf2dbc |
+ g_free (list);
|
|
|
fdf2dbc |
+}
|
|
|
fdf2dbc |
+
|
|
|
fdf2dbc |
static void
|
|
|
fdf2dbc |
meta_window_xwayland_force_restore_shortcuts (MetaWindow *window,
|
|
|
fdf2dbc |
ClutterInputDevice *source)
|
|
|
fdf2dbc |
@@ -115,6 +203,7 @@ meta_window_xwayland_class_init (MetaWindowXwaylandClass *klass)
|
|
|
fdf2dbc |
MetaWindowClass *window_class = META_WINDOW_CLASS (klass);
|
|
|
fdf2dbc |
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
+ window_class->adjust_fullscreen_monitor_rect = meta_window_xwayland_adjust_fullscreen_monitor_rect;
|
|
|
fdf2dbc |
window_class->force_restore_shortcuts = meta_window_xwayland_force_restore_shortcuts;
|
|
|
fdf2dbc |
window_class->shortcuts_inhibited = meta_window_xwayland_shortcuts_inhibited;
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
diff --git a/src/x11/atomnames.h b/src/x11/atomnames.h
|
|
|
fdf2dbc |
index b61f47ff4..4099d5d31 100644
|
|
|
fdf2dbc |
--- a/src/x11/atomnames.h
|
|
|
fdf2dbc |
+++ b/src/x11/atomnames.h
|
|
|
fdf2dbc |
@@ -81,6 +81,7 @@ item(ATOM_PAIR)
|
|
|
fdf2dbc |
item(_XKB_RULES_NAMES)
|
|
|
fdf2dbc |
item(WL_SURFACE_ID)
|
|
|
fdf2dbc |
item(_XWAYLAND_MAY_GRAB_KEYBOARD)
|
|
|
fdf2dbc |
+item(_XWAYLAND_RANDR_EMU_MONITOR_RECTS)
|
|
|
fdf2dbc |
|
|
|
fdf2dbc |
/* Oddities: These are used, and we need atoms for them,
|
|
|
fdf2dbc |
* but when we need all _NET_WM hints (i.e. when we're making
|
|
|
fdf2dbc |
--
|
|
|
fdf2dbc |
2.23.0
|
|
|
fdf2dbc |
|