Continuous CUA hover without cross-call ownership
CUA 连续悬停不分配跨调用所有权
Hover interactions span movement, delayed content, observation and input inside a revealed region. A request cleanup that restores the pointer, or a click that first presses outside that region, can dismiss the content even when nobody else sends input.
English
Problem
Hover interactions span movement, delayed content, observation and input inside a revealed region. A request cleanup that restores the pointer, or a click that first presses outside that region, can dismiss the content even when nobody else sends input.
Decision
App and Window expose hover for an observed AX element or an explicit coordinate target. It never presses a mouse button; disabled controls can use system-pointer movement. Completion, AX reads and screenshots do not restore a previous pointer position. Successive calls can visit intermediate points before entering a popup. Clicks deliver button events at their target without an off-window priming click. The input-routing decision selects AX alternate UI before falling back to system movement with foreground and mouse-hit checks. It never activates or raises the app implicitly. Other input or window changes can race that check.
The shared helper serializes complete individual operations. It grants no application ownership across calls. Earlier arrival, a retained app object and Session lifetime do not establish task priority. Waiting for the model does not reserve the application. Explicit task coordination determines any required execution order.
Alternatives considered
Cross-call application reservation would block other tasks throughout observation and model inference without evidence that the first task deserves priority. Continuous interaction instead relies on CUA preserving the last hover state when no further input occurs.
Click or drag as hover introduces button input that can activate a control, select text or dismiss a popup. Hover requires a separate unpressed movement operation.
PID-directed virtual movement can display Chromium hover content after prior interaction, but a fresh window can ignore it, and later pointer checks can dismiss the content. Native AppKit tracking also requires real pointer movement in the measured fixture. The system-pointer fallback avoids reporting this unreliable event route as continuous hover.
Consequences
Other input and application-driven changes can interrupt the interaction; callers observe fresh state before continuing. Dispatch does not verify that a hover delay has elapsed or a popup has appeared. The Electron fixture verifies delayed reveal, AX and screenshot preservation, entry into the popup, exactly one trusted click and dismissal on exit. The recorded Session covers hover dispatch and observed popup content; it does not substitute for native event verification.
中文
问题
悬停交互包含移动、等待内容出现、观察和在新区域内输入。如果请求清理恢复鼠标位置,或者点击先在该区域外按下鼠标,即使没有其他输入,也可能关闭浮层。
决策
App 和 Window 提供 hover,接受已观察的 AX 元素或显式坐标目标。悬停不按下鼠标按钮,禁用控件可使用系统鼠标移动路径。调用结束、AX 读取和截图不恢复先前的鼠标位置。进入浮层前可连续调用并经过中间位置。点击只在目标位置发送按键事件,不先在窗口外点击。 输入路径决定优先选择 AX 替代界面,再回退到经过前台和鼠标命中检查的系统移动,不隐式激活或抬起应用。其他输入或窗口变化仍可能与检查交错。
共享 helper串行执行完整的单次操作,不分配跨调用的应用所有权。先发起请求、持有 app 对象和 Session 寿命均不代表任务优先级。等待模型期间不占用应用。需要确定执行顺序时,由明确的任务协调决定。
考虑过的替代方案
跨调用占用应用会在观察和模型推理期间阻塞其他任务,但先开始的任务并无优先依据。连续交互依赖 CUA 在没有新输入时保留上一次悬停状态。
用点击或拖动代替悬停会引入按键输入,可能触发控件、选中文字或关闭浮层。悬停需要独立的不按键移动操作。
向 PID 定向发送虚拟移动可能在已有交互的 Chromium 窗口中显示悬停内容,但新窗口可能忽略它,后续鼠标位置检查也可能关闭内容。实测 AppKit 跟踪区域同样需要真实鼠标移动。系统鼠标回退避免把这条不可靠的事件路径当作连续悬停。
影响
其他输入和应用自身变化可能中断交互,调用方需要重新观察再继续。分派成功不代表悬停延迟已经结束或浮层已经出现。Electron fixture 验证延迟出现、AX 和截图保留悬停、进入浮层、恰好一次可信点击以及移出后关闭。Session 回放覆盖悬停分派和浮层内容观察,不代替原生事件验证。