Quick System Access for Mac OS X

Therefore, I was asked to port some internal helper applications to Mac OS X 10.7.

It works quite well, since the platform-specific code is minimal, but a functional combination (i.e. RegisterHotkey function ) is required for one application and I can not find documentation on how I will do this on a Mac.

The program uses PyQt gui with Python 3.2. and the corresponding code for windows is basically:

def register_hotkey(self): hwnd = int(self.winId()) modifiers, key = self._get_hotkey() user32.RegisterHotKey(hwnd, self._MESSAGE_ID, modifiers, key) 

and then to get hotkeys:

 def winEvent(self, msg): if msg.message == w32.WM_HOTKEY: self.handle_hotkey() return True, id(msg) return False, id(msg) 

Note that I don't need the python option, I can easily write a simple c extension, so C / objective-c solutions are also welcome.

+2
source share
2 answers

I recently coded an extension to quodlibet capturing multimedia keys (since the codlibet itself is absorbed); the same process applies to your installation.

I used the CGEventTapCreate hook quartz and the event loop and Cocoa AppKit framework to decrypt the key codes for this.

The following code registers a python callback that is passed by global keystroke and fires an event loop:

 import Quartz from AppKit import NSKeyUp, NSSystemDefined, NSEvent # Set up a tap, with type of tap, location, options and event mask tap = Quartz.CGEventTapCreate( Quartz.kCGSessionEventTap, # Session level is enough for our needs Quartz.kCGHeadInsertEventTap, # Insert wherever, we do not filter Quartz.kCGEventTapOptionListenOnly, # Listening is enough Quartz.CGEventMaskBit(NSSystemDefined), # NSSystemDefined for media keys keyboardTapCallback, None ) runLoopSource = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0) Quartz.CFRunLoopAddSource( Quartz.CFRunLoopGetCurrent(), runLoopSource, Quartz.kCFRunLoopDefaultMode ) # Enable the tap Quartz.CGEventTapEnable(tap, True) # and run! This won't return until we exit or are terminated. Quartz.CFRunLoopRun() 

I defined a tap only for system keys (media keys); you need to specify a different event mask ( CGEventMaskBit with one or more Event Types ); e.g. Quartz.CGEventMaskBit(Quartz.kCGEventKeyUp) for key events.

The callback must have the following signature (it implements the CGEventTapCallBack method from the Quartz API :

 def keyboardTapCallback(proxy, type_, event, refcon): # Convert the Quartz CGEvent into something more useful keyEvent = NSEvent.eventWithCGEvent_(event) 

I converted the Quartz event to NSEvent , because all the information I could find in the Mac multimedia keys referred to this class.

Basically, you can also achieve the same with the AppKit API, but then your Python application is seen as a Mac application (visible in the Dock with an icon and everything), while I wanted it to be saved in the background in whole.

+8
source

Using the power of google, I found this piece of code that allows you to register global hotkeys for Mac OS X

You will need to add the Carbon framework and possibly bridge translation for ARC when passing the Objective-C pointer to function C.

At a minimum, you will also need:

 #import <Carbon/Carbon.h> 

Key codes can be seen on this page, explaining virtual key codes .

+1
source

Source: https://habr.com/ru/post/987446/


All Articles