cmd + period(.) does not work as expected - cocoa

I develop an application on Mac using cocoa. I need to handle cmd + period(.) keyboard event as a command I designed. But now the cmd + period(.) keyboard event does not well handled as I expected.
In the cocoa keyEvent handle process, if the application object processes a key event and it turns out not to be a key equivalent or a key interface control event, it then sends it to the key window in a sendEvent: message. The window object invokes the keyDown: method in the first responder. My handle for cmd + period(.) is in keyDown: method.
But the problem is that Mac treates cmd + period(.) key the same as Escape key. The key window first searches the view hierarchy for a view whose key equivalent is Escape or Command-., whichever was entered. But none of these views handles the key equivalent, then a cancel: action message is sent to the first responder in the responder chain.
So cmd + period(.) is handled as a cancel operation before it reaches keyDown: method.
Can anyone have some idea to solve this problem. And make the cmd + period(.) be handled as I expected but as cancel command. Thank you.
What is more, it is better not handle the cmd + period(.) when do the key equivalent check(performkeyEquivalent).

If you want to override the default handling, you need to catch the keyboard event earlier in the chain. For example, subclass NSWindow and override -sendEvent, or even more thorough, subclass NSApplication and override -nextEventMatchingMask (all events will pass through this function).

Related

Catch Capslock press in Cocoa application

I’m working on an application that uses the great MASShortcut repository by Shpakovski. I reference this to ask if there is a way to register a shortcut for Capslock in the same way that Shpakovski does in his repository?
It seems that I can’t register 0xffff (Key Codes shows this as Capslock) as a valid shortcut. Even if I combine it with the modifier keys. I also want to catch the press before it toggles the system’s Capslock functionality.
I’m aware that I could listen to all keystrokes and just catch the Capslock when it occurs but I want to avoid this behaviour since I feel it’s potentially insecure and will also decrease the overall system performance.
Edit: I already took a look at some working C++ / C# libraries for Windows which implement this feature. They seem to override the system’s Capslock flag continuously which I found pretty odd. I’m basically having 2 problems here:
1. How to catch the Capslock press without having a keystroke listener all the time
2. How to do so without triggering the system’s Capslock functionality.
One possibility could be to overwrite sendEvent: in your NSApplication delegate. From Apples documentation:
You rarely invoke sendEvent: directly, although you might want to
override this method to perform some action on every event. sendEvent:
messages are sent from the main event loop (the run method).
sendEvent: is the method that dispatches events to the appropriate
responders—NSApp handles application events, the NSWindow object
indicated in the event record handles window-related events, and mouse
and key events are forwarded to the appropriate NSWindow object for
further dispatching.
You could evaluate if the current event has the modifier key pressed and act upon that.
Edit:
For background processing Quartz event taps can be used. If that leads to a rejection, I don't know.

NSResponder not receiving keyUp event when Cmd ⌘ key held down

I'm using a custom subclass of NSView and receiving keyboard events through the keyDown/keyUp methods, everything works fine except when the "Cmd ⌘" key is pressed, keyDown events are fired as normal but the keyUp event never comes.
In our case we use the arrow keys on their own to move an image left/right/up/down and if the user holds down "Cmd ⌘" while pressing left/right it will rotate the image instead. Since we get the keyDown event the image starts rotating but it never stops as keyUp never comes. Other modifiers don't have this issue (e.g. if shift, ctrl or alt are held down while another key is pressed we get the keyUp as expected). One option is to use a different modifier but it would be nice to keep it consistent with the PC version (Cmd is used as a substitute for when Ctrl is used on Windows, keeps it consistent with standard copy/paste commands etc).
Does anyone know why it does this? It feels like a bug but is probably just strange "correct behaviour", any ideas how to get around it (other than using an alternative modifier or using the likes of direct HID access).
Thanks.
You can use flagsChanged to be notified when modifier keys are down/up, see: Technical Q&A QA1519
Detecting the Caps Lock Key which is applicable to other modifier keys. See Carbon/Frameworks/HIToolbox/Events.h for more modifier key codes.
- (void)flagsChanged:(NSEvent *)event
{
if (event.keyCode == 0x37) { // kVK_Command
if (event.modifierFlags & NSCommandKeyMask) {
NSLog(#"Command key is down");
} else {
NSLog(#"Command key is up");
}
}
}

how to get Apple "command button" key code programmatically?

i need to know what key code of Command button in mac keyboard, do somebody know how to get it programmatically?
can i get the key code if user tap button Command + X (cut shortcut)? thank you for the suggestion
I'm going to assume here that you're dealing with NSEvents generated by the AppKit framework.
In NSEvent's documentation, take a look at the modifierFlags method.
And the flag you're lookng for is specifically the NSCommandKeyMask.
Now, to get it, if you have a NSView view in focus... it inherits from NSResponder. One of the methods in NSResponder is keyDown. So add a keyDown method to your subclassed view and the parameter it takes is a NSEvent. And that is how you would get your command button key.
BTW & FYI, if you just want to get the command key by itself (which is what I suspect), that's a bigger trick and I'm not sure if it's possible with AppKit. Because the command key, like the control and shift keys, are modifier keys and that means when events get generated, NSEvent is expecting two keys to be pressed at the same time (e.g. Command + Q for Quit, Control + C for interrupt, Shift + A for capital A).

Can not detect ESC key in Cocoa Application?

I use onKeyDown in a Custom NSView in detect keydown events, it works well when I input the normal keys, like "a, b, c", but it does not invoke onkeydown function when I press ESC, I want to exit my application when user press ESC.
How to do that?
OK, it turns out my keyboard is broken, only for ESC key, I changed with a keyboard, it works now. Thank you anyway.
I just dropped in a KeyDown handler into a custom NSView in one of my test apps and the ESC key is hitting KeyDown perfectly fine.
Seems like something to do with the way you're calling KeyDown, I think? Maybe the focus isn't set correctly.
In any event, another thing you can do is to implement cancelOperation: in your custom NSView.
Here is the documentation for [NSResponder cancelOperation:]. This also responds to the Escape key and to the Macintosh standard Command + . key combination.
Also check out the Handling Key Events section of the Cocoa Event-Handling Guide, which is where I was looking for answers for you. Hope this helps!

VB6 Subclassing: How to detect [ALT] + mouse left click in window title/caption bar

I need to subclass a VB6 form so that if the user hits the [ALT] key while left clicking the title/caption bar, I can do something custom (show dialog box, file io, whatever).
So far, I have been able to do the subclassing in my NewWndProc() to correctly trap the WM_NCLBUTTONDOWN message when wParam = HTCAPTION, but I don't know how to trap the [ALT] key at the same time.
I have used the SPY utility a bit to check for messages, but I still can't solve this. Thanks for any help.
Update:
Looks like I may have to use mouse and keyboard hooks?
As it's not sent as part of the message. but you can call GetKeyState(VK_MENU) to get whether it's pressed or not.

Resources