small notes on enabling of menus in a modal window

  • The enabling of menus when a modal window is active can cause confusion and
    is not well explained in the documentation.

    * If a menu item is nil-targeted, we climb the responder chain looking for a
    class that responds to the menu item's action method. If we do not find it,
    the menu item is disabled. If we do find it, we look to see if that class
    responds to validateMenuItem:. If it does not, the menu item is enabled, and
    the story ends. If it does, then validateMenuItem: is called and the menu
    item is enabled or disabled accordingly. Thus it becomes a matter of
    understanding and designing the responder chain accordingly. For example,
    the modal window's delegate is in the chain, so this could be a good place
    to respond to the menu item's action method.

    Unfortunately the responder chain is not fully and correctly documented
    anywhere. For example, AboutRespChain.html fails to mention that a window's
    NSWindowController is part of the chain. As far as I can tell, this
    important fact is mentioned only in the obscure document
    releasenotes/Cocoa/AppKitOlderNotes.html and has never been incorporated
    into the main documentation. Hillegass includes the NSWindowController in
    the chain but with a false proviso that the app should be document-based.

    * Alternatively, a menu item can have a specific non-nil target. In this
    case the only place we look is in that target. If it doesn't implement the
    action method, the menu item is disabled. If it does, then we look to see if
    validateMenuItem: is implemented and the rules are as before.

    However, this does not work when the frontmost window is modal. There are
    various workarounds, but the simplest is to implement worksWhenModal in the
    target class. The problem and the solution are undocumented; I learned about
    this use of worksWhenModal in a note from Sascha Matzke:

    <http://cocoa.mamasam.com/COCOADEV/2003/01/2/54991.php>

    * A completely different kind of solution is not to use auto-enabling. This
    is appropriate only if you are in complete control of the entire menu that
    contains your menu items, because it works at the menu level (i.e. it
    affects all the menu items in a menu, at once). In this case you can turn
    off auto-enabling in the menu and the menu items will then be enabled
    permanently and in all situations, unless you explicitly disable them with
    setEnabled:. (validateMenuItem: is not invoked.)

    m.

    --
    matt neuburg, phd = <matt...>, <http://www.tidbits.com/matt/>
    A fool + a tool + an autorelease pool = cool!
    AppleScript: the Definitive Guide
    <http://www.amazon.com/exec/obidos/ASIN/0596005571/somethingsbymatt>
  • On 2004-10-07, at 19.33, Matt Neuburg wrote:

    > Unfortunately the responder chain is not fully and correctly documented
    > anywhere. For example, AboutRespChain.html fails to mention that a
    > window's
    > NSWindowController is part of the chain. As far as I can tell, this
    > important fact is mentioned only in the obscure document
    > releasenotes/Cocoa/AppKitOlderNotes.html and has never been
    > incorporated
    > into the main documentation. Hillegass includes the NSWindowController
    > in
    > the chain but with a false proviso that the app should be
    > document-based.

    So, you're saying that the window controller is included in the
    responder chain even when it is not a delegate of it's window? File a
    bug report / enhancement request on the doucmentation!

    j o a r
  • On or about 10/7/04 12:40 PM, thus spake "j o a r" <joar...>:

    > So, you're saying that the window controller is included in the
    > responder chain even when [snip]

    Yes. If I'm wrong, pls send me a counter-example. m.

    --
    matt neuburg, phd = <matt...>, http://www.tidbits.com/matt/
    pantes anthropoi tou eidenai oregontai phusei
    AppleScript: the Definitive Guide! NOW SHIPPING...! (Finally.)
    http://www.amazon.com/exec/obidos/ASIN/0596005571/somethingsbymatt
    Subscribe to TidBITS! It's free and smart. http://www.tidbits.com/
  • Op 7-okt-04 om 19:33 heeft Matt Neuburg het volgende geschreven:

    > The enabling of menus when a modal window is active can cause
    > confusion and
    > is not well explained in the documentation.
    >
    >
    > * Alternatively, a menu item can have a specific non-nil target. In
    > this
    > case the only place we look is in that target. If it doesn't implement
    > the
    > action method, the menu item is disabled. If it does, then we look to
    > see if
    > validateMenuItem: is implemented and the rules are as before.
    >
    > However, this does not work when the frontmost window is modal. There
    > are
    > various workarounds, but the simplest is to implement worksWhenModal
    > in the
    > target class. The problem and the solution are undocumented; I learned
    > about
    > this use of worksWhenModal in a note from Sascha Matzke:
    >
    > <http://cocoa.mamasam.com/COCOADEV/2003/01/2/54991.php>
    >

    That is rather brilliant. I have now resorted to connecting my items to
    First Responder and manually inserting my controller in the responder
    chain (where it really doesn't want to be). Today, in fact, after
    running into this problem again and half forgetting I'd fixed it this
    way a few weeks ago (in the same class ;-). I'll try the workswhenmodal
    route too, looks cleaner.

    Regards,

        Steven