事件点击:使用 CGEventPost、kCGSessionEventTap、kCGAnnotatedSessionEventTap、CGEventTapPostEvent 改变结果
我在从事件点击发布事件时遇到了棘手的问题。 我正在 kCGHIDEventTap 中点击 NSSystemDefined,然后用新事件替换该事件。 我遇到的问题是,根据我发布事件的方式,它只能被某些应用程序看到。 我的测试应用程序是 Opera、Firefox、Quicksilver 和 Xcode。 以下是我在事件点击回调中尝试过的不同技术及其结果。 我期待每个应用程序执行一个操作(“正确响应”); “系统蜂鸣声”是指与该键无关的系统声音。
创建一个新事件,并从回调中返回它。 Opera:无响应/系统蜂鸣声,Firefox:无响应/系统蜂鸣声,Quicksilver:正确响应,Xcode:无响应/系统蜂鸣声
创建一个新事件,使用 CGEventPost 发布到 kCGSessionEventTap,返回 null。 Opera:无响应/系统蜂鸣声,Firefox:无响应/系统蜂鸣声,Quicksilver:正确响应,Xcode:无响应/系统蜂鸣声
创建一个新事件,使用 CGEventPost 发布到 kCGAnnotatedSessionEventTap,返回 null。 Opera:正确响应,Firefox:正确响应,Quicksilver:无响应/系统蜂鸣声,Xcode:无响应/系统蜂鸣声
创建一个新事件,使用 CGEventTapPostEvent 发布,返回 null。 Opera:无响应/系统蜂鸣声,Firefox:无响应/系统蜂鸣声,Quicksilver:正确响应,Xcode:无响应/系统蜂鸣声
创建一个新事件,使用 CGEventPost 发布到 kCGSessionEventTap,并返回新事件。 Opera:无响应/系统蜂鸣声,Firefox:无响应/系统蜂鸣声,Quicksilver:正确响应,Xcode:无响应/系统蜂鸣声
创建一个新事件,使用 CGEventPost 发布到 kCGAnnotatedSessionEventTap,并返回新事件。 Opera:正确响应和系统蜂鸣声,Firefox:正确响应和系统蜂鸣声,Quicksilver:正确响应和系统蜂鸣声,Xcode:无响应/双系统蜂鸣声
创建一个新事件,使用 CGEventTapPostEvent 发布,并返回新事件。 Opera:无响应/系统蜂鸣声,Firefox:无响应/系统蜂鸣声,Quicksilver:正确响应,Xcode:无响应/系统蜂鸣声
(6)是最好的,但用户抱怨正确响应时出现额外的系统蜂鸣声,我对此感到不满。我猜测是来自该事件的双重发布。 我不确定是否可以尝试其他组合,或者可以去哪里寻找。 有人可以提供任何指导吗? 有没有办法获得从我的回调返回事件并发布到带注释的水龙头的结果,而不需要同时执行这两者?
抱歉问了这么长的问题; 我已经做了很多实验。
提前致谢
更新:这是我用来创建事件点击的代码:
CFMachPortRef eventTap;
eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0,CGEventMaskBit(NX_SYSDEFINED) | (1 << kCGEventKeyDown) | (1 << kCGEventKeyUp), myCGEventCallback, (void *)hidEventQueue);
I'm running into a thorny problem with posting an event from an event tap. I'm tapping for NSSystemDefined at kCGHIDEventTap, then replacing the event with a new one. The problem I'm running in to is that depending on how I post the event, it's being seen only by some applications. My test applications are Opera, Firefox, Quicksilver, and Xcode. Here are the different techniques I've tried within my event tap callback, with results. I'm expecting an action (the "correct response") from each app; "system beep" means the nothing-is-bound-to-that-key system sound.
Create a new event, and return it from the callback.
Opera: no response/system beep, Firefox: no response/system beep, Quicksilver: correct response, Xcode: no response/system beepCreate a new event, post to kCGSessionEventTap with CGEventPost, return null.
Opera: no response/system beep, Firefox: no response/system beep, Quicksilver: correct response, Xcode: no response/system beepCreate a new event, post to kCGAnnotatedSessionEventTap with CGEventPost, return null.
Opera: correct response, Firefox: correct response, Quicksilver: no response/system beep, Xcode: no response/system beepCreate a new event, post with CGEventTapPostEvent, return null.
Opera: no response/system beep, Firefox: no response/system beep, Quicksilver: correct response, Xcode: no response/system beepCreate a new event, post to kCGSessionEventTap with CGEventPost, and return new event.
Opera: no response/system beep, Firefox: no response/system beep, Quicksilver: correct response, Xcode: no response/system beepCreate a new event, post to kCGAnnotatedSessionEventTap with CGEventPost, and return new event.
Opera: correct response and system beep, Firefox: correct response and system beep, Quicksilver: correct response and system beep, Xcode: no response/double system beepCreate a new event, post with CGEventTapPostEvent, and return new event.
Opera: no response/system beep, Firefox: no response/system beep, Quicksilver: correct response, Xcode: no response/system beep
(6) is the best, but users are complaining about the extra system beep on correct responses, which I'm guessing is coming from the double-posting of the event. I'm not sure of other combinations to try, or where else to look. Can anyone offer any guidance? Is there any way to get the results of both returning the event from my callback and posting to the annotated tap without doing both?
Sorry for the lengthy question; I've been doing a lot of experimenting.
Thanks in advance
Update: this is the code I use to create the event tap:
CFMachPortRef eventTap;
eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0,CGEventMaskBit(NX_SYSDEFINED) | (1 << kCGEventKeyDown) | (1 << kCGEventKeyUp), myCGEventCallback, (void *)hidEventQueue);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想我解决了这个问题。 我一直在使用
+[NSEvent keyEventWithType:location:modifierFlags:timestamp:windowNumber:context:characters:charactersIgnoringModifiers:isARepeat:keyCode:]
创建 NSEvent,然后返回该事件的-CGEvent< /代码>。 我切换到 CGEventCreateKeyboardEvent ,使用从原始事件创建的事件源和 CGEventCreateSourceFromEvent ,并从回调返回事件。 我所有的测试现在都通过了。
I think I fixed this. I had been using
+[NSEvent keyEventWithType:location:modifierFlags:timestamp:windowNumber:context:characters:charactersIgnoringModifiers:isARepeat:keyCode:]
to create an NSEvent, then returning that event's-CGEvent
. I switched toCGEventCreateKeyboardEvent
, using the event source created from the original event withCGEventCreateSourceFromEvent
, and returning the event from the callback. All my tests pass now.