8007267: [macosx] com.apple.eawt.Application.setDefaultMenuBar is not working

Reviewed-by: anthony, serb
This commit is contained in:
Leonid Romanov 2013-07-26 16:22:29 +04:00
parent 48c46af177
commit b146ea38dd
4 changed files with 48 additions and 13 deletions
jdk/src/macosx
classes
com/apple/eawt
sun/lwawt/macosx
native/sun/awt

@ -31,6 +31,7 @@ import java.awt.peer.MenuComponentPeer;
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 @@ class _AppMenuBarHandler {
// 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 @@ class _AppMenuBarHandler {
// 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 @@ class _AppMenuBarHandler {
}
// grab the pointer to the CMenuBar, and retain it in native
nativeSetDefaultMenuBar(((CMenuBar)peer).getNativeMenuBarPeer());
*/
nativeSetDefaultMenuBar(((CMenuBar)peer).getModel());
}
void setAboutMenuItemVisible(final boolean present) {

@ -43,7 +43,7 @@ public abstract class CMenuComponent implements MenuComponentPeer {
return target;
}
long getModel() {
public long getModel() {
return modelPtr;
}

@ -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 @@ static JNF_CLASS_CACHE(jc_CPlatformWindow, "sun/lwawt/macosx/CPlatformWindow");
// 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;
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;
}
[CMenuBar activate:menuBar modallyDisabled:!awtWindow.isEnabled];
if (menuBar == nil) {
menuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar];
isDisabled = NO;
}
[CMenuBar activate:menuBar modallyDisabled:isDisabled];
[AWTWindow setLastKeyWindow:nil];
@ -565,6 +575,14 @@ AWT_ASSERT_APPKIT_THREAD;
[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 @@ JNF_COCOA_ENTER(env);
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];
}
}];

@ -70,9 +70,15 @@ AWT_ASSERT_APPKIT_THREAD;
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 @@ JNF_COCOA_ENTER(env);
eventKey = [NSString stringWithCharacters: &newChar length: 1];
}
if ([menuKey isEqualToString:eventKey]) {
NSWindow *keyWindow = [NSApp keyWindow];
if ([menuKey isEqualToString:eventKey] && keyWindow != nil) {
return;
}
}