diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index f9003dad..1bbc211b 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -752,15 +752,7 @@ final class LinuxDisplay implements DisplayImplementation { if (focused_at_least_once) releaseInput(); if (parent != null && parent.isFocusOwner()) { - // Normally, a real time stamp from an event should be passed to XSetInputFocus instead of CurrentTime, but we don't get timestamps - // from awt. Instead we grab the server and check if the focus changed to avoid a race where our window is made unviewable while focusing it. - grabServer(getDisplay()); - try { - if (nGetInputFocus(getDisplay()) == current_focus) - setInputFocus(getDisplay(), getWindow(), CurrentTime); - } finally { - ungrabServer(getDisplay()); - } + setInputFocusUnsafe(); } } } @@ -768,6 +760,17 @@ final class LinuxDisplay implements DisplayImplementation { private static native void grabServer(long display); private static native void ungrabServer(long display); + private static void setInputFocusUnsafe() { + setInputFocus(getDisplay(), getWindow(), CurrentTime); + try { + checkXError(getDisplay()); + } catch (LWJGLException e) { + // Since we don't have any event timings for XSetInputFocus, a race condition might give a BadMatch, which we'll catch ang ignore + LWJGLUtil.log("Got exception while trying to focus: " + e); + } + } + private static native void checkXError(long display) throws LWJGLException; + private void releaseInput() { if (isLegacyFullscreen() || input_released) return; diff --git a/src/native/linux/org_lwjgl_opengl_Display.c b/src/native/linux/org_lwjgl_opengl_Display.c index 254bf596..32e4457a 100644 --- a/src/native/linux/org_lwjgl_opengl_Display.c +++ b/src/native/linux/org_lwjgl_opengl_Display.c @@ -79,7 +79,7 @@ static Visual *current_visual; static bool async_x_error; static char error_message[ERR_MSG_SIZE]; -bool checkXError(JNIEnv *env, Display *disp) { +static bool checkXError(JNIEnv *env, Display *disp) { XSync(disp, False); if (async_x_error) { async_x_error = false; @@ -113,6 +113,12 @@ static jlong openDisplay(JNIEnv *env) { return (intptr_t)display_connection; } +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_checkXError(JNIEnv *env, jclass unused, jlong display_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + XSync(disp, False); + checkXError(env, disp); +} + JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetDefaultScreen(JNIEnv *env, jclass unused, jlong display_ptr) { Display *disp = (Display *)(intptr_t)display_ptr; return XDefaultScreen(disp);