From de0ba77d3b27a26e971290eafd5f08877477cf2f Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 26 Oct 2018 21:11:03 +0200 Subject: [PATCH] Unix: Filter X visual by X screen On an X set-up with multiple monitors running separate X screens (as opposed to merging them into one large X screen using Xinerama), the selected X visual needs to be one for the screen where the colormap, window, and other X resources are created. In fact, all these need to match, and the GL context as well. Most of the SFML windowing and graphics code uses (X)DefaultScreen() for that, which is fine. Combined with XOpenDisplay(NULL), this will create the window on the screen (and monitor) selected by the DISPLAY enviroment variable. :0.0 will be the first monitor, :0.1 the second, etc. However, XGetVisualInfo() will return visuals for *all* screens, not just the default one. They seem to be ordered by screen number, but I don't think the standard makes any guarantees there. If the visual doesn't match up with the screen, this will abort with an X error. BadMatch, in many cases. This means that in addition to other filtering, GlxContext::selectBestVisual() needs to filter the visuals by screen number, otherwise SFML won't work at all on any screens but the first. This fixes issue #724. --- src/SFML/Window/Unix/GlxContext.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/SFML/Window/Unix/GlxContext.cpp b/src/SFML/Window/Unix/GlxContext.cpp index cd022364..507cfcb0 100644 --- a/src/SFML/Window/Unix/GlxContext.cpp +++ b/src/SFML/Window/Unix/GlxContext.cpp @@ -316,6 +316,8 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe // Make sure that extensions are initialized ensureExtensionsInit(display, DefaultScreen(display)); + const int screen = DefaultScreen(display); + // Retrieve all the visuals int count; XVisualInfo* visuals = XGetVisualInfo(display, 0, NULL, &count); @@ -326,6 +328,10 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe XVisualInfo bestVisual = XVisualInfo(); for (int i = 0; i < count; ++i) { + // Filter by screen + if (visuals[i].screen != screen) + continue; + // Check mandatory attributes int doubleBuffer; glXGetConfig(display, &visuals[i], GLX_DOUBLEBUFFER, &doubleBuffer);