--- old/src/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java 2013-07-26 15:36:25.000000000 +0400 +++ new/src/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java 2013-07-26 15:36:25.000000000 +0400 @@ -31,6 +31,7 @@ import javax.swing.*; import javax.swing.plaf.MenuBarUI; +import com.apple.laf.ScreenMenuBar; import sun.lwawt.macosx.CMenuBar; import com.apple.laf.AquaMenuBarUI; @@ -72,12 +73,15 @@ // scan the current frames, and see if any are foreground final Frame[] frames = Frame.getFrames(); for (final Frame frame : frames) { - if (frame.isVisible() && !isFrameMinimized(frame)) return; + if (frame.isVisible() && !isFrameMinimized(frame)) { + return; + } } // if we have no foreground frames, then we have to "kick" the menubar final JFrame pingFrame = new JFrame(); pingFrame.getRootPane().putClientProperty("Window.alpha", new Float(0.0f)); + pingFrame.setUndecorated(true); pingFrame.setVisible(true); pingFrame.toFront(); pingFrame.setVisible(false); @@ -101,7 +105,6 @@ // Aqua was not installed throw new IllegalStateException("Application.setDefaultMenuBar() only works with the Aqua Look and Feel"); } -/* TODO: disabled until ScreenMenuBar is working final AquaMenuBarUI aquaUI = (AquaMenuBarUI)ui; final ScreenMenuBar screenMenuBar = aquaUI.getScreenMenuBar(); @@ -118,8 +121,7 @@ } // grab the pointer to the CMenuBar, and retain it in native - nativeSetDefaultMenuBar(((CMenuBar)peer).getNativeMenuBarPeer()); -*/ + nativeSetDefaultMenuBar(((CMenuBar)peer).getModel()); } void setAboutMenuItemVisible(final boolean present) { --- old/src/macosx/classes/sun/lwawt/macosx/CMenuComponent.java 2013-07-26 15:36:25.000000000 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/CMenuComponent.java 2013-07-26 15:36:25.000000000 +0400 @@ -43,7 +43,7 @@ return target; } - long getModel() { + public long getModel() { return modelPtr; } --- old/src/macosx/native/sun/awt/AWTWindow.m 2013-07-26 15:36:26.000000000 +0400 +++ new/src/macosx/native/sun/awt/AWTWindow.m 2013-07-26 15:36:26.000000000 +0400 @@ -30,6 +30,7 @@ #import "sun_lwawt_macosx_CPlatformWindow.h" #import "com_apple_eawt_event_GestureHandler.h" #import "com_apple_eawt_FullScreenHandler.h" +#import "ApplicationDelegate.h" #import "AWTWindow.h" #import "AWTView.h" @@ -55,7 +56,7 @@ // doesn't provide information about "opposite" window, so we // have to do a bit of tracking. This variable points to a window // which had been the key window just before a new key window -// was set. It would be nil if the new key window isn't an AWT +// was set. It would be nil if the new key window isn't an AWT // window or the app currently has no key window. static AWTWindow* lastKeyWindow = nil; @@ -542,17 +543,26 @@ AWT_ASSERT_APPKIT_THREAD; [AWTToolkit eventCountPlusPlus]; AWTWindow *opposite = [AWTWindow lastKeyWindow]; - + // Finds appropriate menubar in our hierarchy, AWTWindow *awtWindow = self; while (awtWindow.ownerWindow != nil) { awtWindow = awtWindow.ownerWindow; } + CMenuBar *menuBar = nil; + BOOL isDisabled = NO; if ([awtWindow.nsWindow isVisible]){ menuBar = awtWindow.javaMenuBar; + isDisabled = !awtWindow.isEnabled; + } + + if (menuBar == nil) { + menuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar]; + isDisabled = NO; } - [CMenuBar activate:menuBar modallyDisabled:!awtWindow.isEnabled]; + + [CMenuBar activate:menuBar modallyDisabled:isDisabled]; [AWTWindow setLastKeyWindow:nil]; @@ -565,6 +575,14 @@ [AWTToolkit eventCountPlusPlus]; [self.javaMenuBar deactivate]; + // In theory, this might cause flickering if the window gaining focus + // has its own menu. However, I couldn't reproduce it on practice, so + // perhaps this is a non issue. + CMenuBar* defaultMenu = [[ApplicationDelegate sharedDelegate] defaultMenuBar]; + if (defaultMenu != nil) { + [CMenuBar activate:defaultMenu modallyDisabled:NO]; + } + // the new key window NSWindow *keyWindow = [NSApp keyWindow]; AWTWindow *opposite = nil; @@ -829,11 +847,19 @@ AWTWindow *window = (AWTWindow*)[nsWindow delegate]; - if ([nsWindow isKeyWindow]) [window.javaMenuBar deactivate]; + if ([nsWindow isKeyWindow]) { + [window.javaMenuBar deactivate]; + } + window.javaMenuBar = menuBar; + CMenuBar* actualMenuBar = menuBar; + if (actualMenuBar == nil) { + actualMenuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar]; + } + if ([nsWindow isKeyWindow]) { - [CMenuBar activate:window.javaMenuBar modallyDisabled:NO]; + [CMenuBar activate:actualMenuBar modallyDisabled:NO]; } }]; --- old/src/macosx/native/sun/awt/CMenuItem.m 2013-07-26 15:36:26.000000000 +0400 +++ new/src/macosx/native/sun/awt/CMenuItem.m 2013-07-26 15:36:26.000000000 +0400 @@ -70,9 +70,15 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; JNF_COCOA_ENTER(env); - // If we are called as a result of user pressing a shorcut, do nothing, + // If we are called as a result of user pressing a shortcut, do nothing, // because AVTView has already sent corresponding key event to the Java - // layer from performKeyEquivalent + // layer from performKeyEquivalent. + // There is an exception from the rule above, though: if a window with + // a menu gets minimized by user and there are no other windows to take + // focus, the window's menu won't be removed from the global menu bar. + // However, the Java layer won't handle invocation by a shortcut coming + // from this "frameless" menu, because there are no active windows. This + // means we have to handle it here. NSEvent *currEvent = [[NSApplication sharedApplication] currentEvent]; if ([currEvent type] == NSKeyDown) { NSString *menuKey = [sender keyEquivalent]; @@ -91,7 +97,8 @@ eventKey = [NSString stringWithCharacters: &newChar length: 1]; } - if ([menuKey isEqualToString:eventKey]) { + NSWindow *keyWindow = [NSApp keyWindow]; + if ([menuKey isEqualToString:eventKey] && keyWindow != nil) { return; } }