I want to create a global shortcut for my app. I've used the 'cool new way' of doing this with the addGlobalMonitorForEventsMatchingMask method. The problem is, my events don't get "consumed": my shortcut includes the spacebar, so whenever I use the shortcut, Quicklook pops up when I'm in the Finder.
How can I prevent this from happening? I know it's possible, because many apps, for example the Bowtie iTunes controller app, do it.
addGlobalMonitorForEventsMatchingMask: is not a suitable replacement for the existing Carbon Hotkey API for all sorts of reasons; it's horribly inefficient, for one. And from the docs:
... you can only observe the event; you cannot modify or otherwise prevent the event from being delivered to its original target application.
and
Key-related events may only be monitored if accessibility is enabled or if your application is trusted for accessibility access
The Hotkey API is still the only way to implement global shortcut in OS X. But unlike many Carbon APIs, the Hotkey API is available to 64-bit apps.
Use the hotkey API, which is meant for this purpose.
Related
I am writing a Cocoa Objective-C application for the macOS, and I am using this very good answer here to be notified of window position changes in other applications. Within my app, I can use the event returned by [NSApp currentEvent] to determine the key modifiers. How can I ascertain the same for another app that I am monitoring ? To be simple, I would like to know if a window of an application was moved or resized while pressing the command (or option) key. Many thanks for any help.
I am writing Contextual Menu Plugins for Leopard OS and referring Writing Contextual Menu Plugins for OS X, part 1 article by Brent Simmons. My plugin is working fine.
Is there any way to move my test menu into main menu (above the Label)?
The short answer is "no".
The OS controls what gets displayed in that menu, so in order to change it around, you would need to call private methods, reimplement system-level functionality, and just in general do some Very Bad Things which would be unsafe, could break at a moment's notice, and possibly work differently between even dot releases of the same OS.
Yes, it's called a system service, and was introduced in OS X 10.5. I know for a fact that many applications can do this, and Automator routines can be triggered this way because Automator itself is a system service. To see a service applicable for an application (i.e. Finder) go to the Application menu on the top bar (for lack of better name T_T), such as the Finder bolded text, and go down to Services > and it will show you all services that can be used in the app. If you need pointers on how to build this, just comment here.
EDIT: Yes, a SIMBL plugin is also considered a service, and on second read of your question, that's what you want.
how do I observe keyboard input event while the applicaion is not actived.
You'll need to create a CGEventTap using Quartz Event Services. The user must have access for assistive devices turned on, which makes sense, because that's the only legitimate reason for you to do that.
If you want to set up a hotkey, there's an API in Carbon Event Manager for that, and a Cocoa wrapper named SGHotKeysLib. Note that the Carbon Event Manager hotkey API is still supported in current, 64-bit Mac OS X.
How would I go about locking a screen like Keychain does, meaning preventing all access to Dock, menubar, desktop, etc. Basically just a black screen that I can add a password field to, for the user to return to the desktop? I am well aware of the Carbon method, but I want the NSApplication method because this is an all Cocoa application.
Thanks~
If you can get away with not writing this code yourself, all for the better. It is usually a terrible idea to write your own code to lock the screen, considering the number of vulnerabilities that have been found in screen locking code over the years. If you have a Carbon call that can do it, go ahead and use that... don't worry about the "purity" of your Cocoa code.
However, if you decide to write this yourself, here's what you do:
First, capture all the screens using CoreGraphics. See: http://developer.apple.com/mac/library/documentation/GraphicsImaging/Conceptual/QuartzDisplayServicesConceptual/Articles/DisplayCapture.html
Next, create a new NSWindow and put it in front of the window that's used for capturing the screens. You'll have to call a CG function to get the "order" of the black window covering each screen, and order the new window in front of that. Normally, the black window has an order so far forward that everything is behind it. Put a password field in the window. Do NOT use an ordinary text field or write your own code for password input. The password input field has a ton of special code in it so you can't copy text out of it, and other programs can't listen to keystrokes while you're typing into a password field. So use the one that Apple provides.
Last, put the computer in "kiosk mode". This mode allows you to disable alt-tab, user switching, the menubar and dock, and even the ability to force quit. See: http://developer.apple.com/mac/library/technotes/KioskMode/Introduction/Introduction.html
It's not a lot of code, it just uses a few different APIs so you'll spend most of your time bouncing between API docs. I suggest writing the screen lock code as its own application (just add a new application target to your Xcode project) and then put the screen locker inside your application bundle. This used to be (as of 10.4) how Apple Remote Desktop implemented the "Lock Screen" functionality, but I can't find the app anymore.
I believe the Cocoa replacement to the SetSystemUIMode API was not introduced until 10.6.
If you can live with Snow-Leopard-only code, the answer is - setPresentationOptions: on NSApplication.
Is it possible to assign a global hotkey to a specific feature in an Adobe AIR app, i.e. the app feature responds to the hotkey whether the app is active or not (it must be running of course, but only in the system tray).
I don't this it's possible with Adobe AIR itself. The only method I can think of:
Install 3rd party hotkey application (like AutoHotkey or HotKeyBind)
Configure hotkey application to make CTRL+ALT+Q to launch
"c:\programs\thvo42\coolapp.exe --hotkey q"
In your AIR application, register for the NativeApplication.invoke event, and watch for arguments like '--hotkey q' to know that the Q hotkey was pressed, and then act accordingly.
Of course, this is kind of a hassle, maybe with some hacking you can roll it all into a single install file.
From the Reference Manual:
To listen globally for key events, listen on the Stage for the capture and target or bubble phase.
SWFKit creates a wrapper around your flash/flex movie, and allows access to system DLLs and other goodies, but unfortunately it would export as an .exe, so windows only and no AIR.
ASFAIK, there is no support for it by using AIR alone.