7124428: [macosx] Frame.setExtendedState() doesn't work for undecorated windows
Summary: Emulate native NSWindow -zoom for undecorated windows
Reviewed-by: art
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Thu Mar 29 17:31:48 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Mar 30 18:10:05 2012 +0400
@@ -202,6 +202,8 @@
private LWWindowPeer peer;
private CPlatformView contentView;
private CPlatformWindow owner;
+ private boolean undecorated; // initialized in getInitialStyleBits()
+ private Rectangle normalBounds = null; // not-null only for undecorated maximized windows
public CPlatformWindow(final PeerType peerType) {
super(0, true);
@@ -277,8 +279,8 @@
// Either java.awt.Frame or java.awt.Dialog can be undecorated, however java.awt.Window always is undecorated.
{
- final boolean undecorated = isFrame ? ((Frame)target).isUndecorated() : (isDialog ? ((Dialog)target).isUndecorated() : true);
- if (undecorated) styleBits = SET(styleBits, DECORATED, false);
+ this.undecorated = isFrame ? ((Frame)target).isUndecorated() : (isDialog ? ((Dialog)target).isUndecorated() : true);
+ if (this.undecorated) styleBits = SET(styleBits, DECORATED, false);
}
// Either java.awt.Frame or java.awt.Dialog can be resizable, however java.awt.Window is never resizable
@@ -466,6 +468,30 @@
nativeSetNSWindowBounds(getNSWindowPtr(), x, y, w, h);
}
+ private void zoom() {
+ if (!undecorated) {
+ CWrapper.NSWindow.zoom(getNSWindowPtr());
+ } else {
+ // OS X handles -zoom incorrectly for undecorated windows
+ final boolean isZoomed = this.normalBounds == null;
+ deliverZoom(isZoomed);
+
+ Rectangle toBounds;
+ if (isZoomed) {
+ this.normalBounds = peer.getBounds();
+ long screen = CWrapper.NSWindow.screen(getNSWindowPtr());
+ toBounds = CWrapper.NSScreen.visibleFrame(screen).getBounds();
+ // Flip the y coordinate
+ Rectangle frame = CWrapper.NSScreen.frame(screen).getBounds();
+ toBounds.y = frame.height - toBounds.y - toBounds.height;
+ } else {
+ toBounds = normalBounds;
+ this.normalBounds = null;
+ }
+ setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height);
+ }
+ }
+
@Override // PlatformWindow
public void setVisible(boolean visible) {
final long nsWindowPtr = getNSWindowPtr();
@@ -486,7 +512,7 @@
CWrapper.NSWindow.deminiaturize(nsWindowPtr);
break;
case Frame.MAXIMIZED_BOTH:
- CWrapper.NSWindow.zoom(nsWindowPtr);
+ zoom();
break;
}
}
@@ -526,7 +552,7 @@
CWrapper.NSWindow.miniaturize(nsWindowPtr);
break;
case Frame.MAXIMIZED_BOTH:
- CWrapper.NSWindow.zoom(nsWindowPtr);
+ zoom();
break;
}
}
@@ -692,7 +718,7 @@
if (prevWindowState == Frame.MAXIMIZED_BOTH) {
// let's return into the normal states first
// the zoom call toggles between the normal and the max states
- CWrapper.NSWindow.zoom(nsWindowPtr);
+ zoom();
}
CWrapper.NSWindow.miniaturize(nsWindowPtr);
break;
@@ -701,14 +727,14 @@
// let's return into the normal states first
CWrapper.NSWindow.deminiaturize(nsWindowPtr);
}
- CWrapper.NSWindow.zoom(nsWindowPtr);
+ zoom();
break;
case Frame.NORMAL:
if (prevWindowState == Frame.ICONIFIED) {
CWrapper.NSWindow.deminiaturize(nsWindowPtr);
} else if (prevWindowState == Frame.MAXIMIZED_BOTH) {
// the zoom call toggles between the normal and the max states
- CWrapper.NSWindow.zoom(nsWindowPtr);
+ zoom();
}
break;
default: