United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-7124428 [macosx] Frame.setExtendedState() doesn't work for undecorated windows
JDK-7124428 : [macosx] Frame.setExtendedState() doesn't work for undecorated windows

Details
Type:
Bug
Submit Date:
2011-12-23
Status:
Closed
Updated Date:
2013-07-12
Project Name:
JDK
Resolved Date:
2012-04-04
Component:
client-libs
OS:
os_x
Sub-Component:
java.awt
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
7u4 (b18)

Related Reports
Backport:
Relates:

Sub Tasks

Description
http://java.net/jira/browse/MACOSX_PORT-35 submitted 2011/04/27 by Artem Ananiev
Run the attached test. It creates a simple undecorated window and register a mouse listener. When clicked, the window is maximized with a call to setExtendedState(MAXIMIZED_BOTH). However, the maximization only works for decorated windows, while undecorated windows just move to the left bottom corner of the screen.
The test case:

import java.awt.*;
import java.awt.event.*;

public class CheckExtendedState {

    public static void main(String[] args) {

	final Frame f = new Frame();
	f.setUndecorated(true);
	f.addMouseListener(new MouseAdapter() {
	    public void mouseClicked(MouseEvent e) {
		f.setExtendedState(Frame.MAXIMIZED_BOTH);
	    }
	});
	f.addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
		if (e.getKeyChar() == 'g') {
		    System.exit(0);
		}
	    }
	});
	f.setSize(640, 480);
	f.setLocationRelativeTo(null);
	f.setVisible(true);
    }

}

                                    

Comments
EVALUATION

Author: Yuri Nesterenko Date: 14/Oct/11 09:15 AM
Build: b201
AWT_ZoomFrame/Automated/UndecoratedFrame/GetStateTest/GetStateTest.html
AWT_UndecoratedFrame/Automated/AWT/FullSize
AWT_UndecoratedFrame/Automated/Swing/FullSize
closed/java/awt/Frame/Undecorated/MaximizeUndecoratedTest/MaximizeUndecoratedTest
                                     
2011-12-23
SUGGESTED FIX

--- old/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	2012-03-16 21:15:09.000000000 +0400
+++ new/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	2012-03-16 21:15:09.000000000 +0400
@@ -203,6 +203,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);
@@ -281,8 +283,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
@@ -468,6 +470,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();
@@ -488,7 +514,7 @@
                     CWrapper.NSWindow.deminiaturize(nsWindowPtr);
                     break;
                 case Frame.MAXIMIZED_BOTH:
-                    CWrapper.NSWindow.zoom(nsWindowPtr);
+                    zoom();
                     break;
             }
         }
@@ -521,7 +547,7 @@
                         CWrapper.NSWindow.miniaturize(nsWindowPtr);
                         break;
                     case Frame.MAXIMIZED_BOTH:
-                        CWrapper.NSWindow.zoom(nsWindowPtr);
+                        zoom();
                         break;
                 }
             }
@@ -682,7 +708,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;
@@ -691,14 +717,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:
                                     
2012-03-16
EVALUATION

It looks like OS X handles the -zoom request incorrectly for undecorated windows. Therefore we have to emulate it in our code.
                                     
2012-03-16



Hardware and Software, Engineered to Work Together