mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 04:24:49 +02:00
7177173: [macosx] JFrame.setExtendedState(JFrame.MAXIMIZED_BOTH) not working as expected in JDK 7
Avoid unnecessary changes to the extended state Reviewed-by: art, serb
This commit is contained in:
parent
e3a1dad2c0
commit
d91b2b6f6e
2 changed files with 122 additions and 45 deletions
|
@ -209,6 +209,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||||
private boolean undecorated; // initialized in getInitialStyleBits()
|
private boolean undecorated; // initialized in getInitialStyleBits()
|
||||||
private Rectangle normalBounds = null; // not-null only for undecorated maximized windows
|
private Rectangle normalBounds = null; // not-null only for undecorated maximized windows
|
||||||
private CPlatformResponder responder;
|
private CPlatformResponder responder;
|
||||||
|
private volatile boolean zoomed = false; // from native perspective
|
||||||
|
|
||||||
public CPlatformWindow(final PeerType peerType) {
|
public CPlatformWindow(final PeerType peerType) {
|
||||||
super(0, true);
|
super(0, true);
|
||||||
|
@ -469,26 +470,42 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||||
nativeSetNSWindowBounds(getNSWindowPtr(), x, y, w, h);
|
nativeSetNSWindowBounds(getNSWindowPtr(), x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void zoom() {
|
private boolean isMaximized() {
|
||||||
|
return undecorated ? this.normalBounds != null : zoomed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void maximize() {
|
||||||
|
if (isMaximized()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!undecorated) {
|
if (!undecorated) {
|
||||||
|
zoomed = true;
|
||||||
CWrapper.NSWindow.zoom(getNSWindowPtr());
|
CWrapper.NSWindow.zoom(getNSWindowPtr());
|
||||||
} else {
|
} else {
|
||||||
// OS X handles -zoom incorrectly for undecorated windows
|
deliverZoom(true);
|
||||||
final boolean isZoomed = this.normalBounds == null;
|
|
||||||
deliverZoom(isZoomed);
|
|
||||||
|
|
||||||
Rectangle toBounds;
|
|
||||||
if (isZoomed) {
|
|
||||||
this.normalBounds = peer.getBounds();
|
this.normalBounds = peer.getBounds();
|
||||||
long screen = CWrapper.NSWindow.screen(getNSWindowPtr());
|
long screen = CWrapper.NSWindow.screen(getNSWindowPtr());
|
||||||
toBounds = CWrapper.NSScreen.visibleFrame(screen).getBounds();
|
Rectangle toBounds = CWrapper.NSScreen.visibleFrame(screen).getBounds();
|
||||||
// Flip the y coordinate
|
// Flip the y coordinate
|
||||||
Rectangle frame = CWrapper.NSScreen.frame(screen).getBounds();
|
Rectangle frame = CWrapper.NSScreen.frame(screen).getBounds();
|
||||||
toBounds.y = frame.height - toBounds.y - toBounds.height;
|
toBounds.y = frame.height - toBounds.y - toBounds.height;
|
||||||
} else {
|
setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height);
|
||||||
toBounds = normalBounds;
|
|
||||||
this.normalBounds = null;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unmaximize() {
|
||||||
|
if (!isMaximized()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!undecorated) {
|
||||||
|
zoomed = false;
|
||||||
|
CWrapper.NSWindow.zoom(getNSWindowPtr());
|
||||||
|
} else {
|
||||||
|
deliverZoom(false);
|
||||||
|
|
||||||
|
Rectangle toBounds = this.normalBounds;
|
||||||
|
this.normalBounds = null;
|
||||||
setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height);
|
setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,9 +518,9 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||||
public void setVisible(boolean visible) {
|
public void setVisible(boolean visible) {
|
||||||
final long nsWindowPtr = getNSWindowPtr();
|
final long nsWindowPtr = getNSWindowPtr();
|
||||||
|
|
||||||
// 1. Process parent-child relationship when hiding
|
// Process parent-child relationship when hiding
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
// 1a. Unparent my children
|
// Unparent my children
|
||||||
for (Window w : target.getOwnedWindows()) {
|
for (Window w : target.getOwnedWindows()) {
|
||||||
WindowPeer p = (WindowPeer)w.getPeer();
|
WindowPeer p = (WindowPeer)w.getPeer();
|
||||||
if (p instanceof LWWindowPeer) {
|
if (p instanceof LWWindowPeer) {
|
||||||
|
@ -514,30 +531,17 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1b. Unparent myself
|
// Unparent myself
|
||||||
if (owner != null && owner.isVisible()) {
|
if (owner != null && owner.isVisible()) {
|
||||||
CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), nsWindowPtr);
|
CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), nsWindowPtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Configure stuff
|
// Configure stuff
|
||||||
updateIconImages();
|
updateIconImages();
|
||||||
updateFocusabilityForAutoRequestFocus(false);
|
updateFocusabilityForAutoRequestFocus(false);
|
||||||
|
|
||||||
// 3. Manage the extended state when hiding
|
// Actually show or hide the window
|
||||||
if (!visible) {
|
|
||||||
// Cancel out the current native state of the window
|
|
||||||
switch (peer.getState()) {
|
|
||||||
case Frame.ICONIFIED:
|
|
||||||
CWrapper.NSWindow.deminiaturize(nsWindowPtr);
|
|
||||||
break;
|
|
||||||
case Frame.MAXIMIZED_BOTH:
|
|
||||||
zoom();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Actually show or hide the window
|
|
||||||
LWWindowPeer blocker = peer.getBlocker();
|
LWWindowPeer blocker = peer.getBlocker();
|
||||||
if (blocker == null || !visible) {
|
if (blocker == null || !visible) {
|
||||||
// If it ain't blocked, or is being hidden, go regular way
|
// If it ain't blocked, or is being hidden, go regular way
|
||||||
|
@ -566,16 +570,19 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||||
}
|
}
|
||||||
this.visible = visible;
|
this.visible = visible;
|
||||||
|
|
||||||
// 5. Manage the extended state when showing
|
// Manage the extended state when showing
|
||||||
if (visible) {
|
if (visible) {
|
||||||
// Re-apply the extended state as expected in shared code
|
// Apply the extended state as expected in shared code
|
||||||
if (target instanceof Frame) {
|
if (target instanceof Frame) {
|
||||||
switch (((Frame)target).getExtendedState()) {
|
switch (((Frame)target).getExtendedState()) {
|
||||||
case Frame.ICONIFIED:
|
case Frame.ICONIFIED:
|
||||||
CWrapper.NSWindow.miniaturize(nsWindowPtr);
|
CWrapper.NSWindow.miniaturize(nsWindowPtr);
|
||||||
break;
|
break;
|
||||||
case Frame.MAXIMIZED_BOTH:
|
case Frame.MAXIMIZED_BOTH:
|
||||||
zoom();
|
maximize();
|
||||||
|
break;
|
||||||
|
default: // NORMAL
|
||||||
|
unmaximize(); // in case it was maximized, otherwise this is a no-op
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -583,12 +590,12 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||||
|
|
||||||
nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
|
nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
|
||||||
|
|
||||||
// 6. Configure stuff #2
|
// Configure stuff #2
|
||||||
updateFocusabilityForAutoRequestFocus(true);
|
updateFocusabilityForAutoRequestFocus(true);
|
||||||
|
|
||||||
// 7. Manage parent-child relationship when showing
|
// Manage parent-child relationship when showing
|
||||||
if (visible) {
|
if (visible) {
|
||||||
// 7a. Add myself as a child
|
// Add myself as a child
|
||||||
if (owner != null && owner.isVisible()) {
|
if (owner != null && owner.isVisible()) {
|
||||||
CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), nsWindowPtr, CWrapper.NSWindow.NSWindowAbove);
|
CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), nsWindowPtr, CWrapper.NSWindow.NSWindowAbove);
|
||||||
if (target.isAlwaysOnTop()) {
|
if (target.isAlwaysOnTop()) {
|
||||||
|
@ -596,7 +603,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7b. Add my own children to myself
|
// Add my own children to myself
|
||||||
for (Window w : target.getOwnedWindows()) {
|
for (Window w : target.getOwnedWindows()) {
|
||||||
WindowPeer p = (WindowPeer)w.getPeer();
|
WindowPeer p = (WindowPeer)w.getPeer();
|
||||||
if (p instanceof LWWindowPeer) {
|
if (p instanceof LWWindowPeer) {
|
||||||
|
@ -611,7 +618,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. Deal with the blocker of the window being shown
|
// Deal with the blocker of the window being shown
|
||||||
if (blocker != null && visible) {
|
if (blocker != null && visible) {
|
||||||
// Make sure the blocker is above its siblings
|
// Make sure the blocker is above its siblings
|
||||||
((CPlatformWindow)blocker.getPlatformWindow()).orderAboveSiblings();
|
((CPlatformWindow)blocker.getPlatformWindow()).orderAboveSiblings();
|
||||||
|
@ -778,7 +785,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||||
if (prevWindowState == Frame.MAXIMIZED_BOTH) {
|
if (prevWindowState == Frame.MAXIMIZED_BOTH) {
|
||||||
// let's return into the normal states first
|
// let's return into the normal states first
|
||||||
// the zoom call toggles between the normal and the max states
|
// the zoom call toggles between the normal and the max states
|
||||||
zoom();
|
unmaximize();
|
||||||
}
|
}
|
||||||
CWrapper.NSWindow.miniaturize(nsWindowPtr);
|
CWrapper.NSWindow.miniaturize(nsWindowPtr);
|
||||||
break;
|
break;
|
||||||
|
@ -787,14 +794,14 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||||
// let's return into the normal states first
|
// let's return into the normal states first
|
||||||
CWrapper.NSWindow.deminiaturize(nsWindowPtr);
|
CWrapper.NSWindow.deminiaturize(nsWindowPtr);
|
||||||
}
|
}
|
||||||
zoom();
|
maximize();
|
||||||
break;
|
break;
|
||||||
case Frame.NORMAL:
|
case Frame.NORMAL:
|
||||||
if (prevWindowState == Frame.ICONIFIED) {
|
if (prevWindowState == Frame.ICONIFIED) {
|
||||||
CWrapper.NSWindow.deminiaturize(nsWindowPtr);
|
CWrapper.NSWindow.deminiaturize(nsWindowPtr);
|
||||||
} else if (prevWindowState == Frame.MAXIMIZED_BOTH) {
|
} else if (prevWindowState == Frame.MAXIMIZED_BOTH) {
|
||||||
// the zoom call toggles between the normal and the max states
|
// the zoom call toggles between the normal and the max states
|
||||||
zoom();
|
unmaximize();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
70
jdk/test/java/awt/Frame/HideMaximized/HideMaximized.java
Normal file
70
jdk/test/java/awt/Frame/HideMaximized/HideMaximized.java
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, 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 7177173
|
||||||
|
@summary The maximized state shouldn't be reset upon hiding a frame
|
||||||
|
@author anthony.petrov@oracle.com: area=awt.toplevel
|
||||||
|
@run main HideMaximized
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
public class HideMaximized {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) {
|
||||||
|
// Nothing to test
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First test a decorated frame
|
||||||
|
Frame frame = new Frame("test");
|
||||||
|
test(frame);
|
||||||
|
|
||||||
|
// Now test an undecorated frames
|
||||||
|
frame = new Frame("undecorated test");
|
||||||
|
frame.setUndecorated(true);
|
||||||
|
test(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void test(Frame frame) {
|
||||||
|
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
try { Thread.sleep(1000); } catch (Exception ex) {}
|
||||||
|
|
||||||
|
if (frame.getExtendedState() != Frame.MAXIMIZED_BOTH) {
|
||||||
|
throw new RuntimeException("The maximized state has not been applied");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will hide the frame, and also clean things up for safe exiting
|
||||||
|
frame.dispose();
|
||||||
|
|
||||||
|
try { Thread.sleep(1000); } catch (Exception ex) {}
|
||||||
|
|
||||||
|
if (frame.getExtendedState() != Frame.MAXIMIZED_BOTH) {
|
||||||
|
throw new RuntimeException("The maximized state has been reset");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue