From 3c07a01c42d56c882bde33b7456c367781fabfee Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Thu, 2 Feb 2023 14:17:30 +0100 Subject: [PATCH] xwayland: Use xdg-output name for XRandR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, Xwayland assigns sequential output names for XRandR. When an output is hotplugged, a new name is assigned sequentially (XWAYLAND0, XWAYLAND1, etc.). This is a problem because if a monitor is unplugged and plugged again, it will get a new name each time. Luckily, xdg-output provides us with a name for the outputs. Even though the protocol states that the name is not a reflection of the underlying DRM connector name, it is to remain consistent across sessions with the same hardware and software configuration. So we could use the xdg-output name for the XRandR reported name for the output. Doing so is a bit tricky though, because the output name is set at creation and is not supposed to change. The xdg-output event that provides us with the name will come at a later time. So we just allocate a default fixed size for the output name at creation and just replace the default output name with the xdg-output name when that is known. Also, historically, some X11 clients were expecting output names in Xwayland to be named XWAYLAND and used that to check whether they were running on Xwayland. Those clients should now use the Xwayland X11 extension which is designed specifically for that purpose. Signed-off-by: Olivier Fourdan Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1353 See-also: https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/954 Reviewed-by: Michel Dänzer --- hw/xwayland/xwayland-output.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c index 24c554b57..8e387e760 100644 --- a/hw/xwayland/xwayland-output.c +++ b/hw/xwayland/xwayland-output.c @@ -35,6 +35,8 @@ #include "xdg-output-unstable-v1-client-protocol.h" +#define MAX_OUTPUT_NAME 256 + static void xwl_output_get_xdg_output(struct xwl_output *xwl_output); static Rotation @@ -658,6 +660,21 @@ apply_output_change(struct xwl_output *xwl_output) RRTellChanged(xwl_screen->screen); } +static void +xwl_output_set_name(struct xwl_output *xwl_output, const char *name) +{ + if (xwl_output->randr_output == NULL) + return; /* rootful */ + + /* Check whether the compositor is sending us something useful */ + if (!name || !strlen(name)) { + ErrorF("Not using the provided output name, invalid"); + return; + } + + snprintf(xwl_output->randr_output->name, MAX_OUTPUT_NAME, "%s", name); +} + static void output_handle_done(void *data, struct wl_output *wl_output) { @@ -719,6 +736,9 @@ static void xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, const char *name) { + struct xwl_output *xwl_output = data; + + xwl_output_set_name(xwl_output, name); } static void @@ -774,7 +794,7 @@ struct xwl_output * xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id, Bool with_xrandr) { struct xwl_output *xwl_output; - char name[256]; + char name[MAX_OUTPUT_NAME]; xwl_output = calloc(1, sizeof *xwl_output); if (xwl_output == NULL) { @@ -795,7 +815,7 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id, Bool with_xrandr) xwl_output->xwl_screen = xwl_screen; if (with_xrandr) { - snprintf(name, sizeof name, "XWAYLAND%d", + snprintf(name, MAX_OUTPUT_NAME, "XWAYLAND%d", xwl_screen_get_next_output_serial(xwl_screen)); xwl_output->randr_crtc = RRCrtcCreate(xwl_screen->screen, xwl_output); @@ -806,7 +826,7 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id, Bool with_xrandr) RRCrtcSetRotations (xwl_output->randr_crtc, ALL_ROTATIONS); xwl_output->randr_output = RROutputCreate(xwl_screen->screen, name, - strlen(name), xwl_output); + MAX_OUTPUT_NAME, xwl_output); if (!xwl_output->randr_output) { ErrorF("Failed creating RandR Output\n"); goto err;