src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java

Print this page

        

@@ -207,10 +207,11 @@
     private CPlatformWindow owner;
     private boolean visible = false; // visibility status from native perspective
     private boolean undecorated; // initialized in getInitialStyleBits()
     private Rectangle normalBounds = null; // not-null only for undecorated maximized windows
     private CPlatformResponder responder;
+    private volatile boolean zoomed = false; // from native perspective
 
     public CPlatformWindow(final PeerType peerType) {
         super(0, true);
         assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME);
     }

@@ -465,30 +466,46 @@
     public void setBounds(int x, int y, int w, int h) {
 //        assert CThreading.assertEventQueue();
         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) {
+            zoomed = true;
             CWrapper.NSWindow.zoom(getNSWindowPtr());
         } else {
-            // OS X handles -zoom incorrectly for undecorated windows
-            final boolean isZoomed = this.normalBounds == null;
-            deliverZoom(isZoomed);
+            deliverZoom(true);
 
-            Rectangle toBounds;
-            if (isZoomed) {
                 this.normalBounds = peer.getBounds();
                 long screen = CWrapper.NSWindow.screen(getNSWindowPtr());
-                toBounds = CWrapper.NSScreen.visibleFrame(screen).getBounds();
+            Rectangle 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;
+            setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height);
+        }
+    }
+
+    private void unmaximize() {
+        if (!isMaximized()) {
+            return;
+        }
+        if (!undecorated) {
+            zoomed = false;
+            CWrapper.NSWindow.zoom(getNSWindowPtr());
             } else {
-                toBounds = normalBounds;
+            deliverZoom(false);
+
+            Rectangle toBounds = this.normalBounds;
                 this.normalBounds = null;
-            }
             setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height);
         }
     }
 
     private boolean isVisible() {

@@ -497,47 +514,34 @@
 
     @Override // PlatformWindow
     public void setVisible(boolean visible) {
         final long nsWindowPtr = getNSWindowPtr();
 
-        // 1. Process parent-child relationship when hiding
+        // Process parent-child relationship when hiding
         if (!visible) {
-            // 1a. Unparent my children
+            // 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());
                     }
                 }
             }
 
-            // 1b. Unparent myself
+            // Unparent myself
             if (owner != null && owner.isVisible()) {
                 CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), nsWindowPtr);
             }
         }
 
-        // 2. Configure stuff
+        // Configure stuff
         updateIconImages();
         updateFocusabilityForAutoRequestFocus(false);
 
-        // 3. Manage the extended state when hiding
-        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
+        // Actually show or hide the window
         LWWindowPeer blocker = peer.getBlocker();
         if (blocker == null || !visible) {
             // If it ain't blocked, or is being hidden, go regular way
             if (visible) {
                 CWrapper.NSWindow.makeFirstResponder(nsWindowPtr, contentView.getAWTView());

@@ -562,41 +566,44 @@
             CWrapper.NSWindow.orderWindow(nsWindowPtr, CWrapper.NSWindow.NSWindowBelow,
                     ((CPlatformWindow)blocker.getPlatformWindow()).getNSWindowPtr());
         }
         this.visible = visible;
 
-        // 5. Manage the extended state when showing
+        // Manage the extended state when showing
         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) {
                 switch (((Frame)target).getExtendedState()) {
                     case Frame.ICONIFIED:
                         CWrapper.NSWindow.miniaturize(nsWindowPtr);
                         break;
                     case Frame.MAXIMIZED_BOTH:
-                        zoom();
+                        maximize();
+                        break;
+                    default: // NORMAL
+                        unmaximize(); // in case it was maximized, otherwise this is a no-op
                         break;
                 }
             }
         }
 
         nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
 
-        // 6. Configure stuff #2
+        // Configure stuff #2
         updateFocusabilityForAutoRequestFocus(true);
 
-        // 7. Manage parent-child relationship when showing
+        // Manage parent-child relationship when showing
         if (visible) {
-            // 7a. Add myself as a child
+            // Add myself as a child
             if (owner != null && owner.isVisible()) {
                 CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), nsWindowPtr, CWrapper.NSWindow.NSWindowAbove);
                 if (target.isAlwaysOnTop()) {
                     CWrapper.NSWindow.setLevel(nsWindowPtr, CWrapper.NSWindow.NSFloatingWindowLevel);
                 }
             }
 
-            // 7b. Add my own children to myself
+            // Add my own children to 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()) {

@@ -607,11 +614,11 @@
                     }
                 }
             }
         }
 
-        // 8. Deal with the blocker of the window being shown
+        // Deal with the blocker of the window being shown
         if (blocker != null && visible) {
             // Make sure the blocker is above its siblings
             ((CPlatformWindow)blocker.getPlatformWindow()).orderAboveSiblings();
         }
     }

@@ -765,27 +772,27 @@
         switch (windowState) {
             case Frame.ICONIFIED:
                 if (prevWindowState == Frame.MAXIMIZED_BOTH) {
                     // let's return into the normal states first
                     // the zoom call toggles between the normal and the max states
-                    zoom();
+                    unmaximize();
                 }
                 CWrapper.NSWindow.miniaturize(nsWindowPtr);
                 break;
             case Frame.MAXIMIZED_BOTH:
                 if (prevWindowState == Frame.ICONIFIED) {
                     // let's return into the normal states first
                     CWrapper.NSWindow.deminiaturize(nsWindowPtr);
                 }
-                zoom();
+                maximize();
                 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
-                    zoom();
+                    unmaximize();
                 }
                 break;
             default:
                 throw new RuntimeException("Unknown window state: " + windowState);
         }