mirror of https://github.com/libsdl-org/SDL.git
Handle XWayland not sending display disconnected events
Also updated X11_CheckDisplaysMoved() to handle multiple X11 screens Fixes https://github.com/libsdl-org/SDL/issues/12462
This commit is contained in:
parent
ca9bc6b164
commit
e9632c83c7
|
|
@ -555,24 +555,75 @@ static XRRScreenResources *X11_GetScreenResources(Display *dpy, int screen)
|
||||||
|
|
||||||
static void X11_CheckDisplaysMoved(SDL_VideoDevice *_this, Display *dpy)
|
static void X11_CheckDisplaysMoved(SDL_VideoDevice *_this, Display *dpy)
|
||||||
{
|
{
|
||||||
const int screen = DefaultScreen(dpy);
|
const int screencount = ScreenCount(dpy);
|
||||||
XRRScreenResources *res = X11_GetScreenResources(dpy, screen);
|
|
||||||
if (!res) {
|
SDL_DisplayID *displays = SDL_GetDisplays(NULL);
|
||||||
|
if (!displays) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_DisplayID *displays = SDL_GetDisplays(NULL);
|
for (int screen = 0; screen < screencount; ++screen) {
|
||||||
if (displays) {
|
XRRScreenResources *res = X11_GetScreenResources(dpy, screen);
|
||||||
|
if (!res) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; displays[i]; ++i) {
|
for (int i = 0; displays[i]; ++i) {
|
||||||
SDL_VideoDisplay *display = SDL_GetVideoDisplay(displays[i]);
|
SDL_VideoDisplay *display = SDL_GetVideoDisplay(displays[i]);
|
||||||
const SDL_DisplayData *displaydata = display->internal;
|
const SDL_DisplayData *displaydata = display->internal;
|
||||||
|
if (displaydata->screen == screen) {
|
||||||
X11_UpdateXRandRDisplay(_this, dpy, screen, displaydata->xrandr_output, res, display);
|
X11_UpdateXRandRDisplay(_this, dpy, screen, displaydata->xrandr_output, res, display);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
X11_XRRFreeScreenResources(res);
|
||||||
|
}
|
||||||
SDL_free(displays);
|
SDL_free(displays);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void X11_CheckDisplaysRemoved(SDL_VideoDevice *_this, Display *dpy)
|
||||||
|
{
|
||||||
|
const int screencount = ScreenCount(dpy);
|
||||||
|
int num_displays = 0;
|
||||||
|
|
||||||
|
SDL_DisplayID *displays = SDL_GetDisplays(&num_displays);
|
||||||
|
if (!displays) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int screen = 0; screen < screencount; ++screen) {
|
||||||
|
XRRScreenResources *res = X11_GetScreenResources(dpy, screen);
|
||||||
|
if (!res) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int output = 0; output < res->noutput; output++) {
|
||||||
|
for (int i = 0; i < num_displays; ++i) {
|
||||||
|
if (!displays[i]) {
|
||||||
|
// We already removed this display from the list
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_VideoDisplay *display = SDL_GetVideoDisplay(displays[i]);
|
||||||
|
const SDL_DisplayData *displaydata = display->internal;
|
||||||
|
if (displaydata->xrandr_output == res->outputs[output]) {
|
||||||
|
// This display is active, remove it from the list
|
||||||
|
displays[i] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
X11_XRRFreeScreenResources(res);
|
X11_XRRFreeScreenResources(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < num_displays; ++i) {
|
||||||
|
if (displays[i]) {
|
||||||
|
// This display wasn't in the XRandR list
|
||||||
|
SDL_DelVideoDisplay(displays[i], true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_free(displays);
|
||||||
|
}
|
||||||
|
|
||||||
static void X11_HandleXRandROutputChange(SDL_VideoDevice *_this, const XRROutputChangeNotifyEvent *ev)
|
static void X11_HandleXRandROutputChange(SDL_VideoDevice *_this, const XRROutputChangeNotifyEvent *ev)
|
||||||
{
|
{
|
||||||
SDL_DisplayID *displays;
|
SDL_DisplayID *displays;
|
||||||
|
|
@ -580,9 +631,12 @@ static void X11_HandleXRandROutputChange(SDL_VideoDevice *_this, const XRROutput
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("XRROutputChangeNotifyEvent! [output=%u, crtc=%u, mode=%u, rotation=%u, connection=%u]", (unsigned int) ev->output, (unsigned int) ev->crtc, (unsigned int) ev->mode, (unsigned int) ev->rotation, (unsigned int) ev->connection);
|
printf("XRROutputChangeNotifyEvent! [output=%u, crtc=%u, mode=%u, rotation=%u, connection=%u]\n", (unsigned int) ev->output, (unsigned int) ev->crtc, (unsigned int) ev->mode, (unsigned int) ev->rotation, (unsigned int) ev->connection);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// XWayland doesn't always send output disconnected events
|
||||||
|
X11_CheckDisplaysRemoved(_this, ev->display);
|
||||||
|
|
||||||
displays = SDL_GetDisplays(NULL);
|
displays = SDL_GetDisplays(NULL);
|
||||||
if (displays) {
|
if (displays) {
|
||||||
for (i = 0; displays[i]; ++i) {
|
for (i = 0; displays[i]; ++i) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue