Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/content/docs/reference/cua-driver/mcp-tools.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ Force-terminate a process by pid (kill -9 equivalent on macOS / Linux; taskkill

### `bring_to_front`

Persistently activate an app so it genuinely holds macOS foreground, then leave it there. Most input does NOT need this — every macOS dispatch reaches backgrounded windows, and `dispatch:"foreground"` does its own brief front→act→restore. Reach for `bring_to_front` only for a focus-proxy surface that re-arms its own input channel on activation and must stay frontmost across the interaction — chiefly a remote-desktop client (Microsoft Windows App / RDP), where the brief flash drops keystrokes. Fronts the exact macOS window through WindowServer when `window_id` is present, with app-level Cocoa activation as a fallback. This DOES steal foreground — explicit opt-in, never used by the input ladder.
Persistently activate an app so it genuinely holds macOS foreground, then leave it there. Most input does NOT need this — every macOS dispatch reaches backgrounded windows, and `delivery_mode:"foreground"` does its own brief front→act→restore. Reach for `bring_to_front` only for a focus-proxy surface that re-arms its own input channel on activation and must stay frontmost across the interaction — chiefly a remote-desktop client (Microsoft Windows App / RDP), where the brief flash drops keystrokes. Fronts the exact macOS window through WindowServer when `window_id` is present, with app-level Cocoa activation as a fallback. This DOES steal foreground — explicit opt-in, never used by the input ladder.

**Arguments:**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ fn harness_winui3_xaml_popup_open() {
/// Regression guard for the click → TogglePattern dispatch fix.
/// cua-driver `click` now tries Invoke → Toggle → SelectionItem →
/// ExpandCollapse before falling through to PostMessage, so WinUI3
/// CheckBox toggles correctly via UIA without needing dispatch:foreground.
/// CheckBox toggles correctly via UIA without needing delivery_mode:foreground.
#[test]
#[ignore]
fn harness_winui3_checkbox_toggle() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
//! sandbox runner unignores them explicitly via the `--ignored` arg.
//!
//! **Foreground-lock caveat:** a handful of these tests (`double_click`,
//! `right_click`, `type_text`) rely on `dispatch:"foreground"` to reach
//! `right_click`, `type_text`) rely on `delivery_mode:"foreground"` to reach
//! WPF's input chain reliably. Windows' system-wide foreground-lock
//! kicks in after ~30s with no real user input — once that happens,
//! `SetForegroundWindow` is denied for non-UIAccess processes and the
Expand Down Expand Up @@ -95,7 +95,7 @@ fn launch_harness_with_state_file(
// wait happens via polling in find_window. A 200ms-only
// wait turned out to be too short for the harness to establish
// foreground reliably under test-batch load, which caused
// SetForegroundWindow-needing tests (dispatch:foreground) to
// SetForegroundWindow-needing tests (delivery_mode:foreground) to
// fail with a foreground-lock rejection.
std::thread::sleep(Duration::from_millis(800));
Some(pid)
Expand Down Expand Up @@ -535,7 +535,7 @@ fn harness_wpf_type_text() {
// WPF's TextBox needs *keyboard focus* for WM_CHAR delivery — and
// PostMessage(WM_LBUTTONDOWN) doesn't reliably transfer keyboard
// focus (WPF's input system treats posted events differently from
// real ones). Use dispatch:"foreground" → SendInput synthesizes
// real ones). Use delivery_mode:"foreground" → SendInput synthesizes
// an OS-level click that WPF treats identically to a user mouse,
// landing actual keyboard focus on the TextBox.
let _ = driver.call(
Expand Down Expand Up @@ -666,7 +666,7 @@ fn harness_wpf_right_click() {
let snap = snapshot(driver, pid, wid);
let idx = ax::element_index_by_id(snap.text(), "border-click-target")
.expect("border-click-target not in snapshot");
// Same dispatch:foreground rationale as type_text — PostMessage
// Same delivery_mode:foreground rationale as type_text — PostMessage
// WM_RBUTTONDOWN doesn't always reach WPF's MouseRightButtonDown
// routed-event chain (intermittent in batch runs).
let resp = driver.call(
Expand Down Expand Up @@ -709,7 +709,7 @@ fn harness_wpf_double_click() {
let snap = snapshot(driver, pid, wid);
let idx = ax::element_index_by_id(snap.text(), "border-click-target")
.expect("border-click-target not in snapshot");
// dispatch:foreground for the same reason as right_click —
// delivery_mode:foreground for the same reason as right_click —
// PostMessage WM_LBUTTONDOWN ×2 doesn't always reach WPF's
// MouseDoubleClick / ClickCount=2 path under test-batch load.
let resp = driver.call(
Expand Down Expand Up @@ -1144,7 +1144,7 @@ fn harness_wpf_slider_drag() {
// Regression guard for the SendInput drag path. PostMessage drag
// doesn't update GetKeyState, so WPF's Thumb-drag handler (which
// polls Mouse.LeftButton via GetKeyState) never sees the button
// held — the thumb stays put. dispatch:"foreground" routes through
// held — the thumb stays put. delivery_mode:"foreground" routes through
// send_drag_synthesized which goes via the system input queue and
// DOES update GetKeyState, so the thumb actually tracks.
//
Expand Down Expand Up @@ -1323,7 +1323,7 @@ fn harness_wpf_checkbox_toggle() {
// CheckBox exposes UIA TogglePattern (actions=[toggle]), not Invoke.
// cua-driver's click tool tries UIA Invoke first; for elements that
// don't support it the PostMessage fallback path runs. Use
// dispatch:"foreground" to land a SendInput click that WPF
// delivery_mode:"foreground" to land a SendInput click that WPF
// recognises as a real user click and processes through Toggle.
let resp = driver.call(
"click",
Expand Down Expand Up @@ -1363,7 +1363,7 @@ fn harness_wpf_radio_select() {
let snap = snapshot(driver, pid, wid);
let idx = ax::element_index_by_id(snap.text(), "rdo-high").expect("rdo-high missing");
// RadioButton exposes SelectionItem pattern (actions=[select]).
// Same dispatch:foreground rationale as the checkbox test.
// Same delivery_mode:foreground rationale as the checkbox test.
let response = driver.call(
"click",
serde_json::json!({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! swap before driving a focus-proxy target — a window that only accepts input
//! while its host app genuinely holds activation. The macOS input rungs never
//! need this internally: every `CGEvent.postToPid` dispatch reaches a
//! backgrounded window, and the `dispatch:"foreground"` rung does its own
//! backgrounded window, and the `delivery_mode:"foreground"` rung does its own
//! sub-millisecond front→act→restore flash. The one surface that flash can't
//! satisfy is a remote-desktop client (e.g. Microsoft's Windows App / RDP),
//! which re-establishes its keyboard channel with the remote host *on
Expand Down Expand Up @@ -35,7 +35,7 @@ fn def() -> &'static ToolDef {
name: "bring_to_front".into(),
description: "Persistently activate an app so it genuinely holds macOS foreground, \
then leave it there. Most input does NOT need this — every macOS \
dispatch reaches backgrounded windows, and `dispatch:\"foreground\"` \
dispatch reaches backgrounded windows, and `delivery_mode:\"foreground\"` \
does its own brief front→act→restore. Reach for `bring_to_front` only \
for a focus-proxy surface that re-arms its own input channel on \
activation and must stay frontmost across the interaction — chiefly a \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ pub fn would_be_silently_dropped(hwnd: u64, kind: EventKind) -> bool {
// clicks, drawing-area widgets accept them. We cannot distinguish
// at the HWND level (single HWND for the whole GTK window) so we
// flag mouse clicks broadly. Canvas-style drag works in practice;
// caller can still opt to retry with dispatch:"background" on the
// caller can still opt to retry with delivery_mode:"background" on the
// drag path if the click error wasn't actually load-bearing.
return matches!(kind, MouseClick);
}
Expand All @@ -200,7 +200,7 @@ pub fn would_be_silently_dropped(hwnd: u64, kind: EventKind) -> bool {
// Alt+F4) silently fail. Plain WM_CHAR text input through the
// document widgets still works (verified end-to-end against
// Writer's main editing area). Flag the keystroke-class events
// so dispatch:"background" surfaces a structured error instead
// so delivery_mode:"background" surfaces a structured error instead
// of pretending to succeed.
return matches!(kind, Keystroke | KeyCombo);
}
Expand Down Expand Up @@ -323,7 +323,7 @@ pub fn read_class_name(hwnd: u64) -> String {
}

/// Build the structured `background_unavailable` error returned when
/// `dispatch:"background"` would silently drop.
/// `delivery_mode:"background"` would silently drop.
pub fn background_unavailable_error(
hwnd: u64,
kind: EventKind,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ unsafe fn walk_tree_unsafe(
// The diagnostic tells callers exactly how to drive the SAL
// dialog without the tree: pixel click off the screenshot
// get_window_state always returns, or press_key with
// dispatch:"foreground" for accelerator-style dismissal. That's enough for the
// delivery_mode:"foreground" for accelerator-style dismissal. That's enough for the
// common modal-dismissal case (Yes/No/Esc on a Confirmation),
// which is what SAL dialogs almost always need.
let is_sal = {
Expand Down
Loading