From: <eli...@us...> - 2008-04-06 21:34:32
|
Revision: 2970 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=2970&view=rev Author: elias_naur Date: 2008-04-06 14:34:22 -0700 (Sun, 06 Apr 2008) Log Message: ----------- Linux: Attempt to avoid race condition when tracking Display parent focus Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java trunk/LWJGL/src/native/linux/org_lwjgl_opengl_Display.c Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java 2008-04-06 20:56:52 UTC (rev 2969) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java 2008-04-06 21:34:22 UTC (rev 2970) @@ -623,8 +623,6 @@ private native static void setInputFocus(long display, long window); private void processEvents() { - if (!focused && parent != null && parent.isFocusOwner()) - setInputFocus(getDisplay(), getWindow()); while (LinuxEvent.getPending(getDisplay()) > 0) { event_buffer.nextEvent(getDisplay()); long event_window = event_buffer.getWindow(); @@ -742,15 +740,30 @@ } private void checkInput() { - focused = nGetInputFocus(getDisplay()) == getWindow(); + long current_focus = nGetInputFocus(getDisplay()); + focused = current_focus == getWindow(); if (focused) { focused_at_least_once = true; acquireInput(); - } else if (focused_at_least_once) { - releaseInput(); + } else { + 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()); + } finally { + ungrabServer(getDisplay()); + } + } } } static native long nGetInputFocus(long display); + private static native void grabServer(long display); + private static native void ungrabServer(long display); private void releaseInput() { if (isLegacyFullscreen() || input_released) Modified: trunk/LWJGL/src/native/linux/org_lwjgl_opengl_Display.c =================================================================== --- trunk/LWJGL/src/native/linux/org_lwjgl_opengl_Display.c 2008-04-06 20:56:52 UTC (rev 2969) +++ trunk/LWJGL/src/native/linux/org_lwjgl_opengl_Display.c 2008-04-06 21:34:22 UTC (rev 2970) @@ -327,14 +327,20 @@ return win; } +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_grabServer(JNIEnv *env, jclass unused, jlong display) { + Display *disp = (Display *)(intptr_t)display; + XGrabServer(disp); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_ungrabServer(JNIEnv *env, jclass unused, jlong display) { + Display *disp = (Display *)(intptr_t)display; + XUngrabServer(disp); +} + JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_setInputFocus(JNIEnv *env, jclass clazz, jlong display, jlong window_ptr) { Display *disp = (Display *)(intptr_t)display; Window window = (Window)window_ptr; - // Normally, a real time stamp from an event should be passed instead of CurrentTime, but we don't get timestamps - // from awt. Instead we grab the server before and ungrab it after the request - XGrabServer(disp); XSetInputFocus(disp, window, RevertToParent, CurrentTime); - XUngrabServer(disp); } JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv *env, jclass clazz, jlong display, jint screen, jobject peer_info_handle, jobject mode, jint window_mode, jint x, jint y, jboolean undecorated, jlong parent_handle) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |