6c2dd5fc20
The content of this branch was automatically imported from Fedora ELN with the following as its source: https://src.fedoraproject.org/rpms/xorg-x11-server#eaf442296937a83e622ce4995c5f33122bcd6f02
206 lines
7.5 KiB
Diff
206 lines
7.5 KiB
Diff
From e40d94637207543481769fb570515b782225ff09 Mon Sep 17 00:00:00 2001
|
|
From: Hans de Goede <hdegoede@redhat.com>
|
|
Date: Mon, 2 Sep 2019 17:32:45 +0200
|
|
Subject: [PATCH xserver 13/24] xwayland: Set _XWAYLAND_RANDR_EMU_MONITOR_RECTS
|
|
property for resolution emulation
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Apps using randr to change the resolution when going fullscreen, in
|
|
combination with _NET_WM_STATE_FULLSCREEN to tell the window-manager (WM)
|
|
to make their window fullscreen, expect the WM to give the fullscreen window
|
|
the size of the emulated resolution as would happen when run under Xorg (*).
|
|
|
|
We need the WM to emulate this behavior for these apps to work correctly,
|
|
with Xwaylands resolution change emulation. For the WM to emulate this,
|
|
it needs to know about the emulated resolution for the Windows owning
|
|
client for each monitor.
|
|
|
|
This commit adds a _XWAYLAND_RANDR_EMU_MONITOR_RECTS property, which
|
|
contains 4 Cardinals (32 bit integers) per monitor with resolution
|
|
emulation info. Window-managers can use this to get the emulated
|
|
resolution for the client and size the window correctly.
|
|
|
|
*) Since under Xorg the resolution will actually be changed and after that
|
|
going fullscreen through NET_WM_STATE_FULLSCREEN will size the window to
|
|
be equal to the new resolution.
|
|
|
|
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
|
|
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
|
|
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
(cherry picked from commit 5315f988d9f175e4850f4259f691a68d95ce7ac2)
|
|
---
|
|
hw/xwayland/xwayland-output.c | 77 +++++++++++++++++++++++++++++++++++
|
|
hw/xwayland/xwayland.c | 23 +++++++++++
|
|
hw/xwayland/xwayland.h | 3 ++
|
|
3 files changed, 103 insertions(+)
|
|
|
|
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
|
|
index e09d00108..0d6b9ac9f 100644
|
|
--- a/hw/xwayland/xwayland-output.c
|
|
+++ b/hw/xwayland/xwayland-output.c
|
|
@@ -29,6 +29,7 @@
|
|
|
|
#include "xwayland.h"
|
|
#include <randrstr.h>
|
|
+#include <X11/Xatom.h>
|
|
|
|
#define ALL_ROTATIONS (RR_Rotate_0 | \
|
|
RR_Rotate_90 | \
|
|
@@ -391,6 +392,80 @@ xwl_output_find_mode(struct xwl_output *xwl_output,
|
|
return NULL;
|
|
}
|
|
|
|
+struct xwl_output_randr_emu_prop {
|
|
+ Atom atom;
|
|
+ uint32_t rects[XWL_CLIENT_MAX_EMULATED_MODES][4];
|
|
+ int rect_count;
|
|
+};
|
|
+
|
|
+static void
|
|
+xwl_output_randr_emu_prop(struct xwl_screen *xwl_screen, ClientPtr client,
|
|
+ struct xwl_output_randr_emu_prop *prop)
|
|
+{
|
|
+ static const char atom_name[] = "_XWAYLAND_RANDR_EMU_MONITOR_RECTS";
|
|
+ struct xwl_emulated_mode *emulated_mode;
|
|
+ struct xwl_output *xwl_output;
|
|
+ int index = 0;
|
|
+
|
|
+ prop->atom = MakeAtom(atom_name, strlen(atom_name), TRUE);
|
|
+
|
|
+ xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
|
|
+ emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
|
|
+ if (!emulated_mode)
|
|
+ continue;
|
|
+
|
|
+ prop->rects[index][0] = xwl_output->x;
|
|
+ prop->rects[index][1] = xwl_output->y;
|
|
+ prop->rects[index][2] = emulated_mode->width;
|
|
+ prop->rects[index][3] = emulated_mode->height;
|
|
+ index++;
|
|
+ }
|
|
+
|
|
+ prop->rect_count = index;
|
|
+}
|
|
+
|
|
+static void
|
|
+xwl_output_set_randr_emu_prop(WindowPtr window,
|
|
+ struct xwl_output_randr_emu_prop *prop)
|
|
+{
|
|
+ if (!xwl_window_is_toplevel(window))
|
|
+ return;
|
|
+
|
|
+ if (prop->rect_count) {
|
|
+ dixChangeWindowProperty(serverClient, window, prop->atom,
|
|
+ XA_CARDINAL, 32, PropModeReplace,
|
|
+ prop->rect_count * 4, prop->rects, TRUE);
|
|
+ } else {
|
|
+ DeleteProperty(serverClient, window, prop->atom);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+xwl_output_set_randr_emu_prop_callback(void *resource, XID id, void *user_data)
|
|
+{
|
|
+ xwl_output_set_randr_emu_prop(resource, user_data);
|
|
+}
|
|
+
|
|
+static void
|
|
+xwl_output_set_randr_emu_props(struct xwl_screen *xwl_screen, ClientPtr client)
|
|
+{
|
|
+ struct xwl_output_randr_emu_prop prop = {};
|
|
+
|
|
+ xwl_output_randr_emu_prop(xwl_screen, client, &prop);
|
|
+ FindClientResourcesByType(client, RT_WINDOW,
|
|
+ xwl_output_set_randr_emu_prop_callback, &prop);
|
|
+}
|
|
+
|
|
+void
|
|
+xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
|
|
+ WindowPtr window)
|
|
+{
|
|
+ struct xwl_output_randr_emu_prop prop = {};
|
|
+
|
|
+ xwl_output_randr_emu_prop(xwl_screen, wClient(window), &prop);
|
|
+ xwl_output_set_randr_emu_prop(window, &prop);
|
|
+}
|
|
+
|
|
void
|
|
xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client,
|
|
RRModePtr mode, Bool from_vidmode)
|
|
@@ -405,6 +480,8 @@ xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client,
|
|
xwl_output_add_emulated_mode_for_client(xwl_output, client, mode, from_vidmode);
|
|
|
|
xwl_screen_check_resolution_change_emulation(xwl_output->xwl_screen);
|
|
+
|
|
+ xwl_output_set_randr_emu_props(xwl_output->xwl_screen, client);
|
|
}
|
|
|
|
static void
|
|
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
|
|
index 2e01822fd..ac4d98e6a 100644
|
|
--- a/hw/xwayland/xwayland.c
|
|
+++ b/hw/xwayland/xwayland.c
|
|
@@ -692,6 +692,27 @@ xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen)
|
|
xwl_window_check_resolution_change_emulation(xwl_window);
|
|
}
|
|
|
|
+/* This checks if the passed in Window is a toplevel client window, note this
|
|
+ * returns false for window-manager decoration windows and returns true for
|
|
+ * the actual client top-level window even if it has been reparented to
|
|
+ * a window-manager decoration window.
|
|
+ */
|
|
+Bool
|
|
+xwl_window_is_toplevel(WindowPtr window)
|
|
+{
|
|
+ struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen);
|
|
+
|
|
+ if (xwl_screen_client_is_window_manager(xwl_screen, wClient(window)))
|
|
+ return FALSE;
|
|
+
|
|
+ /* CSD and override-redirect toplevel windows */
|
|
+ if (window_get_damage(window))
|
|
+ return TRUE;
|
|
+
|
|
+ /* Normal toplevel client windows, reparented to decoration window */
|
|
+ return (window->parent && window_get_damage(window->parent));
|
|
+}
|
|
+
|
|
static void
|
|
xwl_window_init_allow_commits(struct xwl_window *xwl_window)
|
|
{
|
|
@@ -857,6 +878,8 @@ xwl_realize_window(WindowPtr window)
|
|
return FALSE;
|
|
}
|
|
|
|
+ xwl_output_set_window_randr_emu_props(xwl_screen, window);
|
|
+
|
|
return ensure_surface_for_window(window);
|
|
}
|
|
|
|
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
|
|
index 36c4c4c8b..1317ae5bb 100644
|
|
--- a/hw/xwayland/xwayland.h
|
|
+++ b/hw/xwayland/xwayland.h
|
|
@@ -420,6 +420,7 @@ Bool xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen);
|
|
struct xwl_output *xwl_screen_get_first_output(struct xwl_screen *xwl_screen);
|
|
void xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen);
|
|
Bool xwl_window_has_viewport_enabled(struct xwl_window *xwl_window);
|
|
+Bool xwl_window_is_toplevel(WindowPtr window);
|
|
|
|
void xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *tool);
|
|
void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
|
|
@@ -458,6 +459,8 @@ RRModePtr xwl_output_find_mode(struct xwl_output *xwl_output,
|
|
void xwl_output_set_emulated_mode(struct xwl_output *xwl_output,
|
|
ClientPtr client, RRModePtr mode,
|
|
Bool from_vidmode);
|
|
+void xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
|
|
+ WindowPtr window);
|
|
|
|
RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
|
|
float VRefresh, Bool Reduced, Bool Interlaced);
|
|
--
|
|
2.26.2
|
|
|