7124310: [macosx] "opposite" seems always null in focus events
Reviewed-by: anthony
This commit is contained in:
parent
1aa03d0b50
commit
c0c03f17ce
jdk/src/macosx
classes/sun/lwawt
native/sun/awt
@ -675,8 +675,9 @@ public class LWWindowPeer
|
|||||||
getLWToolkit().getCursorManager().updateCursorLater(this);
|
getLWToolkit().getCursorManager().updateCursorLater(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyActivation(boolean activation) {
|
public void notifyActivation(boolean activation, LWWindowPeer opposite) {
|
||||||
changeFocusedWindow(activation);
|
Window oppositeWindow = (opposite == null)? null : opposite.getTarget();
|
||||||
|
changeFocusedWindow(activation, oppositeWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MouseDown in non-client area
|
// MouseDown in non-client area
|
||||||
@ -1151,6 +1152,9 @@ public class LWWindowPeer
|
|||||||
Window currentActive = KeyboardFocusManager.
|
Window currentActive = KeyboardFocusManager.
|
||||||
getCurrentKeyboardFocusManager().getActiveWindow();
|
getCurrentKeyboardFocusManager().getActiveWindow();
|
||||||
|
|
||||||
|
Window opposite = LWKeyboardFocusManagerPeer.getInstance().
|
||||||
|
getCurrentFocusedWindow();
|
||||||
|
|
||||||
// Make the owner active window.
|
// Make the owner active window.
|
||||||
if (isSimpleWindow()) {
|
if (isSimpleWindow()) {
|
||||||
LWWindowPeer owner = getOwnerFrameDialog(this);
|
LWWindowPeer owner = getOwnerFrameDialog(this);
|
||||||
@ -1177,16 +1181,17 @@ public class LWWindowPeer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DKFM will synthesize all the focus/activation events correctly.
|
// DKFM will synthesize all the focus/activation events correctly.
|
||||||
changeFocusedWindow(true);
|
changeFocusedWindow(true, opposite);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// In case the toplevel is active but not focused, change focus directly,
|
// In case the toplevel is active but not focused, change focus directly,
|
||||||
// as requesting native focus on it will not have effect.
|
// as requesting native focus on it will not have effect.
|
||||||
} else if (getTarget() == currentActive && !getTarget().hasFocus()) {
|
} else if (getTarget() == currentActive && !getTarget().hasFocus()) {
|
||||||
|
|
||||||
changeFocusedWindow(true);
|
changeFocusedWindow(true, opposite);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return platformWindow.requestWindowFocus();
|
return platformWindow.requestWindowFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1216,7 +1221,7 @@ public class LWWindowPeer
|
|||||||
/*
|
/*
|
||||||
* Changes focused window on java level.
|
* Changes focused window on java level.
|
||||||
*/
|
*/
|
||||||
private void changeFocusedWindow(boolean becomesFocused) {
|
private void changeFocusedWindow(boolean becomesFocused, Window opposite) {
|
||||||
if (focusLog.isLoggable(PlatformLogger.FINE)) {
|
if (focusLog.isLoggable(PlatformLogger.FINE)) {
|
||||||
focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this);
|
focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this);
|
||||||
}
|
}
|
||||||
@ -1240,9 +1245,6 @@ public class LWWindowPeer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
|
|
||||||
Window oppositeWindow = becomesFocused ? kfmPeer.getCurrentFocusedWindow() : null;
|
|
||||||
|
|
||||||
// Note, the method is not called:
|
// Note, the method is not called:
|
||||||
// - when the opposite (gaining focus) window is an owned/owner window.
|
// - when the opposite (gaining focus) window is an owned/owner window.
|
||||||
// - for a simple window in any case.
|
// - for a simple window in any case.
|
||||||
@ -1254,10 +1256,11 @@ public class LWWindowPeer
|
|||||||
grabbingWindow.ungrab();
|
grabbingWindow.ungrab();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
|
||||||
kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
|
kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
|
||||||
|
|
||||||
int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
|
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
|
// TODO: wrap in SequencedEvent
|
||||||
postEvent(windowEvent);
|
postEvent(windowEvent);
|
||||||
|
@ -113,14 +113,14 @@ public class CEmbeddedFrame extends EmbeddedFrame {
|
|||||||
public void handleFocusEvent(boolean focused) {
|
public void handleFocusEvent(boolean focused) {
|
||||||
this.focused = focused;
|
this.focused = focused;
|
||||||
if (parentWindowActive) {
|
if (parentWindowActive) {
|
||||||
responder.handleWindowFocusEvent(focused);
|
responder.handleWindowFocusEvent(focused, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleWindowFocusEvent(boolean parentWindowActive) {
|
public void handleWindowFocusEvent(boolean parentWindowActive) {
|
||||||
this.parentWindowActive = parentWindowActive;
|
this.parentWindowActive = parentWindowActive;
|
||||||
if (focused) {
|
if (focused) {
|
||||||
responder.handleWindowFocusEvent(parentWindowActive);
|
responder.handleWindowFocusEvent(parentWindowActive, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ final class CPlatformResponder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleWindowFocusEvent(boolean gained) {
|
void handleWindowFocusEvent(boolean gained, LWWindowPeer opposite) {
|
||||||
peer.notifyActivation(gained);
|
peer.notifyActivation(gained, opposite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -878,13 +878,15 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
|
|||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Callbacks from the AWTWindow and AWTView objc classes.
|
* 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.
|
// Fix for 7150349: ingore "gained" notifications when the app is inactive.
|
||||||
if (gained && !((LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive()) {
|
if (gained && !((LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive()) {
|
||||||
focusLogger.fine("the app is inactive, so the notification is ignored");
|
focusLogger.fine("the app is inactive, so the notification is ignored");
|
||||||
return;
|
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) {
|
private void deliverMoveResizeEvent(int x, int y, int width, int height) {
|
||||||
|
@ -69,6 +69,9 @@
|
|||||||
- (BOOL) worksWhenModal;
|
- (BOOL) worksWhenModal;
|
||||||
- (void)sendEvent:(NSEvent *)event;
|
- (void)sendEvent:(NSEvent *)event;
|
||||||
|
|
||||||
|
+ (void) setLastKeyWindow:(AWTWindow *)window;
|
||||||
|
+ (AWTWindow *) lastKeyWindow;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface AWTWindow_Normal : NSWindow
|
@interface AWTWindow_Normal : NSWindow
|
||||||
|
@ -51,6 +51,14 @@
|
|||||||
|
|
||||||
static JNF_CLASS_CACHE(jc_CPlatformWindow, "sun/lwawt/macosx/CPlatformWindow");
|
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
|
// NSWindow/NSPanel descendants implementation
|
||||||
#define AWT_NS_WINDOW_IMPLEMENTATION \
|
#define AWT_NS_WINDOW_IMPLEMENTATION \
|
||||||
@ -505,15 +513,17 @@ AWT_ASSERT_APPKIT_THREAD;
|
|||||||
[self _deliverIconify:JNI_FALSE];
|
[self _deliverIconify:JNI_FALSE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) _deliverWindowFocusEvent:(BOOL)focused {
|
- (void) _deliverWindowFocusEvent:(BOOL)focused oppositeWindow:(AWTWindow *)opposite {
|
||||||
//AWT_ASSERT_APPKIT_THREAD;
|
//AWT_ASSERT_APPKIT_THREAD;
|
||||||
|
|
||||||
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
|
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
|
||||||
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
|
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
|
||||||
if (platformWindow != NULL) {
|
if (platformWindow != NULL) {
|
||||||
static JNF_MEMBER_CACHE(jm_deliverWindowFocusEvent, jc_CPlatformWindow, "deliverWindowFocusEvent", "(Z)V");
|
jobject oppositeWindow = [opposite.javaPlatformWindow jObjectWithEnv:env];
|
||||||
JNFCallVoidMethod(env, platformWindow, jm_deliverWindowFocusEvent, (jboolean)focused);
|
|
||||||
|
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, platformWindow);
|
||||||
|
(*env)->DeleteLocalRef(env, oppositeWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,7 +532,10 @@ AWT_ASSERT_APPKIT_THREAD;
|
|||||||
AWT_ASSERT_APPKIT_THREAD;
|
AWT_ASSERT_APPKIT_THREAD;
|
||||||
[AWTToolkit eventCountPlusPlus];
|
[AWTToolkit eventCountPlusPlus];
|
||||||
[CMenuBar activate:self.javaMenuBar modallyDisabled:NO];
|
[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 {
|
- (void) windowDidResignKey: (NSNotification *) notification {
|
||||||
@ -530,7 +543,18 @@ AWT_ASSERT_APPKIT_THREAD;
|
|||||||
AWT_ASSERT_APPKIT_THREAD;
|
AWT_ASSERT_APPKIT_THREAD;
|
||||||
[AWTToolkit eventCountPlusPlus];
|
[AWTToolkit eventCountPlusPlus];
|
||||||
[self.javaMenuBar deactivate];
|
[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 {
|
- (void) windowDidBecomeMain: (NSNotification *) notification {
|
||||||
@ -684,6 +708,17 @@ AWT_ASSERT_APPKIT_THREAD;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (void) setLastKeyWindow:(AWTWindow *)window {
|
||||||
|
[window retain];
|
||||||
|
[lastKeyWindow release];
|
||||||
|
lastKeyWindow = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (AWTWindow *) lastKeyWindow {
|
||||||
|
return lastKeyWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@end // AWTWindow
|
@end // AWTWindow
|
||||||
|
|
||||||
|
|
||||||
@ -1208,6 +1243,10 @@ JNF_COCOA_ENTER(env);
|
|||||||
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
|
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
|
||||||
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
|
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
|
||||||
|
|
||||||
|
if ([AWTWindow lastKeyWindow] == window) {
|
||||||
|
[AWTWindow setLastKeyWindow: nil];
|
||||||
|
}
|
||||||
|
|
||||||
// AWTWindow holds a reference to the NSWindow in its nsWindow
|
// AWTWindow holds a reference to the NSWindow in its nsWindow
|
||||||
// property. Unsetting the delegate allows it to be deallocated
|
// property. Unsetting the delegate allows it to be deallocated
|
||||||
// which releases the reference. This, in turn, allows the window
|
// which releases the reference. This, in turn, allows the window
|
||||||
|
Loading…
x
Reference in New Issue
Block a user