Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get keyboard events in an NSStatusWindowLevel window while my application is not frontmost?

Tags:

macos

cocoa

After creating a translucent window (based on example code by Matt Gemmell) I want to get keyboard events in this window. It seems that there are only keyboard events when my application is the active application while I want keyboard events even when my application isn't active but the window is visible.

Basically I want behavior like that provided by the Quicksilver application (by blacktree).

Does anybody have any hints on how to do this?

like image 649
Kristof Van Landschoot Avatar asked Oct 14 '22 17:10

Kristof Van Landschoot


2 Answers

There are two options:

  1. Use GetEventMonitorTarget() with a tacked-on Carbon run loop to grab keyboard events. Sample code is available on this page at CocoaDev.

  2. Register an event trap with CGEventTapCreate. Sample code can be found in this thread from the Apple developer mailing list.

Edit: Note that these methods only work if you check off “Enable access for assistive devices” in the Universal Access preference pane.

like image 96
e.James Avatar answered Oct 20 '22 17:10

e.James


A simpler route that may work better for you is to make your app background-only. The discussion on CocoaDev of the LSUIElement plist key explains how to set it up. Basically, your application will not appear in the dock or the app switcher, and will not replace the current application's menu bar when activated. From a user perspective it's never the 'active' application, but any windows you open can get activated and respond to events normally. The only caveat is that you'll never get to show your menu bar, so you'll probably have to set up an NSStatusItem (one of those icon menus that show up on the right side of the menu bar) to control (i.e. quit, bring up prefs, etc.) your application.

Edit: I completely forgot about the Non-Activating Panel checkbox in Interface Builder. You need to use an NSPanel instead of an NSWindow to get this choice. This setting lets your panel accept clicks and keyboard input without activating your application. I'm betting that some mix of this setting and the Carbon Hot Keys API is what QuickSilver is using for their UI.

like image 35
Boaz Stuller Avatar answered Oct 20 '22 16:10

Boaz Stuller