7124428: [macosx] Frame.setExtendedState() doesn't work for undecorated windows
authoranthony
Fri, 30 Mar 2012 18:10:05 +0400
changeset 12284 3f2477ebb708
parent 12283 253d9a09f674
child 12285 37f0c586ba99
7124428: [macosx] Frame.setExtendedState() doesn't work for undecorated windows Summary: Emulate native NSWindow -zoom for undecorated windows Reviewed-by: art
jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
--- 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: