2012-07-05 2 views
2

그래서 Mac OS X 10.7로 내부 도우미 응용 프로그램을 이식해야합니다.Mac OS X 용 시스템 전체 단축키

플랫폼 의존적 인 코드가 아무리해도 최소한으로 작동하지만 하나의 응용 프로그램이 작동하려면 시스템 전체 단축키 (예 : RegisterHotkey 기능)가 필요하며 Mac에서이 작업을 수행하는 방법에 대한 문서를 찾을 수 없습니다. .

이 프로그램은 Python 3.2에서 PyQt gui를 사용하고 있습니다. 창문에 해당하는 코드가 기본적으로 : 다음

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

및 핫키 이벤트받을 : 나는 파이썬의 변형이 필요하지 않습니다

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

주, 난 쉽게 간단한 C의 확장을 쓸 수 있습니다 - 그래서 C/objective-c 솔루션도 환영합니다.

답변

8

나는 최근에 extension에서 quodlibet까지 인코딩하여 멀티미디어 키를 캡처합니다 (quodlibet 자체에 흡수되기 때문에). 귀하의 설정에 대해 동일한 프로세스가 적용됩니다.

나는 이것을 달성하기 위해 Quartz CGEventTapCreate hook과 이벤트 루프와 Cocoa AppKit 프레임 워크를 사용하여 키 코드를 해독했다.

다음 코드는 글로벌 키 누름을 통과 파이썬 콜백을 등록하고, 이벤트 루프를 시작한다 : I는 시스템 정의 키만 (미디어 키)를위한 탭 정의

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() 

; 다른 이벤트 마스크 ( CGEventMaskBit과 하나 이상의 Event Types)를 지정해야합니다. 예 : 키 업 이벤트의 경우 Quartz.CGEventMaskBit(Quartz.kCGEventKeyUp)

콜백 그것은 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는 NSEvent에 석영 이벤트를 변환.

원칙적으로 AppKit API에서도 동일한 작업을 수행 할 수 있지만 Python 애플리케이션은 Mac 애플리케이션 (아이콘이있는 Dock에서 볼 수 있음)으로 처리되지만, 배경 모두.

+0

감사합니다. 정확하게 필요한 것 같습니다. pyobjc를 Python3 용으로 컴파일하려고했는데, 코드 실행시'AttributeError : 'module'객체에 'CGEventTapCreate'속성이 없다고 알려줍니다. pyobjc는 python3과 함께 작동해야하므로, 뭔가 빠졌거나 완전히 포팅되지 않은 API입니까? – Voo

+0

@Voo : 죄송합니다, 아무 생각이 없습니다. Python 2.7 및 pyobjc에서만 작업했습니다. –

+2

아침에 문제를 조금 디버그하여 해결했습니다. 테이크 아웃은 다음과 같습니다. python3 및 pyobjc는 실제로 권장되지 않지만 작동하도록 만들 수 있습니다. 그리고 그것은 코코아 프레임 워크를 배우거나 python2로 앱을 다시 포팅하는 것보다 확실히 효과가 없었습니다. 도움을 다시 한번 주셔서 감사합니다. – Voo

1

구글의 힘을 사용하여, 나는 맥 OS X

목적을 통과 할 때 ARCCarbon 프레임 워크, 그리고 아마도 브리지 캐스트를 추가해야 글로벌 단축키의 등록을 허용 this snippet of code를 발견 -C C 함수에 대한 자체 포인터. 키 코드가 on this page explaining the virtual key codes를 볼 수 있습니다

#import <Carbon/Carbon.h> 

:에 최소한

은 또한 필요합니다.