--- old/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java 2012-03-05 19:56:40.000000000 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java 2012-03-05 19:56:40.000000000 +0400 @@ -89,6 +89,7 @@ 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 @@ -192,12 +193,15 @@ } }; + 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; @@ -381,12 +385,6 @@ 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(); @@ -654,16 +652,75 @@ } } + 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() { - isFullScreenMode = true; - contentView.enterFullScreenMode(getNSWindowPtr()); + synchronized (LOCK) { + if (!isFullScreenMode) { + isFullScreenMode = true; + 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(); - isFullScreenMode = false; + synchronized (LOCK) { + if (isFullScreenMode) { + CWrapper.NSWindow.toggleFullScreen(getNSWindowPtr(), 0L); + setMenuBarVisibleIfOnPrimaryScreen(true); + isFullScreenMode = false; + } + } } @Override @@ -763,12 +820,6 @@ } 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