Handling a menu item in a modal dialog


James Walker
 

I'm trying to enable the Quit menu item while a modal dialog is running, is that possible?  My window controller implements the terminate: action, and has a validateMenuItem: method, but validateMenuItem: never gets called.  The window is main and key, and the only thing preceding the window controller in the responder chain is the window itself, which does not respond to a "terminate:" message.  I've checked that [NSApp targetForAction: @selector(terminate:)] returns my window controller.  What might I be missing?


Bill Pitcher
 

Not sure it is possible, modal means just the controls on sheet are actioned. Normally if you’re in a sheet and you want the App to Quit you add a Button that Quits. I think you can give the button the Command-Q short cut.

If the sheet isn’t fully modal then maybe you’re better coming from the other direction and displaying it non-modally and ensuring the menu options that don’t apply are disabled. YMMV.

cheers
Bill Pitcher
Tutor
Literacy Aotearoa - Dunedin

On 14/08/2018, at 11:51 AM, James Walker <list2@jwwalker.com> wrote:

I'm trying to enable the Quit menu item while a modal dialog is running, is that possible? My window controller implements the terminate: action, and has a validateMenuItem: method, but validateMenuItem: never gets called. The window is main and key, and the only thing preceding the window controller in the responder chain is the window itself, which does not respond to a "terminate:" message. I've checked that [NSApp targetForAction: @selector(terminate:)] returns my window controller. What might I be missing?


James Walker
 

On 8/13/18 5:04 PM, Bill Pitcher wrote:
Not sure it is possible, modal means just the controls on sheet are actioned. Normally if you’re in a sheet and you want the App to Quit you add a Button that Quits. I think you can give the button the Command-Q short cut.

If the sheet isn’t fully modal then maybe you’re better coming from the other direction and displaying it non-modally and ensuring the menu options that don’t apply are disabled. YMMV.

It's not a sheet, just a window being operated with -[NSApplication runModalForWindow:].

On 14/08/2018, at 11:51 AM, James Walker <list2@...> wrote:

I'm trying to enable the Quit menu item while a modal dialog is running, is that possible?  My window controller implements the terminate: action, and has a validateMenuItem: method, but validateMenuItem: never gets called.  The window is main and key, and the only thing preceding the window controller in the responder chain is the window itself, which does not respond to a "terminate:" message.  I've checked that [NSApp targetForAction: @selector(terminate:)] returns my window controller.  What might I be missing?



Andy Lee
 

On Aug 13, 2018, at 8:06 PM, James Walker <list2@jwwalker.com> wrote:
It's not a sheet, just a window being operated with -[NSApplication runModalForWindow:].
I forget the tweak to do this -- I think it has something to do with using your own run loop.

I'm pretty sure I've done what you describe. If I can find how I'll post it here, but maybe the run loop hint will help you find it.

--Andy


James Walker
 

On 8/13/18 6:00 PM, Andy Lee via Groups.Io wrote:
On Aug 13, 2018, at 8:06 PM, James Walker <list2@...> wrote:
It's not a sheet, just a window being operated with -[NSApplication runModalForWindow:].
I forget the tweak to do this -- I think it has something to do with using your own run loop.

I'm pretty sure I've done what you describe.  If I can find how I'll post it here, but maybe the run loop hint will help you find it.

Interesting.  The window does have a little red close button, and once the dialog is closed one can quit normally, so maybe I should just live without it rather than using a custom run loop.

By the way, there are other menu items, implemented in the app delegate, that are enabled while the dialog is running.  Seems like there's something special about the Quit item.  Maybe that's related to the fact that Quit isn't in the menu nib, but gets added magically.


Bill Pitcher
 

"While the app is in that loop, it does not respond to any other events (including mouse, keyboard, or window-close events) unless they are associated with the window. It also does not perform any tasks (such as firing timers) that are not associated with the modal run loop. In other words, this method consumes only enough CPU time to process events and dispatch them to the action methods associated with the modal window.”
Discussion: runModalForWindow

"App-Modal Dialogs
An app-modal dialog prevents the user from doing anything else in the app until the dialog is dismissed.”
https://developer.apple.com/design/human-interface-guidelines/macos/windows-and-views/dialogs/

Consider the
Modeless Dialogs
A modeless dialog is usually referred to as a panel. The user can continue interacting with documents and apps uninterrupted.

cheers
Bill Pitcher
Tutor
Literacy Aotearoa - Dunedin

On 14/08/2018, at 12:06 PM, James Walker <list2@jwwalker.com> wrote:

On 8/13/18 5:04 PM, Bill Pitcher wrote:
Not sure it is possible, modal means just the controls on sheet are actioned. Normally if you’re in a sheet and you want the App to Quit you add a Button that Quits. I think you can give the button the Command-Q short cut.

If the sheet isn’t fully modal then maybe you’re better coming from the other direction and displaying it non-modally and ensuring the menu options that don’t apply are disabled. YMMV.
It's not a sheet, just a window being operated with -[NSApplication runModalForWindow:].

On 14/08/2018, at 11:51 AM, James Walker <list2@jwwalker.com>
wrote:

I'm trying to enable the Quit menu item while a modal dialog is running, is that possible? My window controller implements the terminate: action, and has a validateMenuItem: method, but validateMenuItem: never gets called. The window is main and key, and the only thing preceding the window controller in the responder chain is the window itself, which does not respond to a "terminate:" message. I've checked that [NSApp targetForAction: @selector(terminate:)] returns my window controller. What might I be missing?


Andy Lee
 

On Aug 13, 2018, at 9:05 PM, James Walker <list2@jwwalker.com> wrote:
By the way, there are other menu items, implemented in the app delegate, that are enabled while the dialog is running. Seems like there's something special about the Quit item. Maybe that's related to the fact that Quit isn't in the menu nib, but gets added magically.
I got curious and created a scratch app to fiddle with. I called [NSApp runModalForWindow:] and was surprised to see that even though the dialog was demonstrably modal (clicking on the window behind it caused a beep), the Quit menu item was enabled. I'll send you my mini-project off-list in case it helps.

--Andy


James Walker
 

On 8/13/18 6:55 PM, Andy Lee via Groups.Io wrote:
On Aug 13, 2018, at 9:05 PM, James Walker <list2@...> wrote:
By the way, there are other menu items, implemented in the app delegate, that are enabled while the dialog is running.  Seems like there's something special about the Quit item.  Maybe that's related to the fact that Quit isn't in the menu nib, but gets added magically.
I got curious and created a scratch app to fiddle with.  I called [NSApp runModalForWindow:] and was surprised to see that even though the dialog was demonstrably modal (clicking on the window behind it caused a beep), the Quit menu item was enabled.  I'll send you my mini-project off-list in case it helps.

Thanks, that did help.  I think the root of the problem is that my app is not totally a normal Cocoa app.  I am in the process of converting a complex app from Carbon to Cocoa, and though I no longer have any Carbon windows, the overall structure and event handling is still somewhat Carbonated.