Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
i've noticed that i can't terminate an app if there is a sheet present over my main window... it seems this it is the default for NSSheets to disallow termination... i did, however, notice in Safari i am able to quit if the Customize Toolbar sheet is present...

how can i allow termination of an app if a sheet is present?
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
is there no way to do this? the only thing i can think of is the following code, but it doesn't work - the system alert sound goes off (NSBeep) instead of ordering the sheet out and quitting the app.

Code:
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
	{
	if ([registrationSheet isVisible])
		{
		[registrationSheet orderOut:sender];
		}
	return YES;	
	}

the above function is connected correctly in IB, because this works fine ("app quit" will write to the console) when the app quits:

Code:
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
	{
	NSLog (@"app quit");
	return YES;	
	}

any ideas?
 

stadidas

macrumors regular
Feb 27, 2006
243
0
Kent, United Kingdom
I would imagine that applicationShouldTerminate is always called, and the result (Yes) is then only accepted if the application is in a non-modal state, otherwise the NSBeep() function is called. I'm pretty sure this behaviour will be defined in NSApplication, so there's not a whole lot that can be done about it if that is the case.
Just out of interest, why do you want to quit during a sheet? Sheets should only really be used to present to the user an option that the applications needs a responce from. In this situation, application termination is rightly disabled. Maybe a UI re-think is in order rather than trying to work around the standard Apple has put down, although it would be interesting to hear why you need to be able to do this.
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
Maybe a UI re-think is in order rather than trying to work around the standard Apple has put down, although it would be interesting to hear why you need to be able to do this.

Trial Ended, the sheet displays "Quit" or "Purchase License" buttons... having to press the quit button on the sheet instead of Command+Q (or Quit App from the menu bar or dock menu) is annoying, especially when it's still possible to Hide Application, Hide Others, and Show All from the main menu...

as for this being an Apple "standard": in Safari > View > Customize Toolbar. This starts a sheet and still allows a user to quit the app even though the sheet is present.

attached is the best i can come up with, but i still get an NSBeep() instead of being able to quit the app when the sheet is present.
 

Attachments

  • SheetAndQuit.zip
    33.2 KB · Views: 82

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
ok i give up... 2 weeks and nothing i've tried works... not even this:

Code:
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
	{
	if ([theSheet isKeyWindow])
		{
		NSLog (@"App Quit With Active Sheet");
		[self sheetQuit];
		return NO;
		}
		else
		{
		NSLog (@"App Quit");
		return YES;
		}
	}
	
- (void)sheetQuit
	{
	[NSApp endSheet:theSheet];
	[theSheet orderOut:nil];
	[NSApp terminate];
	}

developers who have enabled this function in their app are magical creatures, that's all there is to it... :rolleyes:
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
a total hack job, but better than nothing... and certainly better than an NSBeep()!

for anyone interested, this is what i ended up doing to more-or-less solve this problem:

A- set another (secondary) "Quit Application" menu item under the real one (but i couldn't use the key equivalent Apple-Q because it's taken already)

B- wrote a new method that first ends the sheet and then kills the app.

C- make a hidden button on the sheet that is equivelent to Apple-Q, set to the method mentioned in step B.

D- wrote outlets to the real Quit App menu item and the new secondary Quit App menu item

E- set the menu items hidden YES/NO according to the situation: on beginSheet method, the real Quit App menu item is hidden, and the secondary one is visible. on endSheet the inverse.



there are 3 problems with this:

1. when a sheet is visible, quitting from the dock menu will not work.

2. the secondary Quit App menu item doesn't display Apple-Q as it's key equivalent, as that key equivalent has already been taken by the original Quit App menu item.

3. it's ghetto!

something so simple as this that takes so much effort to implement is definitely something that needs review from Apple.
 

Attachments

  • HackedSheetAndQuit.zip
    35.4 KB · Views: 68

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
finally! some proper code to enable this functionality... still can't quit from the dock menu though, but whatever... enjoy!
 

Attachments

  • SheetAndQuitSOLVED.zip
    42.6 KB · Views: 98

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
I figured it out. In your app's delegate, implement:

Code:
- (void)applicationDidFinishLaunching:(NSNotification *)n
{
    [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
        andSelector:@selector(handleQuitAppleEvent:withReplyEvent:)
        forEventClass:kCoreEventClass
        andEventID:kAEQuitApplication];
}

- (void)handleQuitAppleEvent:(NSAppleEventDescriptor *)event
    withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
    [self handleQuit:nil];
}

- (IBAction)handleQuit:(id)sender
{
    // end all active sheets
    for (NSWindow *win in [NSApp windows])
        if ([win attachedSheet])
            [NSApp endSheet:[win attachedSheet]];
    [NSApp terminate:nil];
}

The handleQuit: method is also hooked up to the File > Quit menu, so all standard calls to quit your application are handled by this method.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.