I'm interested in capturing key presses while a NSMenu is open. For example, if the menu is open and the user presses "e", or "1" on the keyboard, send a particular message (preferably passing an event object which contains reference to which key was pressed).
I've looked into alternate menus, but I'm under the impression that can only be used to capture the option key.
Currently I'm not using any custom views, just NSStatusBar (where the menu spawns from) and NSMenu.
I'm new to Objective-C so my apologies if I'm wording anything incorrectly.
Really appreciate the help!
I assume you are searching for this: Cocoa NSStatusBar Global HotKey
Related
I'm experience some event handling issues when attempting to use arrow keys without modifiers as key equivalents for menu items in the main menu bar. The problem I'm experiencing is that the main menu bar is handling the key down event as a key equivalent event before a tableView is able to. When the tableView is the first responder, the up/down arrow keys do not change the tableView's selection but rather trigger the key equivalent in the main menu bar.
The reason for this is that the incoming keyDown event for an arrow key is first passed to performKeyEquivalent on the target window, which in turns passes that event down the chain. NSTableView does not respond to this so the event bubbles back up to the application where it next dispatches it to the main menu, via performKeyEquivalent, and thus the event is consumed.
If the main menu does not have a key equivalent, then the event goes back to the window and down the chain via keyDown, which the tableView does respond to and correctly handles.
This is documented by Apple (more or less) in their Event Handling Guide.
Is there a proper way to handle key equivalents like arrow keys without modifiers such that they both appear in the menu item when it's being displayed, but are also properly consumed by any subviews that might handle them?
I've tried various tricks, but each one has numerous pros-and-cons:
NSMenu delegate
One can implement menuHasKeyEquivalent but it appears that you have to implement that for the entire main menu. While you could easily filter out the arrow keys, you also have to validate every other key equivalent, which isn't very practical.
Subclass NSApplication
You can override sendEvent: in NSApplication but the logic for keeping track of where you are in the event handling chain gets a bit hairy.
NSEvent tap
Similar to subclassing NSApplication. Things are a bit cleaner here because I can cheat and have the event tap a bit closer to the tableView, but you're still left with a lot of logic to determine when the tap should consume the event and "force-feed" it to the tableView versus when you should let the event be handled normally.
I'm curious if anyone has any suggestions on how best to implement an arrow key as a key equivalent when no modifiers are present and a tableView might be present.
(macOS 10.11+)
For example, I have an NSMenuItem type variable whose title is "History". I need a keyboard shortcut Meta+h to do the same thing as to click this menu item (pop up a submenu list)..
I think there might be two ways to implement this:
1.bind this menu item to a keyboard shortcut, then the Cocoa will fire the execute the action belongs to the item when the shortcut is fired
2.not binding keyboard shortcut to the item. Create an EventHandler for Meta+h, when the event activated, simulate a mouse click on the menu item.
However, both methods don't work for now.
For the keyboard shortcut, there is a method called setKeyEquivalent, but it uses Command instead of Meta as the modifier. And its result is executing the action binds to the menu item, instead of poping up a submenu.
For the simulating of mouse click, in Cocoa's NSMenuItem reference, I haven't see how to send event like click to a NSMenuItem..
Does anyone have ideas about this? Thanks!
[menuItem setKeyEquivalent:#" "];
[menuItem setKeyEquivalentModifierMask:0];
with any of these modifier key masks (combined using the C bitwise OR operator):
NSShiftKeyMask
NSAlternateKeyMask
NSCommandKeyMask
NSControlKeyMask
(BTW, Apple's docs can be really useful!)
Your question is slightly unclear -
If you set a shortcut Cocoa will invoke the command for you and your code will never know whether the user used the mouse or hit the key equivalent.
If you'd like to invoke the same command by some other means (key in an NSView, etc). you'd want to manually call the same method that's hooked up to your menu definition.
Is it possible to enable or show both the "return" and "done" button on the ipad keyboard? If so, How or how to work around?
I have a UITextField that is multi-line and want to add a done button to the key board.
I dont think the keyboard can display both without augmenting the layout manually - Additionally this is not app store safe.
I have done this before by hooking the
-(void)textFieldDidBeginEditing:(UITextField *)_tf
In the UITextFieldDelegate. Although there might be a better keyboard based event to use. If your interested i will post the code.
On this event, A small toolbar appeared flush with the top of the keyboard containing next, previous and Done.
I delegated the button events from the toolbar back to the ViewController that was responsible for the TextField
I am used to programming for the iPhone. There, I would connect a button to an action, and then a method by creating the method like so: -(IBAction) DoStuff{…}. Then I would make an outlet for the button, and then the actual button in Interface Builder. I would then connect the button to the outlet, and then connect the button to the action by clicking on the circle next to Touch Up Inside and drag it over to File's Owner and select my action.
I am new to programming for the Mac, so I tried to drag from performClick to the file I wanted, but it wouldn't let me make the connection. Do I have to do this programmatically or what? How do I get this button to trigger an action in my code?
The fundamental difference is that iOS controls can have multiple actions for different events, but Mac OS X controls only have one primary action (in some cases, there are others that can be set up programatically).
When you right-click on a button in a Mac nib, performClick: is under Received Actions; it’s not an event. The only entry under Sent Actions is “selector”, which is the only thing you can connect to an action on another object.
Because there is only one “sent event”, you’ll normally just control-drag/right-drag from the control to the target and select the action rather than control-clicking, selecting the event and dragging from that.
It works much the same, but unlike UIKit there is only one signature for actions:
- (IBAction)actionName:(id)sender;
See Communicating with Objects and Target/Action in Interface Builder for more.
I like to Control-Click on the button and then drag to the object that I want to recieve the action. I then select the method of possible choices from the popup menu.
My app displays an NSWindow as a sheet. The NSWindow has various controls for settings properties of an object (an NSTextfield, a NSDatepicker etc) and two NSButton's, 'Add' and 'Cancel' which are used to confirm or cancel the action.
I have set the key equivalent of the 'Add' button to enter and the key equivalent of Cancel to escape. This does not have the desired affect. I think this is due to the other controls handling the keypress events.
How do I configure my sheet so that the buttons behave as described?
The solution is to not just check your work, but to double check it!
The setup as described in the question works perfectly. (I have two similar sheets and I was using the wrong one.)