--- old/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m 2016-04-28 16:21:44.000000000 +0300 +++ new/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m 2016-04-28 16:21:44.000000000 +0300 @@ -180,6 +180,7 @@ @synthesize ownerWindow; @synthesize preFullScreenLevel; @synthesize standardFrame; +@synthesize isMinimizing; - (void) updateMinMaxSize:(BOOL)resizable { if (resizable) { @@ -304,6 +305,7 @@ [self.nsWindow release]; // the property retains the object already self.isEnabled = YES; + self.isMinimizing = NO; self.javaPlatformWindow = platformWindow; self.styleBits = bits; self.ownerWindow = owner; @@ -423,6 +425,68 @@ [super dealloc]; } +// Tests wheather the corresponding Java paltform window is visible or not ++ (BOOL) isJavaPlatformWindowVisible:(NSWindow *)window { + BOOL isVisible = NO; + + if ([AWTWindow isAWTWindow:window] && [window delegate] != nil) { + AWTWindow *awtWindow = (AWTWindow *)[window delegate]; + [AWTToolkit eventCountPlusPlus]; + + JNIEnv *env = [ThreadUtilities getJNIEnv]; + jobject platformWindow = [awtWindow.javaPlatformWindow jObjectWithEnv:env]; + if (platformWindow != NULL) { + static JNF_MEMBER_CACHE(jm_isVisible, jc_CPlatformWindow, "isVisible", "()Z"); + isVisible = JNFCallBooleanMethod(env, platformWindow, jm_isVisible) == JNI_TRUE ? YES : NO; + (*env)->DeleteLocalRef(env, platformWindow); + + } + } + return isVisible; +} + +// Orders window's childs based on the current focus state +- (void) orderChildWindows:(BOOL)focus { +AWT_ASSERT_APPKIT_THREAD; + + if (self.isMinimizing) { + // Do not perform any ordering, if iconify is in progress + return; + } + + NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator]; + NSWindow *window; + while ((window = [windowEnumerator nextObject]) != nil) { + if ([AWTWindow isJavaPlatformWindowVisible:window]) { + AWTWindow *awtWindow = (AWTWindow *)[window delegate]; + AWTWindow *owner = awtWindow.ownerWindow; + if (IS(awtWindow.styleBits, ALWAYS_ON_TOP)) { + // Do not order 'always on top' windows + continue; + } + while (awtWindow.ownerWindow != nil) { + if (awtWindow.ownerWindow == self) { + if (focus) { + // Move the childWindow to floating level + // so it will appear in front of its + // parent which owns the focus + [window setLevel:NSFloatingWindowLevel]; + } else { + // Focus owner has changed, move the childWindow + // back to normal window level + [window setLevel:NSNormalWindowLevel]; + } + // The childWindow should be displayed in front of + // its nearest parentWindow + [window orderWindow:NSWindowAbove relativeTo:[owner.nsWindow windowNumber]]; + break; + } + awtWindow = awtWindow.ownerWindow; + } + } + } +} + // NSWindow overrides - (BOOL) canBecomeKeyWindow { AWT_ASSERT_APPKIT_THREAD; @@ -511,6 +575,30 @@ return [self standardFrame]; } +// Hides/shows window's childs during iconify/de-iconify operation +- (void) iconifyChildWindows:(BOOL)iconify { +AWT_ASSERT_APPKIT_THREAD; + + NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator]; + NSWindow *window; + while ((window = [windowEnumerator nextObject]) != nil) { + if ([AWTWindow isJavaPlatformWindowVisible:window]) { + AWTWindow *awtWindow = (AWTWindow *)[window delegate]; + while (awtWindow.ownerWindow != nil) { + if (awtWindow.ownerWindow == self) { + if (iconify) { + [window orderOut:window]; + } else { + [window orderFront:window]; + } + break; + } + awtWindow = awtWindow.ownerWindow; + } + } + } +} + - (void) _deliverIconify:(BOOL)iconify { AWT_ASSERT_APPKIT_THREAD; @@ -524,16 +612,28 @@ } } +- (void)windowWillMiniaturize:(NSNotification *)notification { +AWT_ASSERT_APPKIT_THREAD; + + self.isMinimizing = YES; + // Excplicitly make myself a key window to avoid possible + // negative visual effects during iconify operation + [self.nsWindow makeKeyAndOrderFront:self.nsWindow]; + [self iconifyChildWindows:YES]; +} + - (void)windowDidMiniaturize:(NSNotification *)notification { AWT_ASSERT_APPKIT_THREAD; [self _deliverIconify:JNI_TRUE]; + self.isMinimizing = NO; } - (void)windowDidDeminiaturize:(NSNotification *)notification { AWT_ASSERT_APPKIT_THREAD; [self _deliverIconify:JNI_FALSE]; + [self iconifyChildWindows:NO]; } - (void) _deliverWindowFocusEvent:(BOOL)focused oppositeWindow:(AWTWindow *)opposite { @@ -579,6 +679,7 @@ [AWTWindow setLastKeyWindow:nil]; [self _deliverWindowFocusEvent:YES oppositeWindow: opposite]; + [self orderChildWindows:YES]; } - (void) windowDidResignKey: (NSNotification *) notification { @@ -606,6 +707,7 @@ } [self _deliverWindowFocusEvent:NO oppositeWindow: opposite]; + [self orderChildWindows:NO]; } - (void) windowDidBecomeMain: (NSNotification *) notification {