From 9a895b1dba537ec6740211a166d41f7ecaee822c Mon Sep 17 00:00:00 2001 From: Ioannis Tsakpinis Date: Thu, 18 Apr 2013 17:02:48 +0300 Subject: [PATCH] Attempt to fix focus transfer issue between Display and AWT components in JDK 7: - Instead of grabbing focus directly to our window, we call requestFocus on the Canvas component. This will clear focus from any other AWT component. - When the parent Canvas gets focus, we detect it in update and that's when we grab focus to our window. We can't use a listener, setFocus must be called in our thread. - Alt-tabbing out/in also works because focus goes to the Canvas. The above check will trigger again and our window will be refocused. --- src/java/org/lwjgl/opengl/WindowsDisplay.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/java/org/lwjgl/opengl/WindowsDisplay.java b/src/java/org/lwjgl/opengl/WindowsDisplay.java index 684ba3a2..f4dc93b8 100644 --- a/src/java/org/lwjgl/opengl/WindowsDisplay.java +++ b/src/java/org/lwjgl/opengl/WindowsDisplay.java @@ -256,7 +256,7 @@ final class WindowsDisplay implements DisplayImplementation { } setForegroundWindow(getHwnd()); } - setFocus(getHwnd()); + grabFocus(); } catch (LWJGLException e) { nReleaseDC(hwnd, hdc); nDestroyWindow(hwnd); @@ -373,6 +373,17 @@ final class WindowsDisplay implements DisplayImplementation { private static native void setForegroundWindow(long hwnd); private static native void setFocus(long hwnd); + private void grabFocus() { + if ( parent == null ) + setFocus(getHwnd()); + else + SwingUtilities.invokeLater(new Runnable() { + public void run() { + parent.requestFocus(); + } + }); + } + private void restoreDisplayMode() { try { doSetGammaRamp(current_gamma); @@ -510,9 +521,10 @@ final class WindowsDisplay implements DisplayImplementation { public void update() { nUpdate(); - // This happens when we alt-tab to the frame that contains the parent. The WM_ACTIVATE event is received by AWT instead of our window proc. - if ( !isFocused && parent != null && SwingUtilities.isDescendingFrom(parent, KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()) ) + if ( !isFocused && parent != null && parent.isFocusOwner() ) { + KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); setFocus(getHwnd()); + } if (redoMakeContextCurrent) { redoMakeContextCurrent = false; @@ -935,7 +947,7 @@ final class WindowsDisplay implements DisplayImplementation { return 0L; case WM_MOUSEACTIVATE: if ( !isFocused ) - setFocus(getHwnd()); + grabFocus(); return 3L; // MA_NOACTIVATE case WM_MOUSEMOVE: