7124310: [macosx] "opposite" seems always null in focus events
Reviewed-by: anthony
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Fri Nov 02 16:14:14 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Fri Nov 02 19:20:03 2012 +0400
@@ -675,8 +675,9 @@
getLWToolkit().getCursorManager().updateCursorLater(this);
}
- public void notifyActivation(boolean activation) {
- changeFocusedWindow(activation);
+ public void notifyActivation(boolean activation, LWWindowPeer opposite) {
+ Window oppositeWindow = (opposite == null)? null : opposite.getTarget();
+ changeFocusedWindow(activation, oppositeWindow);
}
// MouseDown in non-client area
@@ -1151,6 +1152,9 @@
Window currentActive = KeyboardFocusManager.
getCurrentKeyboardFocusManager().getActiveWindow();
+ Window opposite = LWKeyboardFocusManagerPeer.getInstance().
+ getCurrentFocusedWindow();
+
// Make the owner active window.
if (isSimpleWindow()) {
LWWindowPeer owner = getOwnerFrameDialog(this);
@@ -1177,16 +1181,17 @@
}
// DKFM will synthesize all the focus/activation events correctly.
- changeFocusedWindow(true);
+ changeFocusedWindow(true, opposite);
return true;
// In case the toplevel is active but not focused, change focus directly,
// as requesting native focus on it will not have effect.
} else if (getTarget() == currentActive && !getTarget().hasFocus()) {
- changeFocusedWindow(true);
+ changeFocusedWindow(true, opposite);
return true;
}
+
return platformWindow.requestWindowFocus();
}
@@ -1216,7 +1221,7 @@
/*
* Changes focused window on java level.
*/
- private void changeFocusedWindow(boolean becomesFocused) {
+ private void changeFocusedWindow(boolean becomesFocused, Window opposite) {
if (focusLog.isLoggable(PlatformLogger.FINE)) {
focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this);
}
@@ -1240,9 +1245,6 @@
}
}
- KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
- Window oppositeWindow = becomesFocused ? kfmPeer.getCurrentFocusedWindow() : null;
-
// Note, the method is not called:
// - when the opposite (gaining focus) window is an owned/owner window.
// - for a simple window in any case.
@@ -1254,10 +1256,11 @@
grabbingWindow.ungrab();
}
+ KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
- WindowEvent windowEvent = new TimedWindowEvent(getTarget(), eventID, oppositeWindow, System.currentTimeMillis());
+ WindowEvent windowEvent = new TimedWindowEvent(getTarget(), eventID, opposite, System.currentTimeMillis());
// TODO: wrap in SequencedEvent
postEvent(windowEvent);
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java Fri Nov 02 16:14:14 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java Fri Nov 02 19:20:03 2012 +0400
@@ -113,14 +113,14 @@
public void handleFocusEvent(boolean focused) {
this.focused = focused;
if (parentWindowActive) {
- responder.handleWindowFocusEvent(focused);
+ responder.handleWindowFocusEvent(focused, null);
}
}
public void handleWindowFocusEvent(boolean parentWindowActive) {
this.parentWindowActive = parentWindowActive;
if (focused) {
- responder.handleWindowFocusEvent(parentWindowActive);
+ responder.handleWindowFocusEvent(parentWindowActive, null);
}
}
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java Fri Nov 02 16:14:14 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java Fri Nov 02 19:20:03 2012 +0400
@@ -218,7 +218,7 @@
}
}
- void handleWindowFocusEvent(boolean gained) {
- peer.notifyActivation(gained);
+ void handleWindowFocusEvent(boolean gained, LWWindowPeer opposite) {
+ peer.notifyActivation(gained, opposite);
}
}
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Nov 02 16:14:14 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Nov 02 19:20:03 2012 +0400
@@ -878,13 +878,15 @@
/*************************************************************
* Callbacks from the AWTWindow and AWTView objc classes.
*************************************************************/
- private void deliverWindowFocusEvent(boolean gained){
+ private void deliverWindowFocusEvent(boolean gained, CPlatformWindow opposite){
// Fix for 7150349: ingore "gained" notifications when the app is inactive.
if (gained && !((LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive()) {
focusLogger.fine("the app is inactive, so the notification is ignored");
return;
}
- responder.handleWindowFocusEvent(gained);
+
+ LWWindowPeer oppositePeer = (opposite == null)? null : opposite.getPeer();
+ responder.handleWindowFocusEvent(gained, oppositePeer);
}
private void deliverMoveResizeEvent(int x, int y, int width, int height) {
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.h Fri Nov 02 16:14:14 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.h Fri Nov 02 19:20:03 2012 +0400
@@ -69,6 +69,9 @@
- (BOOL) worksWhenModal;
- (void)sendEvent:(NSEvent *)event;
++ (void) setLastKeyWindow:(AWTWindow *)window;
++ (AWTWindow *) lastKeyWindow;
+
@end
@interface AWTWindow_Normal : NSWindow
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m Fri Nov 02 16:14:14 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m Fri Nov 02 19:20:03 2012 +0400
@@ -51,6 +51,14 @@
static JNF_CLASS_CACHE(jc_CPlatformWindow, "sun/lwawt/macosx/CPlatformWindow");
+// Cocoa windowDidBecomeKey/windowDidResignKey notifications
+// doesn't provide information about "opposite" window, so we
+// have to do a bit of tracking. This variable points to a window
+// which had been the key window just before a new key window
+// was set. It would be nil if the new key window isn't an AWT
+// window or the app currently has no key window.
+static AWTWindow* lastKeyWindow = nil;
+
// --------------------------------------------------------------
// NSWindow/NSPanel descendants implementation
#define AWT_NS_WINDOW_IMPLEMENTATION \
@@ -505,15 +513,17 @@
[self _deliverIconify:JNI_FALSE];
}
-- (void) _deliverWindowFocusEvent:(BOOL)focused {
+- (void) _deliverWindowFocusEvent:(BOOL)focused oppositeWindow:(AWTWindow *)opposite {
//AWT_ASSERT_APPKIT_THREAD;
-
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
if (platformWindow != NULL) {
- static JNF_MEMBER_CACHE(jm_deliverWindowFocusEvent, jc_CPlatformWindow, "deliverWindowFocusEvent", "(Z)V");
- JNFCallVoidMethod(env, platformWindow, jm_deliverWindowFocusEvent, (jboolean)focused);
+ jobject oppositeWindow = [opposite.javaPlatformWindow jObjectWithEnv:env];
+
+ static JNF_MEMBER_CACHE(jm_deliverWindowFocusEvent, jc_CPlatformWindow, "deliverWindowFocusEvent", "(ZLsun/lwawt/macosx/CPlatformWindow;)V");
+ JNFCallVoidMethod(env, platformWindow, jm_deliverWindowFocusEvent, (jboolean)focused, oppositeWindow);
(*env)->DeleteLocalRef(env, platformWindow);
+ (*env)->DeleteLocalRef(env, oppositeWindow);
}
}
@@ -522,7 +532,10 @@
AWT_ASSERT_APPKIT_THREAD;
[AWTToolkit eventCountPlusPlus];
[CMenuBar activate:self.javaMenuBar modallyDisabled:NO];
- [self _deliverWindowFocusEvent:YES];
+ AWTWindow *opposite = [AWTWindow lastKeyWindow];
+ [AWTWindow setLastKeyWindow:nil];
+
+ [self _deliverWindowFocusEvent:YES oppositeWindow: opposite];
}
- (void) windowDidResignKey: (NSNotification *) notification {
@@ -530,7 +543,18 @@
AWT_ASSERT_APPKIT_THREAD;
[AWTToolkit eventCountPlusPlus];
[self.javaMenuBar deactivate];
- [self _deliverWindowFocusEvent:NO];
+
+ // the new key window
+ NSWindow *keyWindow = [NSApp keyWindow];
+ AWTWindow *opposite = nil;
+ if ([AWTWindow isAWTWindow: keyWindow]) {
+ opposite = (AWTWindow *)[keyWindow delegate];
+ [AWTWindow setLastKeyWindow: self];
+ } else {
+ [AWTWindow setLastKeyWindow: nil];
+ }
+
+ [self _deliverWindowFocusEvent:NO oppositeWindow: opposite];
}
- (void) windowDidBecomeMain: (NSNotification *) notification {
@@ -684,6 +708,17 @@
}
}
++ (void) setLastKeyWindow:(AWTWindow *)window {
+ [window retain];
+ [lastKeyWindow release];
+ lastKeyWindow = window;
+}
+
++ (AWTWindow *) lastKeyWindow {
+ return lastKeyWindow;
+}
+
+
@end // AWTWindow
@@ -1208,6 +1243,10 @@
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
+ if ([AWTWindow lastKeyWindow] == window) {
+ [AWTWindow setLastKeyWindow: nil];
+ }
+
// AWTWindow holds a reference to the NSWindow in its nsWindow
// property. Unsetting the delegate allows it to be deallocated
// which releases the reference. This, in turn, allows the window