【发布时间】:2012-09-14 05:17:03
【问题描述】:
我在使用 OS X 检测击键时遇到问题。每当按下键盘键时,我都需要检测按键按下和按键释放或按键向上。当使用[ NSEvent addLocalMonitorForEventsMatchingMask: handler: ] 拦截应用程序的事件处理链时,这是相当直接的。这使您可以拦截和修改NSEvents 的各种事件类型,包括用于常规打印键的NSKeyUp 和NSKeyDown,以及可用于检测移位、ctrl、alt、和 cmd 键。事实上,因为 shift、ctrl、alt 和 cmd 键的向上和向下键的修饰符标志都发生了变化,所以 NSFlagsChanged 可以通过检查 [NSEvent modifierFlags] 用作这些键的向上和向下键事件连同[NSEvent keyCode]。
但是,Capslock 是不同的。因为 capslock 修饰符实际上只对按下键起作用,所以当您按下 capslock 时,您只会得到一个 NSFlagsChanged 并按下 capslock,而不是在它被释放时。并且NSKeyUp 和NSKeyDown 不会使用诸如 capslock 和 shift 和 ctrl 等修饰键发出。
任何人都可以建议一种方法,甚至是较低级别的界面,来获取大写锁定键事件吗?我是否将不得不求助于使用 kqueue 或其他东西?
【问题讨论】:
-
我要尝试的第一件事是看看 CGEventTap 是否在此处与 NSEvent 有所不同。与大多数 Cocoa 不同,NSEvent 不仅仅是一个简单的桥接在较低级别的等价物上。此外,即使所有其他方法都失败了,您也不必一直使用 kqueue;你可以使用 IOHIDLib。 (即使没有真正学习 IOHIDLib 模型,您也可以在每个 HID 事件上触发,然后在 Cocoa 级别检查大写锁定状态……)
-
我刚刚尝试过,不幸的是,我使用 CGEventTap 得到了相同的结果 - 大写锁定是 kCGEventFlagsChanged 而不是 kCGEventKeyDown 和 kCGEventKeyUp。当然 kCGEventFlagsChanged 仅在按下大写锁定时发出,而不是释放。更糟糕的是,CGEventTap 似乎需要 root 权限或“启用辅助访问”,即使我只对自己进程中的键盘事件感兴趣。接下来我会尝试 IOHIDLib。
-
是的,如果 kCGEventFlagsChanged 没有给你发布,看起来 IOHIDLib 就是答案。查看 Xcode 附带的示例,当您遇到困难时,查看源代码 (IOHIDFamily); IIRC,当它们对我来说比文档更有用时。
-
我真的很想知道您是否找到了解决此问题的方法。
-
是的 - 查看我刚刚发布的答案。
标签: macos cocoa keyboard appkit nsevent