This commit is contained in:
Erik S. V. Jansson 2016-07-18 15:18:59 +00:00 committed by GitHub
commit 6561ece896
3 changed files with 31 additions and 0 deletions

View File

@ -92,6 +92,7 @@ information on what to include when reporting a bug.
## Changelog
- [X11] Bugfix: Didn't wait until window was visible before setting focus (#789)
- Bugfix: Single compilation unit builds failed due to naming conflicts (#783)
- Bugfix: The range checks for `glfwSetCursorPos` used the wrong minimum (#773)
- [Win32] Bugfix: `glfwSetClipboardString` created an unnecessary intermediate

View File

@ -112,6 +112,7 @@ typedef struct _GLFWwindowX11
XIC ic;
GLFWbool overrideRedirect;
GLFWbool visuallyMapped;
// Cached position and size used to filter out duplicate events
int width, height;

View File

@ -604,6 +604,7 @@ static GLFWbool createWindow(_GLFWwindow* window,
_glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
_glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);
window->x11.visuallyMapped = GLFW_FALSE; // Assume window isn't mapped yet.
return GLFW_TRUE;
}
@ -1365,6 +1366,29 @@ static void processEvent(XEvent *event)
return;
}
case VisibilityNotify:
{
int visibilityState = event->xvisibility.state;
// Some window managers (mostly non-reparenting
// like dwm, xmonad, ratpoision, openbox, cwm),
// don't set the visibility flag after mapping,
// a pre-condition for e.g. XSetInputFocus()...
// leads to BadMatch error as described in X11.
// Most of these will however notify with event
// VisibilityFullyObscured on visibility unset.
if (visibilityState != VisibilityFullyObscured)
window->x11.visuallyMapped = GLFW_TRUE;
return;
}
case UnmapNotify:
{
// Should be the only case when a window
// becomes completely visually unmapped.
window->x11.visuallyMapped = GLFW_FALSE;
return;
}
case FocusIn:
{
if (window->cursorMode == GLFW_CURSOR_DISABLED)
@ -1925,6 +1949,11 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
else
{
XRaiseWindow(_glfw.x11.display, window->x11.handle);
// Requested window might not have been completely initialized
// by the window manager at this point, need to wait until the
// window has both been mapped and also set a visibility flag.
// Wait for VisibilityNotify X11 event before setting a focus.
while (!window->x11.visuallyMapped) _glfwPlatformWaitEvents();
XSetInputFocus(_glfw.x11.display, window->x11.handle,
RevertToParent, CurrentTime);
}