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

Print this page

        

@@ -87,10 +87,11 @@
     public static final String WINDOW_DOC_MODAL_SHEET = "apple.awt.documentModalSheet";
     public static final String WINDOW_FADE_DELEGATE = "apple.awt._windowFadeDelegate";
     public static final String WINDOW_FADE_IN = "apple.awt._windowFadeIn";
     public static final String WINDOW_FADE_OUT = "apple.awt._windowFadeOut";
     public static final String WINDOW_FULLSCREENABLE = "apple.awt.fullscreenable";
+    public static final String WINDOW_MENU_VISIBLE_IN_FULLSCREEN = "apple.awt.menuVisibleInFullscreen";
 
 
     // Yeah, I know. But it's easier to deal with ints from JNI
     static final int MODELESS = 0;
     static final int DOCUMENT_MODAL = 1;

@@ -190,16 +191,19 @@
             if (root == null || (LWWindowPeer)root.getPeer() == null) return null;
             return (CPlatformWindow)((LWWindowPeer)root.getPeer()).getPlatformWindow();
         }
     };
 
+    private final Object LOCK = new Object(){};
+
     // Bounds of the native widget but in the Java coordinate system.
     // In order to keep it up-to-date we will update them on
     // 1) setting native bounds via nativeSetBounds() call
     // 2) getting notification from the native level via deliverMoveResizeEvent()
     private Rectangle nativeBounds;
-    private volatile boolean isFullScreenMode = false;
+
+    private boolean isFullScreenMode = false; // synchronized on the LOCK
 
     private Window target;
     private LWWindowPeer peer;
     private CPlatformView contentView;
     private CPlatformWindow owner;

@@ -379,16 +383,10 @@
     // this is the counter-point to -[CWindow _nativeSetStyleBit:]
     protected void setStyleBits(final int mask, final boolean value) {
         nativeSetNSWindowStyleBits(getNSWindowPtr(), mask, value ? mask : 0);
     }
 
-    private native void _toggleFullScreenMode(final long model);
-
-    public void toggleFullScreen() {
-        _toggleFullScreenMode(getNSWindowPtr());
-    }
-
     @Override // PlatformWindow
     public void setMenuBar(MenuBar mb) {
         final long nsWindowPtr = getNSWindowPtr();
         CMenuBar mbPeer = (CMenuBar)LWToolkit.targetToPeer(mb);
         if (mbPeer != null) {

@@ -652,21 +650,80 @@
             long clearColor = CWrapper.NSColor.clearColor();
             CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), clearColor);
         }
     }
 
+    private void setMenuBarVisibleIfOnPrimaryScreen(boolean visible) {
+        long screen = CWrapper.NSWindow.screen(getNSWindowPtr());
+        try {
+            long primaryScreen = CWrapper.NSScreen.screens(0);
+            try {
+                if (primaryScreen == screen) {
+                    CWrapper.NSMenu.setMenuBarVisible(visible);
+                }
+            } finally {
+                CWrapper.NSObject.release(primaryScreen);
+            }
+        } finally {
+            CWrapper.NSObject.release(screen);
+        }
+    }
+
+    // Used from com.apple.eawt.Application.requestToggleFullScreen()
+    public void toggleFullScreen() {
+        synchronized (LOCK) {
+            if (!isFullScreenMode) {
+                enterFullScreenMode();
+            } else {
+                exitFullScreenMode();
+            }
+        }
+    }
+
     @Override
     public void enterFullScreenMode() {
+        synchronized (LOCK) {
+            if (!isFullScreenMode) {
         isFullScreenMode = true;
-        contentView.enterFullScreenMode(getNSWindowPtr());
+                boolean hideMenuBar = true;
+
+                if (target instanceof javax.swing.RootPaneContainer) {
+                    javax.swing.JRootPane rootpane = ((javax.swing.RootPaneContainer)target).getRootPane();
+                    Object prop = rootpane.getClientProperty(WINDOW_MENU_VISIBLE_IN_FULLSCREEN);
+                    if (prop != null) {
+                        if (Boolean.parseBoolean(prop.toString())) {
+                            hideMenuBar = false;
+                        }
+                    }
+
+                    prop = rootpane.getClientProperty(WINDOW_FULLSCREENABLE);
+                    if (prop != null) {
+                        if (Boolean.parseBoolean(prop.toString())) {
+                            // OS will auto-hide the menu for such windows
+                            hideMenuBar = false;
+                        }
+                    }
+                }
+
+                if (hideMenuBar) {
+                    setMenuBarVisibleIfOnPrimaryScreen(false);
+                }
+                CWrapper.NSWindow.toggleFullScreen(getNSWindowPtr(), 0L);
+            }
+        }
     }
 
     @Override
     public void exitFullScreenMode() {
-        contentView.exitFullScreenMode();
+        synchronized (LOCK) {
+            if (isFullScreenMode) {
+                CWrapper.NSWindow.toggleFullScreen(getNSWindowPtr(), 0L);
+                setMenuBarVisibleIfOnPrimaryScreen(true);
         isFullScreenMode = false;
     }
+        }
+    }
 
     @Override
     public void setWindowState(int windowState) {
         if (!peer.isVisible()) {
             // setVisible() applies the state

@@ -761,16 +818,10 @@
     private void deliverWindowFocusEvent(boolean gained){
         peer.notifyActivation(gained);
     }
 
     private void deliverMoveResizeEvent(int x, int y, int width, int height) {
-        // when the content view enters the full-screen mode, the native
-        // move/resize notifications contain a bounds smaller than
-        // the whole screen and therefore we ignore the native notifications
-        // and the content view itself creates correct synthetic notifications
-        if (isFullScreenMode) return;
-
         nativeBounds = new Rectangle(x, y, width, height);
         peer.notifyReshape(x, y, width, height);
         //TODO validateSurface already called from notifyReshape
         validateSurface();
     }