From: <ka...@us...> - 2011-10-30 14:44:59
|
Revision: 3689 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3689&view=rev Author: kappa1 Date: 2011-10-30 14:44:52 +0000 (Sun, 30 Oct 2011) Log Message: ----------- Fix keyboard handling when running Display.setParent() as an application on Linux. Thus allowing WM and system hot-keys to function again when the LWJGL app has focus. Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java trunk/LWJGL/src/native/linux/opengl/org_lwjgl_opengl_Display.c trunk/LWJGL/src/native/linux/opengles/org_lwjgl_opengl_Display.c Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java 2011-10-26 20:24:22 UTC (rev 3688) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java 2011-10-30 14:44:52 UTC (rev 3689) @@ -152,6 +152,7 @@ private static boolean xembedded; private long parent_proxy_focus_window; private boolean parent_focused; + private boolean parent_focus_changed; private long last_window_focus = 0; private LinuxKeyboard keyboard; @@ -161,11 +162,13 @@ public void focusGained(FocusEvent e) { synchronized (GlobalLock.lock) { parent_focused = true; + parent_focus_changed = true; } } public void focusLost(FocusEvent e) { synchronized (GlobalLock.lock) { parent_focused = false; + parent_focus_changed = true; } } }; @@ -489,9 +492,8 @@ if (parent != null) { parent.addFocusListener(focus_listener); - if (parent.isFocusOwner()) { - parent_focused = true; - } + parent_focused = parent.isFocusOwner(); + parent_focus_changed = true; } } finally { peer_info.unlock(); @@ -549,6 +551,9 @@ public void destroyWindow() { lockAWT(); try { + if (parent != null) { + parent.removeFocusListener(focus_listener); + } try { setNativeCursor(null); } catch (LWJGLException e) { @@ -971,20 +976,24 @@ } } else { - if (parent_focused != keyboard_grabbed) { - if (parent_focused) { - grabKeyboard(); - input_released = false; - focused = true; - } - else { - ungrabKeyboard(); - input_released = true; - focused = false; - } + if (parent_focus_changed && parent_focused) { + setInputFocusUnsafe(getWindow()); + parent_focus_changed = false; } } } + + private void setInputFocusUnsafe(long window) { + try { + nSetInputFocus(getDisplay(), window, CurrentTime); + nSync(getDisplay(), false); + } catch (LWJGLException e) { + // Since we don't have any event timings for XSetInputFocus, a race condition might give a BadMatch, which we'll catch and ignore + LWJGLUtil.log("Got exception while trying to focus: " + e); + } + } + + private static native void nSync(long display, boolean throw_away_events) throws LWJGLException; /** * This method will check if the parent window is active when running Modified: trunk/LWJGL/src/native/linux/opengl/org_lwjgl_opengl_Display.c =================================================================== --- trunk/LWJGL/src/native/linux/opengl/org_lwjgl_opengl_Display.c 2011-10-26 20:24:22 UTC (rev 3688) +++ trunk/LWJGL/src/native/linux/opengl/org_lwjgl_opengl_Display.c 2011-10-30 14:44:52 UTC (rev 3689) @@ -138,6 +138,11 @@ return (intptr_t)XSetErrorHandler(handler); } +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSync(JNIEnv *env, jclass unused, jlong display_ptr, jboolean throw_away_events) { + Display *disp = (Display *)(intptr_t)display_ptr; + XSync(disp, throw_away_events ? True : False); +} + JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_sync(JNIEnv *env, jclass unused, jlong display_ptr, jboolean throw_away_events) { Display *disp = (Display *)(intptr_t)display_ptr; XSync(disp, throw_away_events ? True : False); Modified: trunk/LWJGL/src/native/linux/opengles/org_lwjgl_opengl_Display.c =================================================================== --- trunk/LWJGL/src/native/linux/opengles/org_lwjgl_opengl_Display.c 2011-10-26 20:24:22 UTC (rev 3688) +++ trunk/LWJGL/src/native/linux/opengles/org_lwjgl_opengl_Display.c 2011-10-30 14:44:52 UTC (rev 3689) @@ -135,6 +135,11 @@ return (intptr_t)XSetErrorHandler(handler); } +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSync(JNIEnv *env, jclass unused, jlong display_ptr, jboolean throw_away_events) { + Display *disp = (Display *)(intptr_t)display_ptr; + XSync(disp, throw_away_events ? True : False); +} + JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_sync(JNIEnv *env, jclass unused, jlong display_ptr, jboolean throw_away_events) { Display *disp = (Display *)(intptr_t)display_ptr; XSync(disp, throw_away_events ? True : False); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |