Bug 211359 - Apple+Q doesn't quit an SWT app, nor does menu selection of same
Summary: Apple+Q doesn't quit an SWT app, nor does menu selection of same
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.4   Edit
Hardware: Macintosh Mac OS X
: P3 normal (vote)
Target Milestone: 3.4 M6   Edit
Assignee: Kevin Barnes CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed
Depends on:
Blocks:
 
Reported: 2007-11-28 19:15 EST by Alex Blewitt CLA
Modified: 2008-02-21 11:25 EST (History)
6 users (show)

See Also:


Attachments
A patch for Quit Application (4.04 KB, patch)
2008-01-29 04:21 EST, Sky Yan CLA
no flags Details | Diff
loads a NIB (7.88 KB, patch)
2008-02-19 17:38 EST, Kevin Barnes CLA
no flags Details | Diff
based on Kevin's patch. (8.04 KB, patch)
2008-02-21 03:12 EST, Zhang Yao CLA
no flags Details | Diff
Another patch based on Kevin's code (8.15 KB, patch)
2008-02-21 03:16 EST, Sky Yan CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alex Blewitt CLA 2007-11-28 19:15:50 EST
Going to the Java menu and selecting Apple+Q leaves the menu looking like it's hanging. In fact, the only way to get it to shut down is by clicking on the red close button.
Comment 1 Sky Yan CLA 2008-01-29 04:21:52 EST
Created attachment 88108 [details]
A patch for Quit Application

The patch only resolve quit application from menu bar and dock menu. But the shortcut key COMMAND+Q dose not works. I have no idea why it happens. Is it another bug?
Comment 2 Steve Northover CLA 2008-01-30 14:01:05 EST
I seem to remember this from the carbon port.  Did anyone look at the code?
Comment 3 Scott Kovatch CLA 2008-01-30 14:30:01 EST
This change is not correct, as it won't tell NSApplication to do its necessary shutdown activities. Setting up a quit responder is normally handled in the nib. If you use the standard Java application nib in the JavaVM framework it's already set up for you.

If you are creating the application menu entirely within code you need to set the action of the Quit item to terminate: and the target to nil.

In objective-C you would do this:

NSMenuItem *menuItem = <quit menu item>;
[menuItem setAction:@selector(terminate:)];
[menuItem setTarget:nil];

A nil target is okay. That tells NSApplication to look for an appropriate responder to handle the action.

Then, your NSApplication delegate should respond to applicationWillTerminate: and you should do any final cleanup in that method.

Have a look at <http://developer.apple.com/documentation/Cocoa/Conceptual/AppArchitecture/Tasks/GracefulAppTermination.html> for more information. This document goes into a lot of detail about document-based applications, but it applies to the SWT as well.
Comment 4 Sky Yan CLA 2008-01-31 11:45:11 EST
Accessing the Quit menu item is hard for me. For SWT dose not use any nib file, and it seems that there is no API to access application menu.

I googled a serial of articles about how to create cocoa application without nib:

http://lapcatsoftware.com/blog/2007/11/25/working-without-a-nib-part-6-working-without-a-xib/

By this way, it may be possible to get the Quit menu item and set the action of it. But it is a little complicated for it needs to create application menu by programming. Is it possible to implement SWT as this way?
Comment 5 Kevin Barnes CLA 2008-01-31 12:37:49 EST
Sky Yan. See bug 210430 for some instructions on how we could use a NIB.
Comment 6 Scott Kovatch CLA 2008-01-31 12:54:52 EST
What Kevin said. :-)

I've mentioned this to Steve N. in the past via email, but I'm now saying it
here too. For the record, I have no problems with the SWT using the NIB
installed in JavaVM.framework that we use in the AWT. It's a standard nib that
you would get if you ran Interface Builder yourself and created a new nib file
for a Cocoa application. The main menu consists of an application menu that can
have other menus added or removed from it.

As of Java 6 it will live in
/System/Library/Frameworks/JavaVM.framework/Resources/English.lproj/DefaultApp.nib
and will be localized to a number of other languages. Eventually all versions
of Java will use that shared nib file as well, but right now 1.5 uses the
identical nib in
/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Resources/English.lproj/DefaultApp.nib.
I would look in the shared location first, and if it's not there fall back to
the version-specific one.

(Note this is not blanket permission for any other code to use this resource.
It is solely for the use of the SWT and AWT.)

I'm now re-reading my previous comment about creating a Quit menu item and
realizing I may have left the impression that this was doable on Leopard.
Unfortunately it's not and I apologize for sending you in the wrong direction.

I will cross-reference bug #210430, which needs to know this as well.

Comment 7 Sky Yan CLA 2008-02-01 10:02:52 EST
Interesting, is that means if SWT uses NIB file, this bug will be fixed? 
Comment 8 Zhang Yao CLA 2008-02-02 03:42:15 EST
Better change should be:
1. create a delegate object for NSApplication.
2. add selector of applicationWillTerminate to the callback.
3. handle quit things in the callback.

We tried it but  the notification of applicationWillTerminate is not send out at all. After making some investigation, it seems that the reason is the using of nextEventMatchingMask. We made a experiment to use NSApplication;run and we can get nextEventMatchingMask.

I guess that it is because some internal standard application event processing handler is not installed without using NSApplication:run. 
Comment 9 Zhang Yao CLA 2008-02-02 03:43:47 EST
sorry, some type error.

Better change should be:
1. create a delegate object for NSApplication.
2. add selector of applicationWillTerminate to the callback.
3. handle quit things in the callback.

We tried it but  the notification of applicationWillTerminate is not send out
at all. After making some investigation, it seems that the reason is the using
of nextEventMatchingMask. We made a experiment to use NSApplication:run and we
can get applicationWillTerminate.

I guess that it is because some internal standard application event processing
handler is not installed without using NSApplication:run. 
Comment 10 Scott Kovatch CLA 2008-02-04 00:22:07 EST
(In reply to comment #7)
> Interesting, is that means if SWT uses NIB file, this bug will be fixed? 

Not just using the NIB -- additions to an NSApplication delegate are needed as well.

(In reply to comment #9)
> Better change should be:
> 1. create a delegate object for NSApplication.
> 2. add selector of applicationWillTerminate to the callback.
> 3. handle quit things in the callback.

Are you using the NIB? I'm guessing you are -- applicationWillTerminate: only gets called if something calls [NSApp terminate:], which is what the standard Quit item does.

> We tried it but  the notification of applicationWillTerminate is not send out
> at all. After making some investigation, it seems that the reason is the using
> of nextEventMatchingMask. We made a experiment to use NSApplication:run and we
> can get applicationWillTerminate.
> 
> I guess that it is because some internal standard application event processing
> handler is not installed without using NSApplication:run. 

I see one possible reason. Display.init() should call [NSApp finishLaunching] so some necessary handlers get set up. [NSApplication run] calls this before entering the event dispatch loop. I'm not set up at the moment to try this myself.
Comment 11 Zhang Yao CLA 2008-02-18 20:45:32 EST
scott,
I try to call NSApp.finishLaunching in Display.init(). Unfortunately it doesn't work. And even the apple menu is not able to show...
Comment 12 Kevin Barnes CLA 2008-02-19 17:38:58 EST
Created attachment 90117 [details]
loads a NIB

I played around with this a little this afternoon. I can load a NIB and get the terminate: callback. I'm not sure when I'll have time to finish this, but in case anyone else has some time to spend on it I'm posting my work here.
Comment 13 Zhang Yao CLA 2008-02-20 05:18:01 EST
kevin,

I try your code and do get terminate. Will spend more time to finish it. 
Comment 14 Zhang Yao CLA 2008-02-21 03:12:03 EST
Created attachment 90304 [details]
based on Kevin's patch.

Add quit code in applicationDelegateProc's case of OS.sel_terminate_1.
The quit code is the same as SWT.Carbon's in coreEventProc of AppleEvent OS.kAEQuitApplication.
Comment 15 Sky Yan CLA 2008-02-21 03:16:03 EST
Created attachment 90305 [details]
Another patch based on Kevin's code

I added some code based on Kevin's patch.  Now selecting Apple+Q will quit the application gracefully. This patch also handles Hide/Unhide app messages.  And after loading NIB file, it replaces "%@" in each item title of application menu with SWT App name. Moreover, when clicking "About SWT" menu item, it sends out a SWT.ABOUT event to display. 

Hope this patch be useful to fix this bug.
Comment 16 Kevin Barnes CLA 2008-02-21 11:20:45 EST
fixed in HEAD with a slightly modified version of Sky Yan's patch.
Thanks for the help everyone.

btw, now that we're loading a nib we should be able to solve bug 210430 and get Shell.setMenuBar working. Anyone want to have a go at that?