提交 49a2a602 编写于 作者: D dmarkov

8080729: [macosx] java 7 and 8 JDialogs on multiscreen jump to parent frame on focus

Reviewed-by: ant, denis
上级 7c7adb0a
......@@ -427,9 +427,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
@Override // PlatformWindow
public void dispose() {
if (owner != null) {
CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), getNSWindowPtr());
}
contentView.dispose();
nativeDispose(getNSWindowPtr());
CPlatformWindow.super.dispose();
......@@ -526,25 +523,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
public void setVisible(boolean visible) {
final long nsWindowPtr = getNSWindowPtr();
// Process parent-child relationship when hiding
if (!visible) {
// Unparent my children
for (Window w : target.getOwnedWindows()) {
WindowPeer p = (WindowPeer)w.getPeer();
if (p instanceof LWWindowPeer) {
CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
if (pw != null && pw.isVisible()) {
CWrapper.NSWindow.removeChildWindow(nsWindowPtr, pw.getNSWindowPtr());
}
}
}
// Unparent myself
if (owner != null && owner.isVisible()) {
CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), nsWindowPtr);
}
}
// Configure stuff
updateIconImages();
updateFocusabilityForAutoRequestFocus(false);
......@@ -618,19 +596,19 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
// Manage parent-child relationship when showing
if (visible) {
// Add myself as a child
// Order myself above my parent
if (owner != null && owner.isVisible()) {
CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), nsWindowPtr, CWrapper.NSWindow.NSWindowAbove);
CWrapper.NSWindow.orderWindow(nsWindowPtr, CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr());
applyWindowLevel(target);
}
// Add my own children to myself
// Order my own children above myself
for (Window w : target.getOwnedWindows()) {
WindowPeer p = (WindowPeer)w.getPeer();
if (p instanceof LWWindowPeer) {
CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
if (pw != null && pw.isVisible()) {
CWrapper.NSWindow.addChildWindow(nsWindowPtr, pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove);
CWrapper.NSWindow.orderWindow(pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove, nsWindowPtr);
pw.applyWindowLevel(w);
}
}
......@@ -1059,8 +1037,8 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
// Order the window to front of the stack of child windows
final long nsWindowSelfPtr = getNSWindowPtr();
final long nsWindowOwnerPtr = owner.getNSWindowPtr();
CWrapper.NSWindow.removeChildWindow(nsWindowOwnerPtr, nsWindowSelfPtr);
CWrapper.NSWindow.addChildWindow(nsWindowOwnerPtr, nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove);
CWrapper.NSWindow.orderFront(nsWindowOwnerPtr);
CWrapper.NSWindow.orderWindow(nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove, nsWindowOwnerPtr);
}
applyWindowLevel(target);
......
......@@ -221,15 +221,6 @@ public final class CWarningWindow extends CPlatformWindow
synchronized (lock) {
final long nsWindowPtr = getNSWindowPtr();
// Process parent-child relationship when hiding
if (!visible) {
// Unparent myself
if (owner != null && owner.isVisible()) {
CWrapper.NSWindow.removeChildWindow(
owner.getNSWindowPtr(), nsWindowPtr);
}
}
// Actually show or hide the window
if (visible) {
CWrapper.NSWindow.orderFront(nsWindowPtr);
......@@ -241,10 +232,10 @@ public final class CWarningWindow extends CPlatformWindow
// Manage parent-child relationship when showing
if (visible) {
// Add myself as a child
// Order myself above my parent
if (owner != null && owner.isVisible()) {
CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(),
nsWindowPtr, CWrapper.NSWindow.NSWindowAbove);
CWrapper.NSWindow.orderWindow(nsWindowPtr,
CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr());
// do not allow security warning to be obscured by other windows
applyWindowLevel(ownerWindow);
......
......@@ -46,6 +46,7 @@
NSWindow *nsWindow;
AWTWindow *ownerWindow;
jint preFullScreenLevel;
BOOL isMinimizing;
}
// An instance of either AWTWindow_Normal or AWTWindow_Panel
......@@ -59,6 +60,7 @@
@property (nonatomic) jint styleBits;
@property (nonatomic) BOOL isEnabled;
@property (nonatomic) jint preFullScreenLevel;
@property (nonatomic) BOOL isMinimizing;
- (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)javaPlatformWindow
......
......@@ -184,6 +184,7 @@ AWT_NS_WINDOW_IMPLEMENTATION
@synthesize isEnabled;
@synthesize ownerWindow;
@synthesize preFullScreenLevel;
@synthesize isMinimizing;
- (void) updateMinMaxSize:(BOOL)resizable {
if (resizable) {
......@@ -308,6 +309,7 @@ AWT_ASSERT_APPKIT_THREAD;
[self.nsWindow release]; // the property retains the object already
self.isEnabled = YES;
self.isMinimizing = NO;
self.javaPlatformWindow = platformWindow;
self.styleBits = bits;
self.ownerWindow = owner;
......@@ -427,6 +429,68 @@ AWT_ASSERT_APPKIT_THREAD;
[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;
......@@ -509,6 +573,30 @@ AWT_ASSERT_APPKIT_THREAD;
// window exposing in _setVisible:(BOOL)
}
// 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;
......@@ -522,16 +610,28 @@ AWT_ASSERT_APPKIT_THREAD;
}
}
- (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 {
......@@ -577,6 +677,7 @@ AWT_ASSERT_APPKIT_THREAD;
[AWTWindow setLastKeyWindow:nil];
[self _deliverWindowFocusEvent:YES oppositeWindow: opposite];
[self orderChildWindows:YES];
}
- (void) windowDidResignKey: (NSNotification *) notification {
......@@ -604,6 +705,7 @@ AWT_ASSERT_APPKIT_THREAD;
}
[self _deliverWindowFocusEvent:NO oppositeWindow: opposite];
[self orderChildWindows:NO];
}
- (void) windowDidBecomeMain: (NSNotification *) notification {
......
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8080729
* @summary Dialogs on multiscreen jump to parent frame on focus gain
* @author Dmitry Markov
* @library ../../regtesthelpers
* @build Util
* @run main WindowJumpingTest
*/
import java.awt.*;
import test.java.awt.regtesthelpers.Util;
public class WindowJumpingTest {
public static void main(String[] args) throws AWTException {
Robot r = Util.createRobot();
GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] graphicsDevices = graphicsEnvironment.getScreenDevices();
if (graphicsDevices.length < 2) {
System.out.println("This is multi-screen test... Skipping!");
return;
}
Frame frame = new Frame("Frame", graphicsDevices[0].getDefaultConfiguration());
frame.setSize(400, 300);
frame.setVisible(true);
Util.waitForIdle(r);
Dialog dialog = new Dialog(frame, "Dialog", false, graphicsDevices[1].getDefaultConfiguration());
dialog.setSize(400, 300);
dialog.setVisible(true);
Util.waitForIdle(r);
checkGraphicsDevice(frame, graphicsDevices[0]);
checkGraphicsDevice(dialog, graphicsDevices[1]);
Util.clickOnComp(frame, r);
Util.waitForIdle(r);
checkGraphicsDevice(frame, graphicsDevices[0]);
checkGraphicsDevice(dialog, graphicsDevices[1]);
Util.clickOnComp(dialog, r);
Util.waitForIdle(r);
checkGraphicsDevice(frame, graphicsDevices[0]);
checkGraphicsDevice(dialog, graphicsDevices[1]);
dialog.dispose();
frame.dispose();
}
private static void checkGraphicsDevice(Window window, GraphicsDevice graphicsDevice) {
GraphicsDevice actualGraphicsDevice = window.getGraphicsConfiguration().getDevice();
if (!actualGraphicsDevice.equals(graphicsDevice)) {
System.err.println("Expected screen: " + graphicsDevice);
System.err.println("Actual screen: "+ actualGraphicsDevice);
throw new RuntimeException("Test FAILED: " + window + " is displayed on wrong screen");
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册