How to get the last key pressed on Mac? - objective-c

I'm writing a plugin for an application. I cannot derive from NSApplication
as it is a third party application. I can get the callback in my plugin when any key is pressed. But I will not know what key is pressed. So is there any call in Cocoa to find the last key pressed when I get the callback? I only have NSView object.
Any ideas will help me a lot.
Thanks,
Dheeraj.

A couple of thoughts:
Use [NSApp currentEvent]. I know you don't think you have an NSApplication instance, but you should try this. It might work.
Do some event monitoring in your plugin (CGEventTap, NSEvent local monitor, etc) and record whenever you see a keypress event.

Related

How to use the XCode documentation

I'd like to listen in to the text change event for an NSTextField, so I looked at the docs and saw a textDidChange event. So, I connect my text field to a delegate and implement the method, run the app, and nothing happens. I also tried textDidEndEditing, but to no avail.
What are these methods for, exactly? How can one trigger them? Changing the text and tabbing out of the field or pressing enter doesn't do anything. After a bit of googling I found a controlTextDidChange method (in the NSControl parent class of NSTextField) so I implemented it, and it worked (though it had to be an override func, not just a plain func).
Handling the text change event in .NET would be a cinch, just switch to the events panel and double click on "changed" and lo and behold, it creates a method stub into which I can handle the event.
Obviously, I'm an XCode newb comparatively. What's the typical way to go about handling events in XCode/Swift? Did I go about it the wrong way, and is there a better/easier way?
Thanks.

Does shouldReloadTableForSearchString wait a while before executing?

I am implementing search autocommplete. I am doing it without UISearchDisplayController/UISearchBar
A recurring problem is if I start doing something right after the guy press button then the program isn't "snappy".
A way around that is to use timer.
Then I've heard that UISearchController has a delegate to call.
Will that delegate solve my problem? What exactly does the delegate do? Wait a while after pressing button?
My experience is that searchDisplayController:shouldReloadTableForSearchString: is called immediately when the text in the search field changes. So that would not help with your problem.

Objective-C/Cocoa: Detect all keypresses

Is it possible to run a method every time the user presses a key. Basically I want to run a sound like on the iPhone or iPad when a key is pressed. I do not want to detect key presses in my window or in a certain control, I want to detect ALL presses (such as when they are typing in Safari or something. I do not need to know what the key is.
Thanks
Use CGEventTapCreate documented here:
https://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html
Or use NSEvents addGlobalMonitorForEventsMatchingMask:handler: documented here:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/nsevent_Class/Reference/Reference.html
NSEvent Example:
[NSEvent addGlobalMonitorForEventsMatchingMask:(NSKeyDownMask) handler:^(NSEvent *event){
[self keyWasPressedFunction: event];
//Or just put your code here
}];
I would say NSEvents are easier...
Note:
For security reasons, Apple requires you have "Enable access for assistive devices" turned on in System Preferences, in order to use ether of the above methods.
You can get pretty close with a Quartz event tap, but some keypresses aren't detectable even with one for the sake of security.
If you tell us the broader goal you have in mind, we can suggest alternatives. Are you trying to establish a global hotkey for your app? Are you writing a keylogger or malware? What?
Use NSEvents addGlobalMonitorForEventsMatchingMask:handler:
In applicationDidFinishLaunching add the following code, build & go!
[NSEvent addGlobalMonitorForEventsMatchingMask:(NSKeyDownMask) handler:^(NSEvent *event){
NSLog(#"%#", event.characters);
}];
Apple requires you have "Enable access for assistive devices" turned on in System Preferences.
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/nsevent_Class/Reference/Reference.html

-makeFirstResponder: usage

I am fairly new to cocoa programming and I would like to ask if anyone can explain me how to
-(BOOL)makeFirstResponder:(NSResponder *)responder; method works. I was planning on using it for NSEvent but can anyone show me how to implement it?
I am trying to use the NSResponder class to get me a working -keyDown method.
NSResponder is one of the fundamental classes in Cocoa. Any class that can respond to events like key presses or menu commands should be a subclass of NSResponder. Each responder keeps track of it's "next responder", and each window keeps track of the object that's currently the "first responder". When an event happens in a window, a message is sent to the first responder. If that object handles the message, great. If not, it passes it along to its next responder. This is known as the "responder chain."
Normally, you don't mess much with the responder chain in Cocoa. The first responder is mostly determined by user actions, such as clicking on a control.
It doesn't make sense to 'use it for NSEvent'. NSEvent isn't a responder, but something that enables responders to do their job.
If you describe more clearly what you're trying to accomplish, I'm sure we can point you in the right direction.
You don't usually implement -makeFirstReponder:, you call it to set the input focus to a view. What is it that you really want to achieve?
I am trying to use the NSResponder class to get me a working keyDown method.
That doesn't make sense. “Use” a class?
If you want to respond to key events, you normally should do that in a view that should be capable of becoming the first responder (see the NSView docs).
See also the Event-Handling Guide, the View Programming Guide, and the video for session 145 (“Key Event Handling in Cocoa Applications”) from the WWDC 2010 session videos (which you should be able to access through your developer account even if you didn't go to WWDC last year).

How to be notified of the Minimize button being pressed in an OSX Window?

N.B.: this relates to private (SPI) functions of the CoreGraphicServices framework.
I am currently running a CGSConnection to the Windowserver as the UniversalController (with the Dock killed), and would like to know how I can be notified that a CGSWindow has had the yellow minimize blob clicked.
Is there a notification event that I can watch for with CGSRegisterConnectionNotifyProc?
Perhaps the answer lies in HIToolbox? Any experienced CGS hackers out there have an idea?
Thank you.
CGSGetWindowEventMask or CGSGetWindowGeometry is my best guess but I've never tried my hand at it
NSWindow has this method:
- (BOOL)windowShouldZoom:(NSWindow *) toFrame:(NSRect)proposedFrame
method that you can implement.
Or maybe i don't understand your question...