Find out from which control a popup menu is triggered - macos

I have a series of NSButtons on a window, whose menu property is connected to a common NSMenu in the storyboard. In the action method triggered by that menu's item(s), I would like to find out which button was right-clicked to open the menu. How can I do that?
The event ([[NSApplication sharedApplication] currentEvent]) does not seem to contain that information.

Related

Performing an action when _statusItem is clicked, with a NSMenu and the window not in focus seems impossible

There are similar questions on SO but this have a twist.
I need to trigger an action when the user clicks on my app icon sitting on the menu bar. The action is to bring its window to the front, or in other words,
[[[NSApplication sharedApplication] keyWindow] makeKeyAndOrderFront:self];
Normally I would do this:
[_statusItem setTarget:self];
[_statusItem setAction:#selector(bringToFront:)];
but this _statusItem has a NSMenu.
If I disable the menu, bringToFront: is triggered.
So I thought, I will implement NSMenuDelegate method menuWillOpen.
- (void)menuWillOpen:(NSMenu *)menu {
[[[NSApplication sharedApplication] keyWindow] makeKeyAndOrderFront:self];
}
But there is a problem. This will work if the app window is the one selected, but suppose the app is running and I select safari. Then, my app's window is not in focus anymore, is behind 2000 Safari windows. Now I click on my app's icon on the menu bar and menuWillOpen will not be triggered.
If I want to bring the window to focus by clicking on the app's icon on the menu bar, having to bring the window to focus to make it work does not make sense.
NSApplication notifications are posted in response to your app gaining/resigning active status. Handle these notifications and enable/disable your status item's menu so that your action gets invoked when your app is in the background.

OS X Application Keyboard Shortcuts

I am making my first OS X application in Xcode, and I have no idea how to make a specified keyboard shortcut trigger some code (e.g. ⌘ Cmd+ C/⌘ Cmd+V). All I can find online is keyboard shortcuts in Xcode itself.
Thanks in advance
This is usually setup for you automatically. The MainMenu.xib by default has an Edit menu with these shortcuts bound, activating [firstResponder copy:] and [firstResponder paste:]. The first responder is item currently having keyboard focus, or it's parent view if it doesn't answer to those actions, up to the window at the top level.
For new shortcuts, Apple recommends that you have menu items associated to all those. If you do, you can set the shortcut in the interface builder using the attributes inspector. You then ctrl-drag from the menu item to the object you want to send the action to, e.g. the app delegate. You will have to create the target method first obviously. You should also use bindings to control when the menu item is enabled or not.
It's not recommended, but if you want to do this programmatically, without a menu item, you override the
- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
method of the view or window in question. It will be called if it's in the responder chain when the key is pressed, and you return YES to indicate you've handled the event.

How can I get to the menu bar in my app in interface builder

XCode works in mysterious ways (at least to me).
I simply want to create a Preference pane in my app. When I run my app, the stock menu bar comes up (Apple, MyApp, File, Edit...) and the "Preferences" menu item is grayed out. It makes sense since I haven't started playing with it.
How on earth do I add/remove/activate/inactivate menu items? I'm not talking about adding anything new, simply using what should be there.
Thanks in advance.
NSMenu has "Auto Enable Items" enabled by default. That means if the menu item does not have it's action message hooked up, it will appear grayed out. So in your case, you would simply set the Preferences menu item's "Sent Action" to whatever action shows your preferences window. This can be hooked to some sort of showPreferencesWindow: method of your AppDelegate, or directly to the showWindow: method of a window controller.
To dynamically enable/disable menu items the best way is to implement the NSUserInterfaceItemValidation protocol which is excellently documented here
Edit: Your app's menu bar items live in the MainMenu.xib file. The menu bar appears as a "Main Menu" object on the left hand side (if you're using Xcode 4) Simply click on the items to modify them, and you can Ctrl+drag connections to and from them like any UI object.

How to make action to close NSPopover?

Hi I implemented an NSPopover in one of my apps, but the popover will not close. I'm guessing that it should close once I click something else, but its not. I know that there's a close popover action but that only works for a different button. How can I make it look to see that the popover is open and when it is open to close the popover when I press the same button?
I solved the problem!
First go ahead and click your .xib file.
Where you see the first responder box and files owner - click on the popover.
On the sidebar go to the attributes center
Change the behavior from Application-Defined to Transient and it should work!
That should make the popover disappear once someone has clicked outside the popover.
Another way to close the popover is to have a separate button.
Just add another NSButton and then link it to the popover on the sidebar and set it to Received actions -> perform close:

Menu item doesn't show when creating menu in Interface Builder

In interface builder I added a menu item to the main menu. I can click on the menu and access its contents, however the title of the menu item doesn't show when running the program.
The image shows the application and its menu on top and on the bottom is the application as it appears in IB. Notice that where the menu in IB has the "Calculate" menu option, the running application has in its menu a space instead.
In the menu bar, there is an NSMenuItem which contains an NSMenu. Both have a "Title" property. In Interface Builder, what you see in the menu bar is the title of the NSMenuItem. In the application, what you see is the title of the NSMenu. If the NSMenu's title is not set, then you'll just see an empty string, which is what you've shown in your screenshot.
Click on the Menu item in Interface Builder so that the attached menu shows up. You can then set the title.
Note that in Interface Builder, if you drag a Menu Item to the menu bar, you get an NSMenuItem without any NSMenu attached. I suspect that's what you've done. You can drag a Menu on top of the NSMenuItem to add a menu to it, and then you can set the menu's title correctly. If instead of dragging a Menu Item, however, you drag a Submenu Item, then the attached NSMenu is already present, and it automatically updates the title when you change the text in the menu bar.

Resources