Skip to content

Commit

Permalink
Unix: Filter X visual by X screen
Browse files Browse the repository at this point in the history
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 SFML#724.
  • Loading branch information
DrMcCoy committed Oct 26, 2018
1 parent ac98be7 commit de0ba77
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/SFML/Window/Unix/GlxContext.cpp
Expand Up @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit de0ba77

Please sign in to comment.