Community
Participate
Working Groups
Build Identifier: 3.6M6 An AWT/Swing user interface may or may not decide to use the screen menu bar. The various configuration tweaks are: 1. Setting the "apple.laf.useScreenMenuBar" system property to "true". 2. Setting the "com.apple.mrj.application.apple.menu.about.name" system property to whatever name. 3. Invoking "com.apple.eawt.Application.getApplication().addApplicationListener(listener)" to hook to the various application menu items. 4. com.apple.eawt.Application.getApplication().setEnabledPreferencesMenu(true); Adding an SWT control must not interfer with the menus that appear in that bar, which is not the case currently. This is a showstopper for some of my users. SWT should detect that AWT is in the picture and not touch the application menu. Reproducible: Always Steps to Reproduce: 1. Create an AWT/Swing application. 2. Configures the application menu bar through Mac-specific system properties and APIs. 3. Embed an SWT control => menus are not the ones expected.
Created attachment 163171 [details] Test case with boolean to try different scenarios. Here is an AWT/Swing test case that allows trying with and without embedding SWT, and with and without configuring the default application menu. Note that when trying the embedded SWT mode, you need the "-XstartOnFirstThread" flag.
I forgot to mention that this bug was found using 3.6M6, but we also tried the N20100326-2000 nightly with same issues.
We are very keen on seeing this bug fixed. The biggest issue is that nothing happens when you choose Quit in the menu. If that would work, I'm sure we could work the fact that we cannot add our own items to the menu.
(In reply to comment #3) > The biggest issue is that nothing happens when you choose Quit in the menu. If > that would work, I'm sure we could work the fact that we cannot add our own > items to the menu. While this may suit your particular need, I think this would definitely not be enough, because: a. System.exit() may not be what the users expect within a Swing application. They want there shutdown procedure to be called. b. If they took the time to configure preferences and the like, they expect them to work even after adding a 3rd party lib that internally uses SWT. I hope the fix is as simple as preventing SWT to hook to the application menu, which would obviously satisfy everyone.
Good point, I'll rephrase: If a workaround could be found for making the application quit, I'd be happy to use that until the real bug has been fixed.
Ouch. I didn't see this because it was tagged as "Mac OS X", not "Mac OS X - cocoa". May not make it for 3.6, but maybe 3.6.1.
Targeting 3.6.1. We're way too late for 3.6 at this point, but this is a good candidate for 3.6.1.
(In reply to comment #6) > Ouch. I didn't see this because it was tagged as "Mac OS X", not "Mac OS X - > cocoa". May not make it for 3.6, but maybe 3.6.1. Ouch indeed, I get more and more people hitting this issue and asking me if a fix is coming soon. They say they cannot ship on OS X with such a messed up menu. It is a pity that this bug got trapped in a Bugzilla black hole :)
I'm not convinced this is an SWT bug yet, but I think we can find a way to work around it in the SWT. The AWT normally sets up the menu bar when the it is first loaded, but because the AWT thinks the SWT is in use, it doesn't do it. If I comment out all of our menubar setup in Display.applicationWillFinishLaunching we'll get the bare-minimum application menu but not the AWT-generated menu. I believe the AWT makes the assumption that it will not be controlling the menu bar when -XstartOnFirstThread is used to launch the VM, so it doesn't set up the EAWT listeners. We may need to find a way to force it to do so if the screen menubar property is set.
(In reply to comment #9) > I'm not convinced this is an SWT bug yet, but I think we can find a way to work > around it in the SWT. The AWT normally sets up the menu bar when the it is > first loaded, but because the AWT thinks the SWT is in use, it doesn't do it. > If I comment out all of our menubar setup in > Display.applicationWillFinishLaunching we'll get the bare-minimum application > menu but not the AWT-generated menu. > > I believe the AWT makes the assumption that it will not be controlling the menu > bar when -XstartOnFirstThread is used to launch the VM, so it doesn't set up > the EAWT listeners. We may need to find a way to force it to do so if the > screen menubar property is set. The AWT won't allow the eAWT NSApplication subclass to initialize unless the class of NSApp is *exactly* NSApplication. If you install in your own NSApp, the usually means that you are completely in control of how preferences/about/quit/etc. are handled. If the eAWT is initialized, and the NSApp is swapped out later by the SWT, the eAWT listeners won't fire, because the hooks all hang off of it's own NSApplication subclass.
(In reply to comment #10) > The AWT won't allow the eAWT NSApplication subclass to initialize unless the > class of NSApp is *exactly* NSApplication. If you install in your own NSApp, > the usually means that you are completely in control of how > preferences/about/quit/etc. are handled. > > If the eAWT is initialized, and the NSApp is swapped out later by the SWT, the > eAWT listeners won't fire, because the hooks all hang off of it's own > NSApplication subclass. Isn't (one of) the problem the order of initialization? If the AWT is loaded first it gets to determine which NSApplication or subclass will be used. In the attached test case, the AWT is loading first because UIManager.setLookAndFeel gets called. By the time control reaches Display's construction I see we already have a sharedApplication of type NSApplication, with 'isRunning' returning true. I think the other problem is that the AWT assumes a Carbon SWT, so it's calling NSApplicationLoad(). For 64-bit that's not a valid assumption, of course, but I'm not sure how the AWT could know a Cocoa SWT is about to launch.
> Isn't (one of) the problem the order of initialization? In AWT/SWT mixing, AWT or SWT code could be invoked first (Display could be created as first line, UIManager call, etc.). Are you saying there is some sort of auto-detection (heuristic-like) to activate certain modes? > I think the other problem is that the AWT assumes a Carbon SWT, so it's calling > NSApplicationLoad(). For 64-bit that's not a valid assumption, of course, but > I'm not sure how the AWT could know a Cocoa SWT is about to launch. We already have to specify -XstartOnFirstThread so I guess it would not be worse if we could hint certain aspects using new flags (-XloadCocoa, etc.). Would that make sense?
(In reply to comment #12) > In AWT/SWT mixing, AWT or SWT code could be invoked first (Display could be > created as first line, UIManager call, etc.). Are you saying there is some sort > of auto-detection (heuristic-like) to activate certain modes? Normally, when the AWT starts up it checks to see if an NSApplication is running. If one is running it goes into 'embedded mode' for applet or embedded-frame support. If no NSApplication is running the AWT would normally create its own and start handling events. If '-XstartOnFirstThread' was specified it assumes a Carbon SWT will be starting up to pump the event loop, if it hasn't started already. Using this startup logic, the AWT behaves properly whether an SWT Display has been created or not. This needs to be handled by some kind of special case in the AWT. An AWT Frame or signed applet with full permissions embedded in a Cocoa or Carbon application isn't able to use the eAWT either because the AWT doesn't 'own' the menu bar in that situation. > We already have to specify -XstartOnFirstThread so I guess it would not be > worse if we could hint certain aspects using new flags (-XloadCocoa, etc.). > Would that make sense? It would. I was thinking more along the lines of looking at what's in the classpath or examining the 'osgi.ws' property but that means the AWT needs knowledge of the SWT and I'd like to avoid that. I also think that a system property might be the better choice in this case, as '-X' flags are usually reserved for things that affect the Java launcher.
After talking to Mike this will have to wait for 3.7 and a Java update. The eAWT needs to expose its application delegate implementation and then the SWT needs to change its delegate implementation to hand off notifications to both the SWT and AWT as needed.
I plan to check in a fix for this today, but I want to add a few observations. -- I now understand better some of the reasons why folks want to use the eAWT in an SWT application. If folks feel that they need to use the eAWT because they can't do something in the SWT, then we should try to address that. I don't want to match the eAWT's application listener interface method for method, so if there's a specific feature you want to see please file a new bug. For example, the only way to listen to the application menu items is via the ApplicationListener interface. We plan to have an SWT equivalent in 3.7 with a new API for accessing application menu items. To implement the equivalent of handleOpenFile, add a listener to the current Display for SWT.OpenDocument. The name of the file is in the 'text' field of the Event. To implement the equivalent of ApplicationListener.handleQuit, add a listener to the current Display for SWT.Close. If you're not ready to close, set the doIt field of the event to false and the application won't quit. Note that due to the way the AWT is implemented something must call System.exit(); the application will not automatically exit once the last AWT window is closed. Because of this, I recommend that you use either an eAWT handleQuit listener or listen for Display to send SWT.Close but not both. -- I fixed Display startup so that apple.laf.useScreenMenuBar will work as long as you set it before the AWT starts up. -- I added support for com.apple.mrj.application.apple.menu.about.name, but you should use Display.setAppName() instead. That will take precedence over the MRJ property. The precedence is: Whatever was set with -Xdock:name The string set with Display.setAppName() If the application is bundled, the value of CFBundleName from your info.plist The property value for "com.apple.mrj.application.apple.menu.about.name" "SWT" if nothing else was set. Once a Display object has been created the name cannot change. -- eAWT application handlers won't work unless the AWT starts before the SWT. This is a limitation of the AWT, because the necessary native code isn't loaded until the AWT loads, and I don't want to pull in the entire AWT on the chance that someone wants to use the eAWT. I have a request in to Apple to provide a notification that will fire when the AWT has loaded, and then I can create the AWT's application delegate that will handle the application menu items. When that request is implemented I can remove this restriction. -- If you start the AWT first, you may not be able to receive SWT.OpenDocument events. I didn't test this, but I believe that when the AWT calls NSApplicationLoad() none of the default AppleEvent handlers are set up, so the SWT won't receive them. I will try to expand on this in a blog post, but these are the important points.
Fixed > 20100927.
Created attachment 179693 [details] Revised test case Slightly modified test case describing some of the things in my previous message.
Created attachment 183006 [details] Issue on Mac OS X 10.5 with Java 5 Scott, I have a user who has an issue: - They need compatibility with Mac OS X 10.5. - They use JNI extensively, only 32bit. - There is either Java 6 64 bit (not an option) or Java 5 for 10.5. - Java 5 shows 2 apple menus (see screenshots) which is a showstopper for them. I believe the fixes to support AWT configurations are in Java 6. Isn't there a (hidden?) way to prevent SWT from touching the menus at all so that AWT becomes the only source of configuration? If there is no such way, then I guess this user is stuck so suggestions are welcome.
(In reply to comment #18) > I believe the fixes to support AWT configurations are in Java 6. Isn't there a > (hidden?) way to prevent SWT from touching the menus at all so that AWT becomes > the only source of configuration? If there is no such way, then I guess this > user is stuck so suggestions are welcome. I might be able to do a version check so the SWT doesn't load up the menus, but I'll have to test it out. Does that happen on all SWT_AWT apps? I.e, no special test case required?
(In reply to comment #19) > Does that happen on all SWT_AWT apps? I.e, no special > test case required? I asked that user to run your test case on 10.5 with Java 5, the screenshot is the result of that test case. If there is anything else to test, please let us know.