On 20 Oct 2013, at 01:15 am, Kyle Sluder <k...@ksluder.com> wrote:

> Rather than rely on intercepting responder chain-based validation, wouldn't 
> it be much easier and more reliable to make some object the delegate of all 
> of your NSMenus and implement -menuNeedsUpdate:?
> 

But wouldn’t this object then need to know details about the different windows 
which are presented in the app in order to decide which shortcut key to set? I 
have the feeling that the tabbed window (or its delegate) is the place to make 
changes to the default menu configuration. I think I will try updating the menu 
in the windowDidBecomeKey/windowDidResignKey calls of the window’s delegate. 
The thing I don’t like about this is that the delegate (my document subclass) 
now needs to have a link to the menu items which are created in the main menu 
nib. I could try ’scanning' for the relevant menu items, maybe searching by 
tag. Let’s see how far I get with that.

Thanks!

Martin


> --Kyle Sluder
> 
>> On Oct 19, 2013, at 1:28 PM, Andy Lee <ag...@mac.com> wrote:
>> 
>> Uli and I both remembered the app delegate is checked *after* the 
>> window-related objects in the responder chain, which is what you discovered.
>> 
>> I *thought* you could work around this by changing the actions of the Close 
>> menu items to methods that only the app delegate implements.  But you really 
>> don't want to do that, because it'll break any parts of the built-in menu 
>> validation that assume performClose: is the action for closing windows.
>> 
>> So I propose yet another solution, which may well be, again, flawed.  It 
>> does not go through validateMenuItem:.  The following may seem like a lot of 
>> explaining, but it is only a few one- or two-line methods.
>> 
>> * Have the app delegate listen for NSWindowDidBecomeMainNotification.
>> * Handle the notification by setting the menu item shortcuts appropriately 
>> for the main window.
>> 
>> There are different approaches you could take to set the shortcuts 
>> appropriately for the window.  One way would be to add two category methods 
>> on NSWindow, something like
>> 
>> + (void)updateShortcutForCloseMenuItem:(NSMenuItem *)menuItem
>> {
>>   [menuItem setKeyEquivalent:@"w"];
>> }
>> 
>> + (void)updateShortcutForCloseTabMenuItem:(NSMenuItem *)menuItem
>> {
>>   [menuItem setKeyEquivalent:@""];
>> }
>> 
>> For your window that has tabs, use an NSWindow subclass that overrides these 
>> methods:
>> 
>> + (void)updateShortcutForCloseMenuItem:(NSMenuItem *)menuItem
>> {
>>   [menuItem setKeyEquivalent:@"W"];
>> }
>> 
>> + (void)updateShortcutForCloseTabMenuItem:(NSMenuItem *)menuItem
>> {
>>   [menuItem setKeyEquivalent:@"w"];
>> }
>> 
>> Your app delegate could have outlets to the two menu items in question.  
>> Then your notification-handling method can be:
>> 
>> - (void)handleWindowDidBecomeMainNotification:(NSNotification *)notif
>> {
>>   [[[NSApp mainWindow] class] updateShortcutForCloseMenuItem:_closeMenuItem];
>>   [[[NSApp mainWindow] class] 
>> updateShortcutForCloseTabMenuItem:_closeTabMenuItem];
>> }
>> 
>> I think the only case this does not handle is when the very last window is 
>> closed.  You may or may not care what the shortcuts are, since the menu 
>> items will be dimmed.  If you do care, you can:
>> 
>> * Have the app delegate listen for NSWindowDidResignMainNotification.
>> * Handle the notification by first checking whether [NSApp mainWindow] is 
>> nil.  If so (and *only* if so, for the reason Uli pointed out), set the 
>> shortcuts to whatever you want them to be in that case.  For example, you 
>> could do this (which is why I made those "update" methods class methods):
>> 
>> - (void)handleWindowDidResignMainNotification:(NSNotification *)notif
>> {
>>   if ([NSApp mainWindow] == nil)
>>   {
>>       [NSWindow updateShortcutForCloseMenuItem:_closeMenuItem];
>>       [NSWindow updateShortcutForCloseTabMenuItem:_closeTabMenuItem];
>>   }
>> }
>> 
>> --Andy
>> 
>> 
>>> On Oct 19, 2013, at 2:32 PM, Martin Hewitson <martin.hewit...@aei.mpg.de> 
>>> wrote:
>>> 
>>> I guess I didn’t understand correctly since my app delegate does not get 
>>> asked to validate the Close menu item. So far the only thing that get’s 
>>> asked to validate this is the tabbed window object. Even the window’s 
>>> delegate is not asked.
>>> 
>>> The documentation states:
>>> 
>>> For document-based applications, the default responder chain for the main 
>>> window consists of the following responders and delegates:
>>>   • The main window’s first responder and the successive responder objects 
>>> up the view hierarchy
>>>   • The main window itself
>>>   • The window's NSWindowController object (which inherits from NSResponder)
>>>   • The main window’s delegate.
>>>   • The NSDocument object (if different from the main window’s delegate)
>>>   • The application object, NSApp
>>>   • The application object's delegate
>>>   • The application's document controller (an NSDocumentController object, 
>>> which does not inherit from NSResponder)
>>> 
>>> My NSPersistentDocument subclass is the main window’s delegate.
>>> 
>>> Clearly my thinking is flawed, but where? If I want the Close menu item to 
>>> vary depending on the window that is key, and I have to do this with 
>>> validateMenuItem:, then the responder chain above seems to suggest that I 
>>> need to have a validateMenuItem: in each and every window in the app. I 
>>> hope that’s not the case….
>>> 
>>> Martin
>>> 
>>> 
>>>> On 19 Oct 2013, at 07:28 pm, Martin Hewitson <martin.hewit...@aei.mpg.de> 
>>>> wrote:
>>>> 
>>>> OK, so the idea is,
>>>> 
>>>> + validateMenuItem in app delegate gets a first shot at setting the 
>>>> keyboard shortcuts
>>>> + I override validateMenuItem in my tabbed window and reset the keyboard 
>>>> shortcuts
>>>> + Other windows stick with the settings arranged by the app delegate
>>>> 
>>>> Did I understand correctly?
>>>> 
>>>> Thanks to all who replied.
>>>> 
>>>> Cheers,
>>>> 
>>>> Martin
>>>> 
>>>> 
>>>>> On 19, Oct, 2013, at 02:46 pm, Uli Kusterer 
>>>>> <witness.of.teacht...@gmx.net> wrote:
>>>>> 
>>>>> 
>>>>>> On 19 Oct 2013, at 14:27, Andy Lee <ag...@mac.com> wrote:
>>>>>>> On Oct 19, 2013, at 6:58 AM, Martin Hewitson 
>>>>>>> <martin.hewit...@aei.mpg.de> wrote:
>>>>>>> Main Window with tabs:
>>>>>>>   close (cmd-shift-w)
>>>>>>>   close tab (cmd-w)
>>>>>>> 
>>>>>>> All other windows:
>>>>>>>   close (cmd-w)
>>>>>>>   close tab (inactive, no keyboard shortcut)
>>>>>>> 
>>>>>>> This is pretty much the way things work in Xcode. 
>>>>>>> 
>>>>>>> So, my question is, is there a smart way to do this, or do I need to 
>>>>>>> implement -validateMenuItem: on every window in the app and set the 
>>>>>>> keyboard shortcuts there?
>>>>>> 
>>>>>> Untested idea: implement windowDidBecomeKey: and windowDidResignKey: in 
>>>>>> the delegate of the window that has tabs and do the switching of 
>>>>>> shortcuts there.
>>>>> 
>>>>> Would rather recommend against this. I don’t think there’s any guarantee 
>>>>> given what gets called first, validateMenuItem: or windowDidResignKey:. 
>>>>> You might be obliterating something already set by the incoming window. 
>>>>> 
>>>>>> If you want to be extra careful you could have two ivars that remember 
>>>>>> what the shortcuts were before you changed them to cmd-shift-w and 
>>>>>> cmd-w.  Then in windowDidResignKey: plug those shortcuts in rather than 
>>>>>> hard-code cmd-w and @“”.
>>>>> 
>>>>> Also, while I’m not aware of any localization that doesn’t use Cmd-W for 
>>>>> close, it’s in general a good idea to keep your shortcuts localizable 
>>>>> (e.g. on a German keyboard, there’s no way to type Cmd-~, because it has 
>>>>> no ~-key, so window rotation is done using Cmd-< there).
>>>>> 
>>>>> I’d recommend adding a validateMenuItem: handler in the application 
>>>>> delegate, as long as you’re aware that this won’t be called for modal 
>>>>> panels or windows that have sheets on them, but since those generally 
>>>>> don’t enable the “Close” menu item, you should be fine. At least then 
>>>>> you’re modifying the items.
>>>>> 
>>>>> Also, I’m not sure whether menu shortcut disambiguation lets you do that, 
>>>>> but have you tried hiding and showing menu items with the same names but 
>>>>> different shortcuts instead of actually changing the items’ shortcut? 
>>>>> I.e. create your menu as
>>>>> 
>>>>> Close           Cmd-Shift-W   -> -performCloseForTabbedWindow:
>>>>> Close           Cmd-W           -> -performClose:
>>>>> Close Tab    Cmd-W           -> -performCloseTab:
>>>>> Close Tab                           -> -performCloseTabDummy:
>>>>> 
>>>>> And then hide/show the “tab” items? That way, localization would be 
>>>>> easier, and you’re not hard-coding any shortcuts. Though that doesn’t 
>>>>> solve the issue of properly restoring the items after you’ve hidden them.
>>>>> 
>>>>> Cheers,
>>>>> -- Uli Kusterer
>>>>> “The Witnesses of TeachText are everywhere...”
>>>>> http://zathras.de
>>>> 





_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to