xwayland: Use xdg-output name for XRandR
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<x> 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 <ofourdan@redhat.com> 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 <mdaenzer@redhat.com>
This commit is contained in:
parent
ddcbb46f97
commit
3c07a01c42
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue