Defines an opaque type that represents a low-level hardware event.
定义一个不透明类型,代表一次底层硬件事件。
Low-level hardware events of this type are referred to as Quartz events.
这类底层硬件事件称作 Quartz 事件。
A typical event in macOS originates when the user manipulates an input device such as a mouse or a keyboard.
macOS 中一个典型的事件,起于用户操作输入设备——如鼠标或键盘。
The device driver associated with that device, through the I/O Kit, creates a low-level event, puts it in the window server's event queue, and notifies the window server.
该设备对应的驱动程序,经由 I/O Kit 造出一个底层事件,把它放进窗口服务器(window server)的事件队列,并通知窗口服务器。
The window server creates a Quartz event, annotates the event, and dispatches the event to the appropriate run-loop port of the target process.
窗口服务器据此造出一个 Quartz 事件,为它做标注(annotate),再把它派发到目标进程相应的 run-loop 端口。
There the event is picked up by the Carbon Event Manager and forwarded to the event-handling mechanism appropriate to the application environment.
事件在那里被 Carbon Event Manager 取走,转交给适合该应用环境的事件处理机制。
You can use event taps to gain access to Quartz events at several different steps in this process.
你可以用 event tap(事件截获点)在这条流程的若干不同环节上取得 Quartz 事件。
This opaque type is derived from CFType and inherits the properties that all Core Foundation types have in common.
这个不透明类型派生自 CFType,继承了所有 Core Foundation 类型共有的性质。
CGEventPost(kCGHIDEventTap, …) 把事件塞进链路开头,窗口服务器照常标注、照常派发 → 鼠标有效。CGEventPostToPid(pid, …) 直接投到目标进程的 run-loop 端口,跳过了标注 → 鼠标缺了归属信息被丢弃;而键盘事件不依赖标注(送给该进程的主窗口即可),故仍然有效。Provides features for managing event taps—filters for observing and altering the stream of low-level user input events in macOS.
提供管理 event tap 的功能——所谓 event tap,是用来观察并改动 macOS 底层用户输入事件流的过滤器。
Event taps make it possible to monitor and filter input events from several points within the system, prior to their delivery to a foreground application.
event tap 让你能在系统内部的若干点上监视并过滤输入事件——在这些事件送达前台应用之前。
Event taps complement and extend the capabilities of the Carbon event monitor mechanism, which allows an application to observe input events delivered to other processes.
event tap 补充并扩展了 Carbon 事件监视机制的能力——后者允许一个应用观察送往其他进程的输入事件。
Event taps are designed to serve as a Section 508 enabling technology.
event tap 的设计初衷,是作为一项符合「第 508 条」的无障碍使能技术。
For example, consider a software system to assist a person with language impairments, designed to perform keyboard filtering with spoken review.
举例来说,设想一套辅助语言障碍者的软件,其设计是做键盘过滤并配以语音复述。
Such a system could use an event tap to monitor all keystrokes, perform dictionary checks and matches, and recite the assembled word back to the user on detection of a word break in the input stream.
这样一套系统可以用 event tap 监视全部按键,做词典查验与匹配,并在输入流中检测到词的边界时,把拼成的词朗读回给用户。
If acceptable to the user, as indicated by an additional input keystroke or other gesture, the events would be posted into the system for delivery to the foreground application.
若用户认可(以再按一个键或其他手势表示),这些事件才会被投入系统,送往前台应用。
Introduced in OS X version 10.4, event taps provide functionality similar to the Win32 functions SetWinEventHook when used to establish an out-of-context event hook, and SendInput.
event tap 引入于 OS X 10.4,其功能类似于 Win32 的 SetWinEventHook(用于建立进程外事件钩子时)与 SendInput。
Quartz Event Services also includes an older set of event-related functions declared in the file CGRemoteOperation.h.
Quartz Event Services 里还包含一套更老的事件相关函数,声明在 CGRemoteOperation.h 文件中。
These functions are still supported, but they are not recommended for new development.
这些函数仍受支持,但不建议在新开发中使用。
CGRemoteOperation.h),那不是错的,是旧的——仍能用,但新写代码别选它。Constants that specify possible tapping points for events.
一组常量,指定事件可能的截获点。
kCGHIDEventTap — Specifies that an event tap is placed at the point where HID system events enter the window server.
kCGHIDEventTap —— 截获点设在 HID 系统事件进入窗口服务器的那一点。
kCGSessionEventTap — Specifies that an event tap is placed at the point where HID system and remote control events enter a login session.
kCGSessionEventTap —— 截获点设在 HID 系统事件与远程控制事件进入某个登录会话的那一点。
kCGAnnotatedSessionEventTap — Specifies that an event tap is placed at the point where session events have been annotated to flow to an application.
kCGAnnotatedSessionEventTap —— 截获点设在会话事件已被标注、即将流向某个应用的那一点。
In addition to the three tapping points described above, an event tap may also be placed where annotated events are delivered to a specific application.
除上述三个截获点外,还可以把 event tap 放在「已标注事件送达特定应用」之处。
postToPid 之所以对鼠标失效,正因为它不在这条链路上。Previously, I have used CGEventPost to post events to another application (Logic) which works provided it is in focus.
此前我一直用 CGEventPost 向另一个应用(Logic)投递事件,只要它处于焦点状态就能工作。
I'm actually sending events to a dialog that I've opened via OSC, which causes Logic to "bounce" in the dock indicating that the user needs to respond to the dialog.
我实际是在向一个对话框投递事件——那对话框是我经 OSC 打开的,它会让 Logic 在 Dock 里跳动,提示用户需要响应。
As I'm getting some "flashing" due to focus switching, I've tried using CGEventPostToPid to post to the application directly.
因为切换焦点造成画面闪烁,我改用 CGEventPostToPid 直接投给该应用。
The theory is that it no longer needs to be in focus, so will obviate the need for focus switching.
设想是这样它就不再需要处于焦点状态,从而省掉切换焦点这一步。
Unfortunately this doesn't work.
可惜行不通。
I still need to bring Logic into focus for the dialog to respond to the sent events.
我仍须把 Logic 切到前台,那个对话框才会响应所投的事件。
I can see that the main window of Logic has lost focus, which implies that, from its point of view the dialog has focus - I would have thought that it would respond to the background event posts.
我能看到 Logic 的主窗口已失去焦点,这说明在它看来对话框是有焦点的——我本以为它会响应后台投来的事件。
Any pointers on how to get this to work appreciated. Just wondering if I need to send events directly to the dialog window somehow?
若有让它跑通的思路,感激不尽。只是在想,我是不是得设法把事件直接投给那个对话框窗口?
Note that I'm doing this to work around a positioning bug in the OSC interface when songs have mixed time signatures.
附带一提,我做这些是为了绕开 OSC 界面的一个定位缺陷——曲子里混用多种拍号时会出问题。
CGEventPost 走正路(三档截获点全在链路上),CGEventPostToPid 抄近道直投进程。postToPid 这个函数苹果没写行为文档(无摘要、无讨论、只有一行签名),以上全靠实测与推理。