【发布时间】:2010-11-06 09:41:38
【问题描述】:
我对 OSX 开发相当陌生,所以这可能很容易,但 google 并没有帮助。
我正在尝试将操作绑定到您在较新的 Apple 键盘上找到的媒体键(播放、暂停等)。看来您无法使用常规热键 API 绑定到这些键,但它必须是可能的,因为 iTunes 清楚地管理。是否有一些棘手的无证 API 可以实现这一目标?任何帮助将不胜感激。
【问题讨论】:
我对 OSX 开发相当陌生,所以这可能很容易,但 google 并没有帮助。
我正在尝试将操作绑定到您在较新的 Apple 键盘上找到的媒体键(播放、暂停等)。看来您无法使用常规热键 API 绑定到这些键,但它必须是可能的,因为 iTunes 清楚地管理。是否有一些棘手的无证 API 可以实现这一目标?任何帮助将不胜感激。
【问题讨论】:
经过更广泛的谷歌搜索,这个http://www.rogueamoeba.com/utm/2007/09/29/ 似乎解决了这个问题。没有简单的解决方案,但如果您正在开发一个真正的 Cocoa 应用程序,这似乎至少是可能的。
【讨论】:
根据我的调查,操作系统会在这些关键事件可供其他进程使用之前捕获它们。我创建了一个 CGEventTap,如下所示:
int main(int argc, char *argv[]) {
CFMachPortRef eventTap;
CFRunLoopSourceRef runLoopSource;
eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, kCGEventMaskForAllEvents, myCGEventCallback, NULL);
if (!eventTap) {
NSLog(@"Couldn't create event tap!");
exit(1);
}
runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);
CFRunLoopRun();
CFRelease(eventTap);
CFRelease(runLoopSource);
exit(0);
}
然后实际的事件回调是这样的:
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
if (type == kCGEventKeyUp) {
CGKeyCode keycode = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
NSLog(@"%d", keycode);
}
return event;
}
您看到记录到控制台的是功能键的正常记录方法(如果您也按住“fn”键),但是当按下媒体键、亮度、音量或弹出键时, 没有被记录。
因此,不幸的是,似乎无法捕获媒体键事件。但是,我很想被证明是错误的。
编辑:我忘了指出,要使其工作,它需要以 root 身份运行,或者您需要在“系统偏好设置”的“通用访问”窗格中打开辅助设备的访问权限。
【讨论】: