mirror of
https://github.com/lahfir/agent-desktop.git
synced 2026-08-04 13:16:06 +00:00
Settle the Playwright-grade reliability contract in agent-desktop-core before the Windows/Linux adapters are built, so they inherit it instead of redesigning it. Every command now observes, waits, verifies, and reports honestly instead of firing blindly. Highlights: capability-supertrait split of PlatformAdapter with not_supported() defaults; canonical role/state vocabulary with live `is --property visible`; display enumeration (`list-displays`) and honest `--screen` with scale factor; truthful Automation permission; `native_id` identity spine; window-id-first resolution; serializable `LocatorQuery` with live `find`; default-on auto-wait before every ref action; three-way `hit_test` occlusion gate; `scroll_into_view` in core; core accessible-name precedence; typed `ActionStep` delivery tier; `ProcessState` and `APP_UNRESPONSIVE`; `LaunchOptions`; baseline-diff desktop signals (`wait --event`); typed clipboard (`Text`/`Image`/`FileUrls`); mouse modifier chords and `mouse-wheel`. Hardened through a 35-reviewer pass with independent validation and a green live e2e gate (109/0), plus a head-vs-main performance comparison harness. BREAKING CHANGE: default-on auto-wait changes the timing of every previously-untouched ref-action call (bounded 5000 ms default; `--timeout-ms 0` restores single-shot). `ENVELOPE_VERSION` is now `2.1` (adds the `APP_UNRESPONSIVE` code and process state in error details). FFI ABI major is `3` (append-only struct evolution; `wait --event` is intentionally not exposed over FFI). The legacy string clipboard API is removed in favor of typed content. `key-down`/`key-up` fail closed until daemon-owned held input exists. `close-app` verifies termination and the osascript fallback path is removed. `--text` matching is subtree containment: `find --text X --first` returns the outermost matching container.
2465 lines
89 KiB
C
2465 lines
89 KiB
C
#ifndef AGENT_DESKTOP_H
|
|
#define AGENT_DESKTOP_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
/*
|
|
* Agent workflow — quick orientation for C/C++ binding authors:
|
|
*
|
|
* 1. (Optional) Call ad_init(AD_ABI_VERSION_MAJOR) to verify at runtime that
|
|
* the header you compiled against matches the loaded dylib. A version
|
|
* mismatch returns ErrInvalidArgs; abort rather than proceed.
|
|
*
|
|
* 2. Create an adapter:
|
|
* AdAdapter *a = ad_adapter_create(); // no session
|
|
* AdAdapter *a = ad_adapter_create_with_session(session_id); // with session
|
|
*
|
|
* 3. Observe via ad_snapshot(). The returned JSON envelope contains the
|
|
* accessibility tree with snapshot-qualified ref IDs (for example,
|
|
* "@s8f3k2p9:e5") that address
|
|
* individual interactive elements. A refmap is written under
|
|
* ~/.agent-desktop/ and is keyed to the session. The envelope carries
|
|
* data.snapshot_id. Qualified refs already pin the exact snapshot; legacy
|
|
* bare @eN refs require that ID as the snapshot_id argument.
|
|
*
|
|
* 4. Act via ad_execute_by_ref(a, "@s8f3k2p9:e5", NULL, &action, policy, &out).
|
|
* Build an AdAction by zero-initialising it and setting its kind field to
|
|
* an AD_ACTION_KIND_* constant plus any kind-specific fields (e.g. .text
|
|
* for AD_ACTION_KIND_TYPE_TEXT). policy=0 (Headless) keeps each action's
|
|
* built-in base behaviour; pass 2 (Headed) to additionally allow
|
|
* cursor/focus fallbacks. ref_id must be non-null (null returns
|
|
* ErrInvalidArgs immediately).
|
|
*
|
|
* 5. Ownership: every non-null *out string must be freed with ad_free_string().
|
|
* Destroy the adapter when done with ad_adapter_destroy(a).
|
|
*
|
|
* Calls may originate on any host thread. Native element handles remain
|
|
* thread-affine and must be used and released on the thread that resolved
|
|
* them. Desktop mutations are serialized by an interaction lease.
|
|
*/
|
|
|
|
|
|
/**
|
|
* The major ABI version of this build of `libagent_desktop_ffi`.
|
|
*
|
|
* Version-bump rule: increment this constant (and update the header via
|
|
* `scripts/update-ffi-header.sh`) whenever a breaking change is made to the
|
|
* C ABI — a removed or incompatibly-changed `ad_*` symbol, or a layout
|
|
* change to any `repr(C)` struct. Additive changes (new `ad_*` symbols, new
|
|
* error codes) do **not** require a bump. It is recommended to call `ad_init`
|
|
* with the major compiled against the header to verify ABI compatibility; a
|
|
* mismatch means the header and dylib are incompatible and the consumer should
|
|
* refuse to proceed rather than risk undefined behaviour.
|
|
*/
|
|
#define AD_ABI_VERSION_MAJOR 3
|
|
|
|
/**
|
|
* Maximum byte length (excluding the NUL terminator) accepted for any
|
|
* foreign C string. Bounds both the terminator scan and the resulting
|
|
* allocation, so a missing NUL or a hostile caller cannot walk arbitrary
|
|
* memory into a `String`. Sized to roughly match the CLI's argv ceiling so
|
|
* payload-bearing calls (clipboard-set, type) keep CLI parity rather than
|
|
* being cut off at a ref-field-sized cap. Mirrored in the header as
|
|
* `AD_MAX_STRING_BYTES`.
|
|
*/
|
|
#define AD_MAX_STRING_BYTES (1024 * 1024)
|
|
|
|
#define AD_ACTION_SIZE 96
|
|
|
|
#define AD_ACTION_RESULT_SIZE 56
|
|
|
|
#define AD_ACTION_STEP_SIZE 32
|
|
|
|
#define AD_DELIVERY_SEMANTICS_SIZE 8
|
|
|
|
#define AD_DISPLAY_INFO_VERSION 1
|
|
|
|
#define AD_DISPLAY_INFO_SIZE 64
|
|
|
|
#define AD_DRAG_PARAMS_SIZE 48
|
|
|
|
#define AD_ELEMENT_STATE_SIZE 32
|
|
|
|
#define AD_EXACT_REF_ENTRY_VERSION 1
|
|
|
|
#define AD_EXACT_REF_ENTRY_SIZE 224
|
|
|
|
#define AD_EXACT_SURFACE_INFO_VERSION 1
|
|
|
|
#define AD_EXACT_SURFACE_INFO_SIZE 40
|
|
|
|
#define AD_EXACT_WINDOW_INFO_VERSION 1
|
|
|
|
#define AD_EXACT_WINDOW_INFO_SIZE 88
|
|
|
|
#define AD_FIND_CONTROL_SIZE 24
|
|
|
|
#define AD_FIND_FILTER_SIZE 88
|
|
|
|
#define AD_FIND_IDENTITY_SIZE 40
|
|
|
|
#define AD_FIND_QUERY_VERSION 1
|
|
|
|
#define AD_FIND_QUERY_SIZE 112
|
|
|
|
#define AD_FIND_SELECTION_SIZE 8
|
|
|
|
#define AD_FIND_STATE_PREDICATE_SIZE 16
|
|
|
|
#define AD_FIND_STATE_SLICE_SIZE 16
|
|
|
|
#define AD_MODIFIER_CMD 0
|
|
|
|
#define AD_NODE_SIZE 112
|
|
|
|
#define AD_NODE_CONTENT_SIZE 48
|
|
|
|
#define AD_NODE_PRESENTATION_SIZE 48
|
|
|
|
#define AD_NODE_RELATION_SIZE 12
|
|
|
|
#define AD_NOTIFICATION_ACTION_REQUEST_SIZE 32
|
|
|
|
#define AD_NOTIFICATION_IDENTITY_SIZE 16
|
|
|
|
#define AD_OPTIONAL_U64_SIZE 16
|
|
|
|
#define AD_OPTIONAL_USIZE_SIZE 16
|
|
|
|
#define AD_REF_CAPABILITIES_SIZE 32
|
|
|
|
#define AD_REF_ENTRY_SIZE 200
|
|
|
|
/**
|
|
* Per-field input caps enforced when converting an `AdRefEntry` at the C
|
|
* boundary, sized from what real accessibility trees produce (a handful of
|
|
* states/actions, double-digit path depth) with generous headroom. Mirrored
|
|
* in the header so callers can validate before calling.
|
|
*/
|
|
#define AD_MAX_REF_STATES 64
|
|
|
|
#define AD_MAX_REF_ACTIONS 32
|
|
|
|
#define AD_MAX_REF_PATH_DEPTH 128
|
|
|
|
#define AD_REF_GEOMETRY_SIZE 48
|
|
|
|
#define AD_REF_IDENTITY_SIZE 40
|
|
|
|
#define AD_REF_PROCESS_SIZE 4
|
|
|
|
#define AD_REF_SCOPE_SIZE 32
|
|
|
|
#define AD_REF_SOURCE_SIZE 40
|
|
|
|
#define AD_STRING_SLICE_SIZE 16
|
|
|
|
/**
|
|
* Pinned size of `AdWaitArgs` on 64-bit targets. The compile-time
|
|
* assert below and the `ad_wait_args_size()` runtime getter form the
|
|
* 3-layer pin: Rust const assert, C `_Static_assert` in the header,
|
|
* and the test in `c_abi_layout.rs`.
|
|
*/
|
|
#define AD_WAIT_ARGS_SIZE 112
|
|
|
|
#define AD_WAIT_MODE_SIZE 48
|
|
|
|
#define AD_WAIT_PREDICATE_SIZE 48
|
|
|
|
#define AD_WAIT_SCOPE_SIZE 16
|
|
|
|
#define AD_WAIT_SURFACE_MODES_SIZE 3
|
|
|
|
/**
|
|
* New result codes may be appended in future releases. Always handle values
|
|
* outside this list.
|
|
*/
|
|
enum AdResult
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_RESULT_OK = 0,
|
|
AD_RESULT_ERR_PERM_DENIED = -1,
|
|
AD_RESULT_ERR_ELEMENT_NOT_FOUND = -2,
|
|
AD_RESULT_ERR_APP_NOT_FOUND = -3,
|
|
AD_RESULT_ERR_ACTION_FAILED = -4,
|
|
AD_RESULT_ERR_ACTION_NOT_SUPPORTED = -5,
|
|
AD_RESULT_ERR_STALE_REF = -6,
|
|
AD_RESULT_ERR_WINDOW_NOT_FOUND = -7,
|
|
AD_RESULT_ERR_PLATFORM_NOT_SUPPORTED = -8,
|
|
AD_RESULT_ERR_TIMEOUT = -9,
|
|
AD_RESULT_ERR_INVALID_ARGS = -10,
|
|
AD_RESULT_ERR_NOTIFICATION_NOT_FOUND = -11,
|
|
AD_RESULT_ERR_INTERNAL = -12,
|
|
AD_RESULT_ERR_SNAPSHOT_NOT_FOUND = -13,
|
|
AD_RESULT_ERR_POLICY_DENIED = -14,
|
|
AD_RESULT_ERR_AMBIGUOUS_TARGET = -15,
|
|
AD_RESULT_ERR_APP_UNRESPONSIVE = -16,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdResult AdResult;
|
|
#else
|
|
typedef int32_t AdResult;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdImageFormat
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_IMAGE_FORMAT_PNG = 0,
|
|
AD_IMAGE_FORMAT_JPG = 1,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdImageFormat AdImageFormat;
|
|
#else
|
|
typedef int32_t AdImageFormat;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdActionKind
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_ACTION_KIND_CLICK = 0,
|
|
AD_ACTION_KIND_DOUBLE_CLICK = 1,
|
|
AD_ACTION_KIND_RIGHT_CLICK = 2,
|
|
AD_ACTION_KIND_TRIPLE_CLICK = 3,
|
|
AD_ACTION_KIND_SET_VALUE = 4,
|
|
AD_ACTION_KIND_SET_FOCUS = 5,
|
|
AD_ACTION_KIND_EXPAND = 6,
|
|
AD_ACTION_KIND_COLLAPSE = 7,
|
|
AD_ACTION_KIND_SELECT = 8,
|
|
AD_ACTION_KIND_TOGGLE = 9,
|
|
AD_ACTION_KIND_CHECK = 10,
|
|
AD_ACTION_KIND_UNCHECK = 11,
|
|
AD_ACTION_KIND_SCROLL = 12,
|
|
AD_ACTION_KIND_SCROLL_TO = 13,
|
|
AD_ACTION_KIND_PRESS_KEY = 14,
|
|
AD_ACTION_KIND_KEY_DOWN = 15,
|
|
AD_ACTION_KIND_KEY_UP = 16,
|
|
AD_ACTION_KIND_TYPE_TEXT = 17,
|
|
AD_ACTION_KIND_CLEAR = 18,
|
|
AD_ACTION_KIND_HOVER = 19,
|
|
AD_ACTION_KIND_DRAG = 20,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdActionKind AdActionKind;
|
|
#else
|
|
typedef int32_t AdActionKind;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdDirection
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_DIRECTION_UP = 0,
|
|
AD_DIRECTION_DOWN = 1,
|
|
AD_DIRECTION_LEFT = 2,
|
|
AD_DIRECTION_RIGHT = 3,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdDirection AdDirection;
|
|
#else
|
|
typedef int32_t AdDirection;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdDeliveryDisposition
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_DELIVERY_DISPOSITION_UNKNOWN = 0,
|
|
AD_DELIVERY_DISPOSITION_NOT_DELIVERED = 1,
|
|
AD_DELIVERY_DISPOSITION_DELIVERY_UNCERTAIN = 2,
|
|
AD_DELIVERY_DISPOSITION_DELIVERED_UNVERIFIED = 3,
|
|
AD_DELIVERY_DISPOSITION_DELIVERED_VERIFIED = 4,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdDeliveryDisposition AdDeliveryDisposition;
|
|
#else
|
|
typedef int32_t AdDeliveryDisposition;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdFindSelectionKind
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_FIND_SELECTION_KIND_STRICT = 0,
|
|
AD_FIND_SELECTION_KIND_FIRST = 1,
|
|
AD_FIND_SELECTION_KIND_LAST = 2,
|
|
AD_FIND_SELECTION_KIND_NTH = 3,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdFindSelectionKind AdFindSelectionKind;
|
|
#else
|
|
typedef int32_t AdFindSelectionKind;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdIdentifierKind
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_IDENTIFIER_KIND_AX_IDENTIFIER = 0,
|
|
AD_IDENTIFIER_KIND_AX_DOM_IDENTIFIER = 1,
|
|
AD_IDENTIFIER_KIND_AUTOMATION_ID = 2,
|
|
AD_IDENTIFIER_KIND_RUNTIME_ID = 3,
|
|
AD_IDENTIFIER_KIND_ATSPI_OBJECT_PATH = 4,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdIdentifierKind AdIdentifierKind;
|
|
#else
|
|
typedef int32_t AdIdentifierKind;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdModifier
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_MODIFIER_META = 0,
|
|
AD_MODIFIER_CTRL = 1,
|
|
AD_MODIFIER_ALT = 2,
|
|
AD_MODIFIER_SHIFT = 3,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdModifier AdModifier;
|
|
#else
|
|
typedef int32_t AdModifier;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdMouseButton
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_MOUSE_BUTTON_LEFT = 0,
|
|
AD_MOUSE_BUTTON_RIGHT = 1,
|
|
AD_MOUSE_BUTTON_MIDDLE = 2,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdMouseButton AdMouseButton;
|
|
#else
|
|
typedef int32_t AdMouseButton;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdMouseEventKind
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_MOUSE_EVENT_KIND_MOVE = 0,
|
|
AD_MOUSE_EVENT_KIND_DOWN = 1,
|
|
AD_MOUSE_EVENT_KIND_UP = 2,
|
|
AD_MOUSE_EVENT_KIND_CLICK = 3,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdMouseEventKind AdMouseEventKind;
|
|
#else
|
|
typedef int32_t AdMouseEventKind;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdPolicyKind
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_POLICY_KIND_HEADLESS = 0,
|
|
AD_POLICY_KIND_FOCUS_FALLBACK = 1,
|
|
AD_POLICY_KIND_HEADED = 2,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdPolicyKind AdPolicyKind;
|
|
#else
|
|
typedef int32_t AdPolicyKind;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdRetryDisposition
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_RETRY_DISPOSITION_UNKNOWN = 0,
|
|
AD_RETRY_DISPOSITION_SAFE = 1,
|
|
AD_RETRY_DISPOSITION_UNSAFE = 2,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdRetryDisposition AdRetryDisposition;
|
|
#else
|
|
typedef int32_t AdRetryDisposition;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdScreenshotKind
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_SCREENSHOT_KIND_SCREEN = 0,
|
|
AD_SCREENSHOT_KIND_WINDOW = 1,
|
|
AD_SCREENSHOT_KIND_FULL_SCREEN = 2,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdScreenshotKind AdScreenshotKind;
|
|
#else
|
|
typedef int32_t AdScreenshotKind;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdSnapshotSurface
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_SNAPSHOT_SURFACE_WINDOW = 0,
|
|
AD_SNAPSHOT_SURFACE_FOCUSED = 1,
|
|
AD_SNAPSHOT_SURFACE_MENU = 2,
|
|
AD_SNAPSHOT_SURFACE_MENUBAR = 3,
|
|
AD_SNAPSHOT_SURFACE_SHEET = 4,
|
|
AD_SNAPSHOT_SURFACE_POPOVER = 5,
|
|
AD_SNAPSHOT_SURFACE_ALERT = 6,
|
|
AD_SNAPSHOT_SURFACE_DESKTOP = 7,
|
|
AD_SNAPSHOT_SURFACE_TASKBAR = 8,
|
|
AD_SNAPSHOT_SURFACE_SYSTEM_TRAY = 9,
|
|
AD_SNAPSHOT_SURFACE_QUICK_SETTINGS = 10,
|
|
AD_SNAPSHOT_SURFACE_NOTIFICATION_CENTER = 11,
|
|
AD_SNAPSHOT_SURFACE_TOOLBAR = 12,
|
|
AD_SNAPSHOT_SURFACE_DOCK = 13,
|
|
AD_SNAPSHOT_SURFACE_SPOTLIGHT = 14,
|
|
AD_SNAPSHOT_SURFACE_MENU_BAR_EXTRAS = 15,
|
|
AD_SNAPSHOT_SURFACE_SYSTEM_TRAY_OVERFLOW = 16,
|
|
AD_SNAPSHOT_SURFACE_START_MENU = 17,
|
|
AD_SNAPSHOT_SURFACE_ACTION_CENTER = 18,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdSnapshotSurface AdSnapshotSurface;
|
|
#else
|
|
typedef int32_t AdSnapshotSurface;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdStepMechanism
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_STEP_MECHANISM_SEMANTIC_API = 1,
|
|
AD_STEP_MECHANISM_PHYSICAL_SYNTHETIC = 2,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdStepMechanism AdStepMechanism;
|
|
#else
|
|
typedef int32_t AdStepMechanism;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
enum AdWindowOpKind
|
|
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
: int32_t
|
|
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
|
|
{
|
|
AD_WINDOW_OP_KIND_RESIZE = 0,
|
|
AD_WINDOW_OP_KIND_MOVE = 1,
|
|
AD_WINDOW_OP_KIND_MINIMIZE = 2,
|
|
AD_WINDOW_OP_KIND_MAXIMIZE = 3,
|
|
AD_WINDOW_OP_KIND_RESTORE = 4,
|
|
};
|
|
#ifndef __cplusplus
|
|
#if __STDC_VERSION__ >= 202311L
|
|
typedef enum AdWindowOpKind AdWindowOpKind;
|
|
#else
|
|
typedef int32_t AdWindowOpKind;
|
|
#endif // __STDC_VERSION__ >= 202311L
|
|
#endif // __cplusplus
|
|
|
|
typedef struct AdAdapter AdAdapter;
|
|
|
|
/**
|
|
* Opaque list handle emitted by `ad_list_apps`. See
|
|
* [`crate::types::window_list::AdWindowList`] for the pattern.
|
|
*/
|
|
typedef struct AdAppList AdAppList;
|
|
|
|
/**
|
|
* Opaque list handle emitted by `ad_list_displays`.
|
|
*/
|
|
typedef struct AdDisplayList AdDisplayList;
|
|
|
|
/**
|
|
* Opaque list handle emitted by `ad_list_surfaces_exact`.
|
|
*/
|
|
typedef struct AdExactSurfaceList AdExactSurfaceList;
|
|
|
|
/**
|
|
* Opaque list handle emitted by ad_list_windows_exact.
|
|
*/
|
|
typedef struct AdExactWindowList AdExactWindowList;
|
|
|
|
/**
|
|
* Opaque image-buffer handle returned by `ad_screenshot`. The backing
|
|
* byte buffer and its length live inside the Rust-owned struct — a
|
|
* consumer cannot accidentally desynchronize the pair and trigger a
|
|
* heap-corruption double-free. Walk it through `ad_image_buffer_*`
|
|
* accessors and free it with `ad_image_buffer_free`.
|
|
*/
|
|
typedef struct AdImageBuffer AdImageBuffer;
|
|
|
|
/**
|
|
* Opaque notification list returned by `ad_list_notifications`.
|
|
*/
|
|
typedef struct AdNotificationList AdNotificationList;
|
|
|
|
/**
|
|
* Opaque list handle emitted by `ad_list_surfaces`. See
|
|
* [`crate::types::window_list::AdWindowList`] for the pattern.
|
|
*/
|
|
typedef struct AdSurfaceList AdSurfaceList;
|
|
|
|
/**
|
|
* Opaque list handle emitted by `ad_list_windows`.
|
|
*
|
|
* The struct intentionally has no `#[repr(C)]` so cbindgen emits a
|
|
* forward declaration only (`typedef struct AdWindowList AdWindowList;`).
|
|
* Consumers cannot read the backing pointer or length and cannot
|
|
* construct a count mismatch — they walk the list through
|
|
* `ad_window_list_count`, `ad_window_list_get`, and free it with
|
|
* `ad_window_list_free`.
|
|
*/
|
|
typedef struct AdWindowList AdWindowList;
|
|
|
|
typedef struct AdNativeHandle {
|
|
/**
|
|
* Opaque thread-affine registry token, never an allocation or OS pointer.
|
|
*/
|
|
const void *ptr;
|
|
} AdNativeHandle;
|
|
|
|
/**
|
|
* Scroll parameters embedded in `AdAction` when `kind == SCROLL`.
|
|
*
|
|
* `direction` is stored as `int32_t` for the same boundary-safety
|
|
* reason `AdAction.kind` is. Valid values are the discriminants of
|
|
* `AdDirection`.
|
|
*/
|
|
typedef struct AdScrollParams {
|
|
int32_t direction;
|
|
uint32_t amount;
|
|
} AdScrollParams;
|
|
|
|
/**
|
|
* Key combination: a named key plus optional modifier list.
|
|
*
|
|
* `modifiers` points to an array of `int32_t` values (not a typed Rust
|
|
* enum array) so the C boundary cannot be tricked into writing an
|
|
* out-of-range discriminant into a Rust enum slot. Each entry is
|
|
* validated against `AdModifier` before use; an invalid discriminant
|
|
* returns `AD_RESULT_ERR_INVALID_ARGS`.
|
|
*/
|
|
typedef struct AdKeyCombo {
|
|
const char *key;
|
|
const int32_t *modifiers;
|
|
uint32_t modifier_count;
|
|
} AdKeyCombo;
|
|
|
|
typedef struct AdPoint {
|
|
double x;
|
|
double y;
|
|
} AdPoint;
|
|
|
|
/**
|
|
* Caller-allocated drag parameters. Callers must zero-initialize the whole
|
|
* struct before setting fields so unset numeric fields read as the `0`
|
|
* adapter-default sentinel rather than stack garbage. Verify layout against
|
|
* `AD_DRAG_PARAMS_SIZE` / `ad_drag_params_size()` when binding from a language
|
|
* whose struct layout may diverge.
|
|
*/
|
|
typedef struct AdDragParams {
|
|
struct AdPoint from;
|
|
struct AdPoint to;
|
|
uint64_t duration_ms;
|
|
uint64_t drop_delay_ms;
|
|
} AdDragParams;
|
|
|
|
/**
|
|
* Action dispatched by `ad_execute_action`.
|
|
*
|
|
* `kind` is stored as `int32_t` so a buggy or malicious C caller
|
|
* cannot write an out-of-range discriminant into a Rust enum slot —
|
|
* an out-of-range value is rejected with
|
|
* `AD_RESULT_ERR_INVALID_ARGS` at the boundary. Valid values are the
|
|
* discriminants of `AdActionKind`.
|
|
*
|
|
* `AdDragParams` is embedded by value, so any growth there grows this
|
|
* struct too. Callers must zero-initialize the whole struct and verify
|
|
* layout against `AD_ACTION_SIZE` / `ad_action_size()` when binding from
|
|
* a language whose struct layout may diverge — an under-allocated action
|
|
* makes the library read past the caller's buffer.
|
|
*/
|
|
typedef struct AdAction {
|
|
int32_t kind;
|
|
const char *text;
|
|
struct AdScrollParams scroll;
|
|
struct AdKeyCombo key;
|
|
struct AdDragParams drag;
|
|
} AdAction;
|
|
|
|
typedef struct AdElementState {
|
|
const char *role;
|
|
char **states;
|
|
uint32_t state_count;
|
|
const char *value;
|
|
} AdElementState;
|
|
|
|
typedef struct AdActionStep {
|
|
const char *label;
|
|
const char *outcome;
|
|
int32_t mechanism;
|
|
bool has_mechanism;
|
|
bool verified;
|
|
bool has_verified;
|
|
uint64_t _reserved;
|
|
} AdActionStep;
|
|
|
|
typedef struct AdDeliverySemantics {
|
|
int32_t delivery;
|
|
int32_t retry;
|
|
} AdDeliverySemantics;
|
|
|
|
typedef struct AdActionResult {
|
|
const char *action;
|
|
const char *ref_id;
|
|
struct AdElementState *post_state;
|
|
struct AdActionStep *steps;
|
|
uint32_t step_count;
|
|
const char *details_json;
|
|
struct AdDeliverySemantics disposition;
|
|
} AdActionResult;
|
|
|
|
typedef struct AdRefProcess {
|
|
uint32_t pid;
|
|
} AdRefProcess;
|
|
|
|
typedef struct AdRefIdentity {
|
|
const char *role;
|
|
const char *name;
|
|
const char *value;
|
|
const char *description;
|
|
const char *native_id;
|
|
} AdRefIdentity;
|
|
|
|
typedef struct AdRect {
|
|
double x;
|
|
double y;
|
|
double width;
|
|
double height;
|
|
} AdRect;
|
|
|
|
typedef struct AdRefGeometry {
|
|
struct AdRect bounds;
|
|
uint64_t bounds_hash;
|
|
bool has_bounds;
|
|
bool has_bounds_hash;
|
|
} AdRefGeometry;
|
|
|
|
typedef struct AdStringSlice {
|
|
const char *const *items;
|
|
size_t count;
|
|
} AdStringSlice;
|
|
|
|
typedef struct AdRefCapabilities {
|
|
struct AdStringSlice states;
|
|
struct AdStringSlice available_actions;
|
|
} AdRefCapabilities;
|
|
|
|
typedef struct AdRefSource {
|
|
const char *app;
|
|
const char *window_id;
|
|
const char *window_title;
|
|
uint64_t window_bounds_hash;
|
|
int32_t surface;
|
|
bool has_window_bounds_hash;
|
|
} AdRefSource;
|
|
|
|
typedef struct AdRefScope {
|
|
const char *root_ref;
|
|
const uint32_t *path;
|
|
size_t path_count;
|
|
bool path_is_absolute;
|
|
} AdRefScope;
|
|
|
|
typedef struct AdRefEntry {
|
|
struct AdRefProcess process;
|
|
struct AdRefIdentity identity;
|
|
struct AdRefGeometry geometry;
|
|
struct AdRefCapabilities capabilities;
|
|
struct AdRefSource source;
|
|
struct AdRefScope scope;
|
|
} AdRefEntry;
|
|
|
|
/**
|
|
* Additive exact-identity payload for low-level struct-based ref actions.
|
|
*
|
|
* Callers must set `version` to `AD_EXACT_REF_ENTRY_VERSION`, `size` to
|
|
* `AD_EXACT_REF_ENTRY_SIZE`, and `process_instance` to the generation token
|
|
* emitted by the snapshot. When `entry.identity.native_id` is non-null,
|
|
* `identifier_kind` must name its exact platform identifier namespace.
|
|
*/
|
|
typedef struct AdExactRefEntry {
|
|
uint32_t version;
|
|
uint32_t size;
|
|
struct AdRefEntry entry;
|
|
const char *process_instance;
|
|
int32_t identifier_kind;
|
|
} AdExactRefEntry;
|
|
|
|
typedef struct AdWindowInfo {
|
|
/**
|
|
* Legacy observation-only window ID. This struct has no process-generation
|
|
* evidence and is rejected by targeting APIs; use `AdExactWindowInfo` for
|
|
* any operation that sends a previously observed window back to the library.
|
|
*/
|
|
const char *id;
|
|
const char *title;
|
|
const char *app_name;
|
|
uint32_t pid;
|
|
struct AdRect bounds;
|
|
bool has_bounds;
|
|
bool is_focused;
|
|
} AdWindowInfo;
|
|
|
|
/**
|
|
* Additive generation-pinned window identity for operations that target a
|
|
* previously observed live window.
|
|
*/
|
|
typedef struct AdExactWindowInfo {
|
|
uint32_t version;
|
|
uint32_t size;
|
|
struct AdWindowInfo window;
|
|
const char *process_instance;
|
|
} AdExactWindowInfo;
|
|
|
|
typedef struct AdAppInfo {
|
|
const char *name;
|
|
uint32_t pid;
|
|
const char *bundle_id;
|
|
} AdAppInfo;
|
|
|
|
typedef struct AdOptionalU64 {
|
|
uint64_t value;
|
|
bool present;
|
|
} AdOptionalU64;
|
|
|
|
typedef struct AdWaitSurfaceModes {
|
|
bool menu;
|
|
bool menu_closed;
|
|
bool notification;
|
|
} AdWaitSurfaceModes;
|
|
|
|
typedef struct AdWaitMode {
|
|
struct AdOptionalU64 pause;
|
|
const char *element;
|
|
const char *window;
|
|
const char *text;
|
|
struct AdWaitSurfaceModes surfaces;
|
|
} AdWaitMode;
|
|
|
|
typedef struct AdOptionalUsize {
|
|
size_t value;
|
|
bool present;
|
|
} AdOptionalUsize;
|
|
|
|
typedef struct AdWaitPredicate {
|
|
const char *snapshot_id;
|
|
const char *predicate;
|
|
const char *value;
|
|
const char *action;
|
|
struct AdOptionalUsize count;
|
|
} AdWaitPredicate;
|
|
|
|
typedef struct AdWaitScope {
|
|
uint64_t timeout_ms;
|
|
const char *app;
|
|
} AdWaitScope;
|
|
|
|
/**
|
|
* Arguments for `ad_wait`, mirroring `core::commands::wait::WaitArgs` for
|
|
* the pause/element/text/surface wait modes and predicates.
|
|
*
|
|
* The core event-wait mode (`--event` / `--window-id`) is intentionally not
|
|
* exposed over FFI in this release; `wait_args_from_ffi` always forwards
|
|
* `event: None` and `window_id: None` to core. `mode.window` here is a
|
|
* title-appearance wait (poll until a window with the given title exists),
|
|
* which is a distinct semantic from the deferred event-wait mode.
|
|
*
|
|
* Mode, predicate, and scope fields are grouped into named PODs. Optional
|
|
* numbers use `AdOptional*`; optional strings are nullable pointers.
|
|
*
|
|
* Callers must zero-initialize before use and verify layout via
|
|
* `AD_WAIT_ARGS_SIZE` / `ad_wait_args_size()`.
|
|
*/
|
|
typedef struct AdWaitArgs {
|
|
struct AdWaitMode mode;
|
|
struct AdWaitPredicate predicate;
|
|
struct AdWaitScope scope;
|
|
} AdWaitArgs;
|
|
|
|
typedef struct AdDisplayInfo {
|
|
uint32_t version;
|
|
uint32_t size;
|
|
const char *id;
|
|
struct AdRect bounds;
|
|
bool is_primary;
|
|
double scale;
|
|
} AdDisplayInfo;
|
|
|
|
/**
|
|
* Mouse event dispatched by `ad_mouse_event`.
|
|
*
|
|
* `kind` and `button` are stored as `int32_t` for the same reason
|
|
* `AdAction.kind` is — foreign callers cannot place invalid
|
|
* discriminants into Rust enum slots. Valid values are the
|
|
* discriminants of `AdMouseEventKind` and `AdMouseButton`.
|
|
*/
|
|
typedef struct AdMouseEvent {
|
|
int32_t kind;
|
|
struct AdPoint point;
|
|
int32_t button;
|
|
uint32_t click_count;
|
|
} AdMouseEvent;
|
|
|
|
typedef struct AdNotificationIdentity {
|
|
const char *app;
|
|
const char *title;
|
|
} AdNotificationIdentity;
|
|
|
|
typedef struct AdNotificationActionRequest {
|
|
uint32_t index;
|
|
int32_t policy;
|
|
const char *action_name;
|
|
struct AdNotificationIdentity identity;
|
|
} AdNotificationActionRequest;
|
|
|
|
typedef struct AdNotificationFilter {
|
|
const char *app;
|
|
const char *text;
|
|
uint32_t limit;
|
|
bool has_limit;
|
|
} AdNotificationFilter;
|
|
|
|
typedef struct AdNotificationInfo {
|
|
uint32_t index;
|
|
const char *app_name;
|
|
const char *title;
|
|
const char *body;
|
|
char **actions;
|
|
uint32_t action_count;
|
|
} AdNotificationInfo;
|
|
|
|
typedef struct AdFindSelection {
|
|
int32_t kind;
|
|
uint32_t nth;
|
|
} AdFindSelection;
|
|
|
|
typedef struct AdFindControl {
|
|
uint32_t version;
|
|
struct AdFindSelection selection;
|
|
uint64_t timeout_ms;
|
|
} AdFindControl;
|
|
|
|
typedef struct AdFindIdentity {
|
|
const char *role;
|
|
const char *name;
|
|
const char *description;
|
|
const char *native_id;
|
|
const char *value;
|
|
} AdFindIdentity;
|
|
|
|
typedef struct AdFindStatePredicate {
|
|
const char *token;
|
|
int32_t expected;
|
|
} AdFindStatePredicate;
|
|
|
|
typedef struct AdFindStateSlice {
|
|
const struct AdFindStatePredicate *items;
|
|
size_t count;
|
|
} AdFindStateSlice;
|
|
|
|
typedef struct AdFindFilter {
|
|
struct AdFindIdentity identity;
|
|
const char *has_text;
|
|
struct AdFindStateSlice states;
|
|
const struct AdFindQuery *has;
|
|
const struct AdFindQuery *has_not;
|
|
bool exact;
|
|
} AdFindFilter;
|
|
|
|
typedef struct AdFindQuery {
|
|
struct AdFindControl control;
|
|
struct AdFindFilter filter;
|
|
} AdFindQuery;
|
|
|
|
/**
|
|
* Screenshot target for `ad_screenshot`.
|
|
*
|
|
* `kind` is stored as `int32_t` to keep the enum-discriminant check
|
|
* at the boundary. Valid values are the discriminants of
|
|
* `AdScreenshotKind`. `screen_index` is only consulted when kind is
|
|
* `SCREEN`; `pid` only when kind is `WINDOW`.
|
|
*/
|
|
typedef struct AdScreenshotTarget {
|
|
int32_t kind;
|
|
uint64_t screen_index;
|
|
uint32_t pid;
|
|
} AdScreenshotTarget;
|
|
|
|
typedef struct AdSurfaceInfo {
|
|
const char *kind;
|
|
const char *title;
|
|
int64_t item_count;
|
|
} AdSurfaceInfo;
|
|
|
|
/**
|
|
* Additive surface observation that preserves the core surface ID.
|
|
*/
|
|
typedef struct AdExactSurfaceInfo {
|
|
uint32_t version;
|
|
uint32_t size;
|
|
const char *id;
|
|
struct AdSurfaceInfo surface;
|
|
} AdExactSurfaceInfo;
|
|
|
|
typedef struct AdNodeContent {
|
|
const char *ref_id;
|
|
const char *role;
|
|
const char *name;
|
|
const char *value;
|
|
const char *description;
|
|
const char *hint;
|
|
} AdNodeContent;
|
|
|
|
typedef struct AdNodePresentation {
|
|
char **states;
|
|
struct AdRect bounds;
|
|
uint32_t state_count;
|
|
bool has_bounds;
|
|
} AdNodePresentation;
|
|
|
|
typedef struct AdNodeRelation {
|
|
int32_t parent_index;
|
|
uint32_t child_start;
|
|
uint32_t child_count;
|
|
} AdNodeRelation;
|
|
|
|
typedef struct AdNode {
|
|
struct AdNodeContent content;
|
|
struct AdNodePresentation presentation;
|
|
struct AdNodeRelation relation;
|
|
} AdNode;
|
|
|
|
typedef struct AdNodeTree {
|
|
struct AdNode *nodes;
|
|
uint32_t count;
|
|
} AdNodeTree;
|
|
|
|
/**
|
|
* Options for `ad_get_tree`.
|
|
*
|
|
* `surface` is stored as `int32_t` so foreign callers cannot write
|
|
* an invalid discriminant into a Rust enum slot. Valid values are the
|
|
* discriminants of `AdSnapshotSurface`; out-of-range values return
|
|
* `AD_RESULT_ERR_INVALID_ARGS`.
|
|
*/
|
|
typedef struct AdTreeOptions {
|
|
uint8_t max_depth;
|
|
bool include_bounds;
|
|
bool interactive_only;
|
|
bool compact;
|
|
int32_t surface;
|
|
} AdTreeOptions;
|
|
|
|
/**
|
|
* Window-manager operation dispatched by `ad_window_op`.
|
|
*
|
|
* `kind` is stored as `int32_t` to keep the enum-discriminant check at
|
|
* the boundary — out-of-range values return
|
|
* `AD_RESULT_ERR_INVALID_ARGS`. Valid values are the discriminants of
|
|
* `AdWindowOpKind`. `width`/`height`/`x`/`y` are only consulted for
|
|
* the variants that use them.
|
|
*/
|
|
typedef struct AdWindowOp {
|
|
int32_t kind;
|
|
double width;
|
|
double height;
|
|
double x;
|
|
double y;
|
|
} AdWindowOp;
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif // __cplusplus
|
|
|
|
/**
|
|
* Returns the packed ABI major version of this dylib build.
|
|
*
|
|
* A consumer should compare this to `AD_ABI_VERSION_MAJOR` from the header it
|
|
* compiled against. If they differ, call nothing further — the ABI is
|
|
* incompatible.
|
|
*/
|
|
uint32_t ad_abi_version(void);
|
|
|
|
/**
|
|
* Checks that the consumer's expected ABI major matches this dylib.
|
|
*
|
|
* It is recommended to call this once after `dlopen` / `LoadLibrary` to verify
|
|
* the header and dylib agree on the major ABI version; a mismatch means they
|
|
* are incompatible. No global state is initialised by this call — skipping it
|
|
* does not prevent adapter functions from operating, but undetected ABI
|
|
* mismatches may cause memory corruption. Returns `AD_RESULT_OK` when
|
|
* `expected_major == AD_ABI_VERSION_MAJOR`. Returns
|
|
* `AD_RESULT_ERR_INVALID_ARGS` with a diagnostic last-error when the version
|
|
* does not match.
|
|
*/
|
|
AdResult ad_init(uint32_t expected_major);
|
|
|
|
/**
|
|
* Low-level native-handle action. Dispatches directly to the platform adapter
|
|
* without strict ref re-identification or actionability preflight. This is a
|
|
* raw escape hatch for callers that already hold a live native handle. Callers
|
|
* wanting CLI-semantics parity (RefStore load → strict resolution → preflight
|
|
* → dispatch) should use `ad_execute_by_ref` instead.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
* `handle` must be a non-null pointer to a valid `AdNativeHandle` produced by
|
|
* the same live adapter. Free the handle before destroying that adapter.
|
|
* `action` must be a non-null pointer to a valid `AdAction`.
|
|
* `out` must be a non-null pointer to an `AdActionResult` to write the result into.
|
|
*
|
|
* Handles come from exact resolvers and already carry process-generation
|
|
* evidence, so this executes under the same policy as
|
|
* `ad_execute_action_with_policy`.
|
|
*/
|
|
AdResult ad_execute_action(const struct AdAdapter *adapter,
|
|
const struct AdNativeHandle *handle,
|
|
const struct AdAction *action,
|
|
struct AdActionResult *out);
|
|
|
|
/**
|
|
* Low-level native-handle action with explicit interaction policy. Dispatches
|
|
* directly to the platform adapter without strict ref re-identification or
|
|
* actionability preflight. The `policy` discriminant is applied verbatim — no
|
|
* base-policy elevation is performed. This is a raw escape hatch for callers
|
|
* that already hold a live native handle. Callers wanting CLI-semantics parity
|
|
* (RefStore load → strict resolution → preflight → dispatch with base-policy
|
|
* join) should use `ad_execute_by_ref` instead.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
* `handle` must be a non-null pointer to a valid `AdNativeHandle` produced by
|
|
* the same live adapter. Free the handle before destroying that adapter.
|
|
* `action` must be a non-null pointer to a valid `AdAction`.
|
|
* `out` must be a non-null pointer to an `AdActionResult` to write the result into.
|
|
*/
|
|
AdResult ad_execute_action_with_policy(const struct AdAdapter *adapter,
|
|
const struct AdNativeHandle *handle,
|
|
const struct AdAction *action,
|
|
int32_t policy,
|
|
struct AdActionResult *out);
|
|
|
|
/**
|
|
* Low-level struct-based ref-action path: takes a pre-resolved `AdRefEntry`,
|
|
* runs strict element re-identification and actionability preflight, then
|
|
* dispatches using the caller-supplied `policy` verbatim (no base-policy
|
|
* elevation). The adapter's session context (from `ad_adapter_create_with_session`)
|
|
* is threaded through so that trace events carry the correct session id.
|
|
*
|
|
* This is the low-level escape hatch for callers that have already resolved
|
|
* a `RefEntry` outside the `RefStore` pipeline (e.g. serialized from an
|
|
* external snapshot). The `policy` discriminant is applied as-is — there is
|
|
* no `Action::base_interaction_policy` join here.
|
|
*
|
|
* Callers wanting full CLI-semantics parity (RefStore load → `RefMap` lookup
|
|
* → strict resolution → preflight → dispatch with base-policy join) should
|
|
* use `ad_execute_by_ref` instead.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
* `entry` must be a non-null pointer to a valid `AdRefEntry`.
|
|
* `action` must be a non-null pointer to a valid `AdAction`.
|
|
* `out` must be a non-null pointer to an `AdActionResult` to write the result into.
|
|
*/
|
|
AdResult ad_execute_ref_action_with_policy(const struct AdAdapter *adapter,
|
|
const struct AdRefEntry *entry,
|
|
const struct AdAction *action,
|
|
int32_t policy,
|
|
struct AdActionResult *out);
|
|
|
|
/**
|
|
* Executes a struct-based ref action with exact process-generation and typed
|
|
* native-id evidence.
|
|
*
|
|
* # Safety
|
|
*
|
|
* All pointers must be valid. `entry` must carry the current exact-entry
|
|
* version and size. `out` is zeroed before any fallible operation.
|
|
*/
|
|
AdResult ad_execute_ref_action_exact_with_policy(const struct AdAdapter *adapter,
|
|
const struct AdExactRefEntry *entry,
|
|
const struct AdAction *action,
|
|
int32_t policy,
|
|
struct AdActionResult *out);
|
|
|
|
/**
|
|
* Releases a handle previously returned by an exact resolver and
|
|
* zeroes the caller's struct so accidentally calling this twice is
|
|
* a deterministic no-op instead of dropping its owned payload twice.
|
|
*
|
|
* `AdNativeHandle.ptr` is an opaque registry token, not an operating-system
|
|
* or Rust allocation address. Removing it releases the platform payload.
|
|
*
|
|
* Ownership contract: the FFI owns the handle from the moment a resolver
|
|
* writes `ptr`. Copying the struct after that point is unsupported. Releasing
|
|
* the original zeroes it and makes a second release of that same struct a
|
|
* no-op; releasing an unzeroed copy is rejected.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
* It must identify the same adapter that created the handle. The adapter may
|
|
* already have been destroyed; handles remain independently owned until freed.
|
|
* `handle` must be null or a `*mut AdNativeHandle` previously populated by an
|
|
* exact resolver on the calling thread. On return `(*handle).ptr` is
|
|
* `NULL` so a double-call is a no-op instead of a double-free.
|
|
*/
|
|
AdResult ad_free_handle(const struct AdAdapter *adapter, struct AdNativeHandle *handle);
|
|
|
|
/**
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
* `entry` must be a non-null pointer to a valid `AdRefEntry`.
|
|
* `out` must be a non-null pointer to an `AdNativeHandle` to write the result into.
|
|
*
|
|
* This legacy entrypoint lacks exact identity evidence and fails closed. Use ad_resolve_element_exact.
|
|
*/
|
|
AdResult ad_resolve_element(const struct AdAdapter *adapter,
|
|
const struct AdRefEntry *entry,
|
|
struct AdNativeHandle *out);
|
|
|
|
/**
|
|
* Resolves an element using process-generation and typed native-id evidence.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `adapter` and `entry` must be live and valid; `out` must be writable.
|
|
*/
|
|
AdResult ad_resolve_element_exact(const struct AdAdapter *adapter,
|
|
const struct AdExactRefEntry *entry,
|
|
struct AdNativeHandle *out);
|
|
|
|
/**
|
|
* # Safety
|
|
*
|
|
* `result` must be null or a pointer to an `AdActionResult` previously written
|
|
* by `ad_execute_action`, `ad_execute_action_with_policy`,
|
|
* `ad_execute_ref_action_with_policy`, or `ad_notification_action`. This frees
|
|
* `post_state`, `steps`, and all nested strings. After this call all pointers
|
|
* inside the struct are invalid.
|
|
*/
|
|
void ad_free_action_result(struct AdActionResult *result);
|
|
|
|
/**
|
|
* Builds a platform adapter for the current OS and returns an opaque
|
|
* handle. Returns null on allocation failure or if a Rust panic is
|
|
* caught at the FFI boundary (inspect `ad_last_error_*` for details).
|
|
*
|
|
* The returned pointer is owned by the caller and must be released with
|
|
* `ad_adapter_destroy`. Creating and destroying adapters is cheap; the
|
|
* common pattern is one adapter per process lifetime.
|
|
*/
|
|
struct AdAdapter *ad_adapter_create(void);
|
|
|
|
/**
|
|
* Builds a session-scoped platform adapter. `session` may be:
|
|
* - null: equivalent to `ad_adapter_create()` (no session).
|
|
* - a valid session id (1-64 ASCII alphanumeric / `-` / `_` chars): associates
|
|
* the adapter with that session for refmap persistence.
|
|
* - empty, too long, containing invalid characters, or invalid UTF-8: sets
|
|
* `ErrInvalidArgs` in the last-error slot and returns null; no adapter is
|
|
* allocated.
|
|
*
|
|
* The returned pointer must be released with `ad_adapter_destroy`.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `session` must be null or point to readable memory that is NUL-terminated
|
|
* within `AD_MAX_STRING_BYTES + 1` bytes.
|
|
*/
|
|
struct AdAdapter *ad_adapter_create_with_session(const char *session);
|
|
|
|
/**
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a pointer returned by `ad_adapter_create` or
|
|
* `ad_adapter_create_with_session`, or null. After this call the pointer
|
|
* is invalid and must not be used.
|
|
*
|
|
* Calls that acquired the adapter before destruction retain it until they
|
|
* return. Calls beginning after destruction fail with `ErrInvalidArgs`.
|
|
*/
|
|
void ad_adapter_destroy(struct AdAdapter *adapter);
|
|
|
|
/**
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create` that
|
|
* has not yet been destroyed.
|
|
*/
|
|
AdResult ad_check_permissions(const struct AdAdapter *adapter);
|
|
|
|
/**
|
|
* Closes the application identified by `id` (bundle id on macOS,
|
|
* executable path on other platforms). `force = true` skips the
|
|
* graceful-shutdown path, terminates matching app processes, and escalates
|
|
* survivors when the platform supports it. Session-critical
|
|
* processes (loginwindow, WindowServer, Dock, Finder, launchd) are
|
|
* refused with `AD_RESULT_ERR_INVALID_ARGS` — the protected-process
|
|
* guard is enforced inside the adapter, so FFI and CLI behave
|
|
* identically.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be non-null. `id` must be a non-null UTF-8 C string.
|
|
*/
|
|
AdResult ad_close_app(const struct AdAdapter *adapter, const char *id, bool force);
|
|
|
|
/**
|
|
* Launches the application identified by `id` (bundle id on macOS,
|
|
* executable path on other platforms) and, on success, writes the
|
|
* first window that becomes available into `*out`. Waits up to
|
|
* `timeout_ms` for the window to appear; zero means "no wait".
|
|
*
|
|
* The returned `AdWindowInfo` owns heap-allocated interior strings that
|
|
* must be released with `ad_release_window_fields` once done. On error
|
|
* the out-param is zero-initialized, so calling the release fn on it
|
|
* is a safe no-op.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be non-null. `id` must be a non-null UTF-8 C string.
|
|
* `out` must be a non-null writable `*mut AdWindowInfo`.
|
|
*/
|
|
AdResult ad_launch_app(const struct AdAdapter *adapter,
|
|
const char *id,
|
|
uint64_t timeout_ms,
|
|
struct AdWindowInfo *out);
|
|
|
|
/**
|
|
* Launches an application and returns a generation-pinned exact window.
|
|
*
|
|
* # Safety
|
|
* `adapter`, `id`, and `out` must satisfy the same requirements as
|
|
* `ad_launch_app`. Release the result with `ad_release_exact_window_fields`.
|
|
*/
|
|
AdResult ad_launch_app_exact(const struct AdAdapter *adapter,
|
|
const char *id,
|
|
uint64_t timeout_ms,
|
|
struct AdExactWindowInfo *out);
|
|
|
|
/**
|
|
* # Safety
|
|
* `adapter` must be a valid pointer from `ad_adapter_create`.
|
|
* `out` must be a valid writable `*mut *mut AdAppList`.
|
|
* On success, `*out` is a newly-allocated opaque list freed with
|
|
* `ad_app_list_free`. On error, `*out` is null and last-error is set.
|
|
*/
|
|
AdResult ad_list_apps(const struct AdAdapter *adapter, struct AdAppList **out);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_apps`.
|
|
*/
|
|
uint32_t ad_app_list_count(const struct AdAppList *list);
|
|
|
|
/**
|
|
* Returns a borrowed pointer into the list; valid until the list is freed.
|
|
* Out-of-range `index` returns null.
|
|
*
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_apps`.
|
|
*/
|
|
const struct AdAppInfo *ad_app_list_get(const struct AdAppList *list, uint32_t index);
|
|
|
|
/**
|
|
* Frees the list and every `AdAppInfo` it owns, including the interior
|
|
* C-strings.
|
|
*
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_apps`.
|
|
*/
|
|
void ad_app_list_free(struct AdAppList *list);
|
|
|
|
/**
|
|
* Drives a snapshot-qualified ref action (`@<snapshot_id>:e5`, action)
|
|
* through the canonical ref-action
|
|
* pipeline: `RefStore` load → `RefMap` lookup (→ `STALE_REF` on missing) →
|
|
* strict element resolution (→ `STALE_REF`/`AMBIGUOUS_TARGET`) → live
|
|
* actionability preflight → dispatch → owned-handle drop.
|
|
*
|
|
* Policy: semantic actions, including `TypeText`, default to strict
|
|
* `headless`. Explicit `PressKey` defaults to `focus_fallback`. A policy
|
|
* discriminant may elevate to focus fallback or headed. Base and elevation
|
|
* are computed by `agent_desktop_core::commands::execute_by_ref::execute` via
|
|
* `Action::base_interaction_policy` + `InteractionPolicy::join`, so CLI and
|
|
* FFI share a single source of policy truth.
|
|
*
|
|
* `ref_id` tri-state: null → `ErrInvalidArgs`; non-null invalid UTF-8 →
|
|
* `ErrInvalidArgs`; valid UTF-8 but bad `@e{N}` format → `ErrInvalidArgs`.
|
|
*
|
|
* `snapshot_id` tri-state: null is valid only when `ref_id` embeds its
|
|
* snapshot; valid UTF-8 pins a legacy bare `@eN` ref or must match the
|
|
* snapshot embedded in a qualified ref; invalid UTF-8 returns `ErrInvalidArgs`.
|
|
*
|
|
* `policy` is an `AdPolicyKind` discriminant (0=Headless, 1=FocusFallback,
|
|
* 2=Headed). An out-of-range value returns `ErrInvalidArgs`. `Headless (0)`
|
|
* accepts the action's base policy. `FocusFallback (1)` explicitly permits
|
|
* focus without cursor movement. `Headed (2)` opts in to physical cursor and
|
|
* keyboard delivery.
|
|
*
|
|
* Uses a fixed 5000ms auto-wait budget (`DEFAULT_ACTION_TIMEOUT_MS`) before
|
|
* the actionability preflight, matching the CLI default. Call
|
|
* `ad_execute_by_ref_timeout` with an explicit `timeout_ms` (-1 = default,
|
|
* 0 = single-shot with no auto-wait) to control this.
|
|
*
|
|
* On success `*out` is set to a NUL-terminated JSON envelope (command
|
|
* `"execute_by_ref"`); free with `ad_free_string`. On guard or decode
|
|
* failure (invalid args before the command runs) `*out` remains null.
|
|
* On a command-level error (STALE_REF, AMBIGUOUS_TARGET, etc.) `*out`
|
|
* holds the error JSON envelope and must still be freed with
|
|
* `ad_free_string`. The last-error slot is populated on all failures.
|
|
*
|
|
* **Dispatch-before-serialize ordering**: the action is dispatched (and any
|
|
* side effects committed) before the result JSON is serialized. In the
|
|
* near-impossible event that serialization of an already-valid
|
|
* `ActionResult` fails, `*out` is null and `ErrInternal` is returned while
|
|
* the side effect has already occurred. No pre-validation machinery is
|
|
* needed because serialization of a valid envelope effectively never fails.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer from `ad_adapter_create[_with_session]`.
|
|
* `ref_id` must be a non-null pointer to a NUL-terminated C string within
|
|
* `AD_MAX_STRING_BYTES + 1` bytes; null is **not** optional — it is defined
|
|
* behaviour (no UB) but is rejected immediately with `ErrInvalidArgs`.
|
|
* `snapshot_id` may be null only for a snapshot-qualified ref, or a non-null
|
|
* NUL-terminated C string within `AD_MAX_STRING_BYTES + 1` bytes. `action`
|
|
* must be a non-null pointer to a
|
|
* valid `AdAction`. `out` must be a non-null writable pointer. All pointers
|
|
* must remain valid for the duration of the call. Must be called from the
|
|
* calling thread.
|
|
*/
|
|
AdResult ad_execute_by_ref(const struct AdAdapter *adapter,
|
|
const char *ref_id,
|
|
const char *snapshot_id,
|
|
const struct AdAction *action,
|
|
int32_t policy,
|
|
char **out);
|
|
|
|
/**
|
|
* Same as `ad_execute_by_ref` but with an explicit pre-action auto-wait
|
|
* budget in milliseconds. `timeout_ms == -1` uses the 5000ms default and
|
|
* `timeout_ms == 0` disables auto-wait for a single-shot preflight.
|
|
*
|
|
* # Safety
|
|
*
|
|
* Same pointer and threading requirements as `ad_execute_by_ref`.
|
|
*/
|
|
AdResult ad_execute_by_ref_timeout(const struct AdAdapter *adapter,
|
|
const char *ref_id,
|
|
const char *snapshot_id,
|
|
const struct AdAction *action,
|
|
int32_t policy,
|
|
int64_t timeout_ms,
|
|
char **out);
|
|
|
|
/**
|
|
* Takes a full CLI-format snapshot of the target application window,
|
|
* allocates `@e` refs for all interactive elements, persists the refmap
|
|
* to disk, and writes the JSON envelope into `*out`.
|
|
*
|
|
* The JSON shape matches `agent-desktop snapshot`:
|
|
* `{"version":"2.1","ok":true,"command":"snapshot","data":{"app":"...","window":{...},"ref_count":N,"snapshot_id":"...","tree":{...}}}`.
|
|
*
|
|
* **`*out` ownership and error behaviour:**
|
|
* - On success (`AD_RESULT_OK`): `*out` is a heap-allocated JSON string with `"ok":true`.
|
|
* Caller must free it with `ad_free_string`.
|
|
* - On a command-level error (e.g. app not found, snapshot failure): `*out` is a
|
|
* heap-allocated JSON string with `"ok":false` and an `"error"` payload. Caller
|
|
* must still free it with `ad_free_string`. The last-error slot is also set.
|
|
* - On an argument or infrastructure error (null adapter, invalid
|
|
* UTF-8, bad surface discriminant, context failure): `*out` is set to null and no
|
|
* allocation is made. Only the last-error slot is set.
|
|
*
|
|
* `app` is tri-state:
|
|
* - null — snapshot the currently focused window (same as running the command with no `--app`).
|
|
* - valid UTF-8 string — snapshot the named application's focused window.
|
|
* - non-null but invalid UTF-8 or exceeding `AD_MAX_STRING_BYTES` — returns `ErrInvalidArgs`.
|
|
*
|
|
* `surface` is an `AdSnapshotSurface` discriminant (0 = Window, 1 = Focused, …).
|
|
* An out-of-range value returns `ErrInvalidArgs`.
|
|
*
|
|
* This entrypoint always targets the active focused window of the requested
|
|
* application; explicit window targeting (`window_id`) is not yet exposed
|
|
* over the ABI. Progressive traversal (skeleton mode and `--root` drill-down)
|
|
* is likewise not exposed here. Both are planned fast-follows to this
|
|
* entrypoint — agents needing them should use the CLI in the meantime.
|
|
*
|
|
* **Dispatch-before-serialize ordering**: the snapshot and refmap persistence
|
|
* occur before the result JSON is serialised. In the near-impossible event
|
|
* that serialisation of an already-valid result fails, `*out` is set to null
|
|
* and `ErrInternal` is returned while the refmap is already written.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer from `ad_adapter_create` or
|
|
* `ad_adapter_create_with_session`. `out` must be a non-null writable
|
|
* `*mut *mut c_char`. `app` must be null or a NUL-terminated string within
|
|
* `AD_MAX_STRING_BYTES + 1` bytes. All pointers must remain valid for the
|
|
* duration of the call.
|
|
*/
|
|
AdResult ad_snapshot(const struct AdAdapter *adapter,
|
|
const char *app,
|
|
int32_t surface,
|
|
uint8_t max_depth,
|
|
bool interactive_only,
|
|
bool compact,
|
|
char **out);
|
|
|
|
/**
|
|
* Returns the adapter's current health and permission state as a JSON
|
|
* envelope matching the `agent-desktop status` CLI output.
|
|
*
|
|
* `ad_status` does not query the accessibility tree; it reads the
|
|
* permission report and ref-store metadata only. Like other adapter
|
|
* entrypoints, it may be called from any host thread. On success `*out` is a
|
|
* NUL-terminated, heap-allocated JSON string freed with `ad_free_string`.
|
|
*
|
|
* On a command-level failure `*out` is set to a heap-allocated JSON string
|
|
* with `"ok":false` and an `"error"` payload. The caller must still release
|
|
* it with `ad_free_string(*out)`. The last-error slot is also set.
|
|
*
|
|
* On an argument or infrastructure failure (null adapter, null out, context
|
|
* error) `*out` is zeroed and only the last-error slot is populated.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`
|
|
* that has not been destroyed. `out` must be a non-null writable
|
|
* `*mut *mut c_char`.
|
|
*/
|
|
AdResult ad_status(const struct AdAdapter *adapter, char **out);
|
|
|
|
/**
|
|
* Exports the merged trace timeline for the adapter's active session as a
|
|
* single self-contained HTML file matching `agent-desktop trace export`.
|
|
*
|
|
* `limit` controls tail semantics: `0` embeds all events; the default `5000`
|
|
* matches the CLI. Pass `-1` to use the CLI default explicitly.
|
|
*
|
|
* `out_path` may be null; when set it must be a NUL-terminated UTF-8 path
|
|
* within `AD_MAX_STRING_BYTES + 1` bytes.
|
|
*
|
|
* On success `*out` is a heap-allocated JSON envelope freed with
|
|
* `ad_free_string`. On command-level failure `*out` still holds an error
|
|
* envelope that must be freed.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer from `ad_adapter_create` or
|
|
* `ad_adapter_create_with_session`. `out` must be non-null. `out_path`
|
|
* may be null or a NUL-terminated UTF-8 string within `AD_MAX_STRING_BYTES + 1`
|
|
* bytes.
|
|
*/
|
|
AdResult ad_trace_export(const struct AdAdapter *adapter,
|
|
int32_t limit,
|
|
const char *out_path,
|
|
char **out);
|
|
|
|
/**
|
|
* Returns the merged trace timeline for the adapter's active session as a
|
|
* JSON envelope matching `agent-desktop trace show`.
|
|
*
|
|
* `limit` controls tail semantics: `0` embeds all events; the default `500`
|
|
* matches the CLI. Pass `-1` to use the CLI default explicitly.
|
|
*
|
|
* `event_prefix` may be null; when set, only events whose name starts with the
|
|
* prefix are returned before the tail limit is applied.
|
|
*
|
|
* On success `*out` is a heap-allocated JSON envelope freed with
|
|
* `ad_free_string`. On command-level failure `*out` still holds an error
|
|
* envelope that must be freed.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer from `ad_adapter_create` or
|
|
* `ad_adapter_create_with_session`. `out` must be non-null. `event_prefix`
|
|
* may be null or a NUL-terminated UTF-8 string within `AD_MAX_STRING_BYTES + 1`
|
|
* bytes.
|
|
*/
|
|
AdResult ad_trace_show(const struct AdAdapter *adapter,
|
|
int32_t limit,
|
|
const char *event_prefix,
|
|
char **out);
|
|
|
|
/**
|
|
* Returns the `agent-desktop` version envelope as an owned JSON C string.
|
|
*
|
|
* The returned string has the same `{version, ok, command, data}` shape
|
|
* as `agent-desktop version` on the CLI. Free it with `ad_free_string`.
|
|
*
|
|
* On success `*out` points to the envelope JSON.
|
|
* On error `*out` is null and the last-error slot is populated.
|
|
*
|
|
* # Safety
|
|
* `out` must be a non-null writable `*mut *mut c_char`.
|
|
*/
|
|
AdResult ad_version(char **out);
|
|
|
|
/**
|
|
* Runs `wait` with the given args, blocking the calling thread until the
|
|
* condition is met or `timeout_ms` elapses.
|
|
*
|
|
* On success `*out` is set to a freshly allocated JSON string containing the
|
|
* CLI-format wait envelope (`{version, ok, command, data}`). The caller must
|
|
* release the string with `ad_free_string(*out)`.
|
|
*
|
|
* On a command-level failure (e.g. `TIMEOUT`, `ELEMENT_NOT_FOUND`) `*out` is
|
|
* set to a freshly allocated JSON string with `"ok":false` and an `"error"`
|
|
* payload. The caller must still release it with `ad_free_string(*out)`. The
|
|
* last-error slot is also set.
|
|
*
|
|
* On an argument or infrastructure failure (null adapter, null args, null out,
|
|
* invalid UTF-8 field) `*out` is zeroed, the last-error slot
|
|
* is set, and a negative `AdResult` code is returned. No allocation is made.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create` that
|
|
* has not been destroyed. `args` must be non-null and point to a valid
|
|
* zero-initialized `AdWaitArgs`. `out` must be non-null and point to a
|
|
* writable `*mut c_char`.
|
|
*
|
|
* All `*const c_char` fields inside `AdWaitArgs` must be null or point to
|
|
* readable, NUL-terminated memory within `AD_MAX_STRING_BYTES + 1` bytes.
|
|
*
|
|
* `ad_wait` retains the adapter while blocked. Concurrent destruction revokes
|
|
* the opaque adapter token for new calls without invalidating this call.
|
|
*/
|
|
AdResult ad_wait(const struct AdAdapter *adapter, const struct AdWaitArgs *args, char **out);
|
|
|
|
/**
|
|
* Lists displays in screenshot screen-index order.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be valid and `out` must be writable. Success produces an
|
|
* opaque list freed with `ad_display_list_free`.
|
|
*/
|
|
AdResult ad_list_displays(const struct AdAdapter *adapter, struct AdDisplayList **out);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or returned by `ad_list_displays`.
|
|
*/
|
|
uint32_t ad_display_list_count(const struct AdDisplayList *list);
|
|
|
|
/**
|
|
* Returns a borrowed display entry, or null when `index` is out of range.
|
|
*
|
|
* # Safety
|
|
* `list` must be null or returned by `ad_list_displays`.
|
|
*/
|
|
const struct AdDisplayInfo *ad_display_list_get(const struct AdDisplayList *list, uint32_t index);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or returned by `ad_list_displays`.
|
|
*/
|
|
void ad_display_list_free(struct AdDisplayList *list);
|
|
|
|
/**
|
|
* Last-error lifetime — errno-style.
|
|
*
|
|
* The pointer returned by `ad_last_error_message`,
|
|
* `ad_last_error_suggestion`, and `ad_last_error_platform_detail`
|
|
* remains valid across any number of subsequent **successful** FFI
|
|
* calls on the same thread. Only the next FFI call that itself **fails**
|
|
* (returns a non-`AD_RESULT_OK` code) invalidates the previous pointers.
|
|
*
|
|
* Consumers can therefore read an error once, cache the pointer, and
|
|
* keep reading it back across follow-up work that clears or re-fetches
|
|
* state before handing control to the user.
|
|
*
|
|
* This matches the POSIX `errno` / `strerror` contract and is scoped
|
|
* per-thread via thread-local storage — Thread A's last-error never
|
|
* leaks to Thread B.
|
|
* Returns the `AdResult` code of the last error on the calling thread,
|
|
* or `AD_RESULT_OK` if no error has been recorded.
|
|
*/
|
|
AdResult ad_last_error_code(void);
|
|
|
|
/**
|
|
* Returns a borrowed C string describing the last error, or null if no
|
|
* error has been recorded on the calling thread. The pointer remains
|
|
* valid across any number of subsequent *successful* FFI calls; only
|
|
* the next failing call overwrites it.
|
|
*/
|
|
const char *ad_last_error_message(void);
|
|
|
|
/**
|
|
* Returns a borrowed C string with a human-readable suggestion for how
|
|
* to recover from the last error, or null if the adapter didn't emit
|
|
* one. Same lifetime rules as `ad_last_error_message`.
|
|
*/
|
|
const char *ad_last_error_suggestion(void);
|
|
|
|
/**
|
|
* Returns a borrowed C string carrying a platform-specific diagnostic
|
|
* for the last error (AX error codes, COM HRESULTs, AT-SPI messages,
|
|
* etc.), or null if the adapter didn't supply one. Same lifetime rules
|
|
* as `ad_last_error_message`.
|
|
*/
|
|
const char *ad_last_error_platform_detail(void);
|
|
|
|
/**
|
|
* Returns a borrowed JSON string carrying structured details for the last
|
|
* error, or null if the adapter didn't supply any. Same lifetime rules as
|
|
* `ad_last_error_message`. Details may contain element names, values, and
|
|
* window titles from the user's screen; treat as sensitive diagnostics and
|
|
* avoid routing to shared log surfaces.
|
|
*/
|
|
const char *ad_last_error_details(void);
|
|
|
|
/**
|
|
* Writes the delivery and retry semantics associated with the calling
|
|
* thread's last error. If no error has been recorded, both values are
|
|
* `UNKNOWN`. This successful read does not clear or replace last-error state.
|
|
*
|
|
* # Safety
|
|
*
|
|
* `out` must point to writable `AdDeliverySemantics` storage.
|
|
*/
|
|
AdResult ad_last_error_delivery_semantics(struct AdDeliverySemantics *out);
|
|
|
|
/**
|
|
* Reads the current clipboard text and writes an owned C string into
|
|
* `*out`. The caller must free the returned pointer with
|
|
* `ad_free_string`. On error `*out` is left null.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
* `out` must be a non-null writable `*mut *mut c_char`.
|
|
*/
|
|
AdResult ad_get_clipboard(const struct AdAdapter *adapter, char **out);
|
|
|
|
/**
|
|
* Writes UTF-8 `text` to the clipboard. Null or non-UTF-8 input returns
|
|
* `AD_RESULT_ERR_INVALID_ARGS` with a diagnostic last-error.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
* `text` must be a non-null, NUL-terminated UTF-8 C string.
|
|
*/
|
|
AdResult ad_set_clipboard(const struct AdAdapter *adapter, const char *text);
|
|
|
|
/**
|
|
* Clears the clipboard.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
*/
|
|
AdResult ad_clear_clipboard(const struct AdAdapter *adapter);
|
|
|
|
/**
|
|
* Frees a C string previously returned by `ad_get_clipboard` or any
|
|
* other FFI call documented as allocating a C string for the caller.
|
|
* Null-tolerant. Unknown pointers and repeated frees are ignored.
|
|
*
|
|
* # Safety
|
|
* `s` may be null or a pointer previously handed out by this crate.
|
|
* After a successful free the pointer is invalid and must not be used.
|
|
*/
|
|
void ad_free_string(char *s);
|
|
|
|
/**
|
|
* Synthesizes an explicit physical mouse drag from `params.from` to
|
|
* `params.to`. When `params.duration_ms` is zero the drag is instantaneous;
|
|
* a non-zero value asks the platform adapter to interpolate. Callers that
|
|
* need headless policy enforcement should use ref actions with policy.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
* `params` must be a non-null pointer to a valid `AdDragParams`.
|
|
*/
|
|
AdResult ad_drag(const struct AdAdapter *adapter, const struct AdDragParams *params);
|
|
|
|
/**
|
|
* Dispatches an explicit physical mouse event (move / down / up / click)
|
|
* at the given screen point. Click count is only consulted when `event.kind`
|
|
* is `CLICK` (e.g., `click_count == 2` for a double-click). Callers that
|
|
* need headless policy enforcement should use ref actions with policy.
|
|
* Carries no modifier chord — use [`ad_mouse_event_with_modifiers`] for
|
|
* meta/ctrl/alt/shift-held clicks.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
* `event` must be a non-null pointer to a valid `AdMouseEvent`.
|
|
*/
|
|
AdResult ad_mouse_event(const struct AdAdapter *adapter, const struct AdMouseEvent *event);
|
|
|
|
/**
|
|
* Additive counterpart to [`ad_mouse_event`] that also carries a held
|
|
* modifier chord (meta/ctrl/alt/shift) — e.g. Meta-click for additive
|
|
* selection, shift-click for range selection. `AdMouseEvent`'s layout is
|
|
* unchanged; modifiers travel as a separate array + count, mirroring
|
|
* `AdKeyCombo::modifiers`/`modifier_count`.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
* `event` must be a non-null pointer to a valid `AdMouseEvent`.
|
|
* `modifiers` must point to `modifier_count` valid `int32_t` values, or be
|
|
* null when `modifier_count` is 0.
|
|
*/
|
|
AdResult ad_mouse_event_with_modifiers(const struct AdAdapter *adapter,
|
|
const struct AdMouseEvent *event,
|
|
const int32_t *modifiers,
|
|
uint32_t modifier_count);
|
|
|
|
/**
|
|
* Dispatches a physical wheel event using platform-neutral line deltas.
|
|
* Positive `delta_y` scrolls up and negative scrolls down; positive
|
|
* `delta_x` scrolls left and negative scrolls right. `modifier_mask` uses
|
|
* bits 0-3 for meta, ctrl, alt, and shift respectively.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be a non-null pointer returned by `ad_adapter_create`.
|
|
*/
|
|
AdResult ad_mouse_wheel(const struct AdAdapter *adapter,
|
|
struct AdPoint point,
|
|
double delta_x,
|
|
double delta_y,
|
|
uint32_t modifier_mask);
|
|
|
|
/**
|
|
* Registers or clears the callback used for events emitted synchronously
|
|
* inside later `ad_*` calls on the same thread.
|
|
*
|
|
* The callback may be invoked concurrently by different host threads. The
|
|
* message pointer is valid only until the callback returns. The callback must
|
|
* not unwind across this C ABI boundary; C++ exceptions and Rust panics must
|
|
* be caught inside the callback. Violating that contract may abort the host.
|
|
*/
|
|
AdResult ad_set_log_callback(void (*callback)(int32_t level, const char *msg));
|
|
|
|
/**
|
|
* Triggers the named action on the notification at `index`. Typical
|
|
* action names are those reported in `AdNotificationInfo.actions`
|
|
* (e.g. `"Reply"`, `"Open"`).
|
|
*
|
|
* ## Identity / reorder safety
|
|
*
|
|
* Notification Center reindexes entries on every listing — a new
|
|
* notification arriving (or another one being dismissed) shifts which
|
|
* notification sits at any given `index`. Calling this function with
|
|
* an index obtained from a prior `ad_list_notifications` can therefore
|
|
* press the action button on a different notification than the host
|
|
* intended.
|
|
*
|
|
* `request.identity` pins the target to an observed fingerprint. At least one
|
|
* identity field is required; a mismatch fails closed with
|
|
* `AD_RESULT_ERR_NOTIFICATION_NOT_FOUND`.
|
|
*
|
|
* # Safety
|
|
* `adapter` and `request` must be valid. `request.action_name` must be a
|
|
* non-null UTF-8 C string. Identity fields must each be null or a
|
|
* NUL-terminated UTF-8 C string. Invalid UTF-8 in either field
|
|
* is rejected with `AD_RESULT_ERR_INVALID_ARGS` rather than silently
|
|
* treated as "no fingerprint". `out` must be a valid writable
|
|
* `*mut AdActionResult`; on error it is zero-initialized.
|
|
*/
|
|
AdResult ad_notification_action(const struct AdAdapter *adapter,
|
|
const struct AdNotificationActionRequest *request,
|
|
struct AdActionResult *out);
|
|
|
|
/**
|
|
* Dismisses a notification only when the current row matches an identity
|
|
* observed in the same listing. At least one expected field is required.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be valid. String pointers may be null and otherwise must be
|
|
* NUL-terminated UTF-8.
|
|
*/
|
|
AdResult ad_dismiss_notification(const struct AdAdapter *adapter,
|
|
uint32_t index,
|
|
const char *app_filter,
|
|
const char *expected_app,
|
|
const char *expected_title);
|
|
|
|
/**
|
|
* Dismisses every notification matching `app_filter` (null = all apps).
|
|
*
|
|
* Returns two lists: `dismissed_out` carries the notifications that
|
|
* were successfully dismissed; `failed_out` holds error strings for
|
|
* notifications where the platform rejected the dismiss. Partial
|
|
* failures do not set last-error — inspect `failed_out` for details.
|
|
*
|
|
* `failed_out` uses the notification-list handle to stay ABI-consistent
|
|
* with the other list-returning FFI calls; the entries carry the
|
|
* original notification shape with `body` populated by the platform
|
|
* error message.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be valid. `app_filter` may be null. `dismissed_out`
|
|
* and `failed_out` must both be valid writable `*mut *mut AdNotificationList`.
|
|
*/
|
|
AdResult ad_dismiss_all_notifications(const struct AdAdapter *adapter,
|
|
const char *app_filter,
|
|
struct AdNotificationList **dismissed_out,
|
|
struct AdNotificationList **failed_out);
|
|
|
|
/**
|
|
* Convenience wrapper: free both lists returned by
|
|
* `ad_dismiss_all_notifications`. Equivalent to calling
|
|
* `ad_notification_list_free` on each; provided for symmetry.
|
|
*
|
|
* # Safety
|
|
* Both arguments must be null or pointers from
|
|
* `ad_dismiss_all_notifications`.
|
|
*/
|
|
void ad_dismiss_all_notifications_free(struct AdNotificationList *dismissed,
|
|
struct AdNotificationList *failed);
|
|
|
|
/**
|
|
* Lists the notifications currently on-screen.
|
|
*
|
|
* Notification indexes are only stable within a single list response. Pass
|
|
* the entry's app or title fingerprint to the checked mutation functions;
|
|
* index-only mutations are rejected.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be valid. `filter` may be null. `out` must be a valid
|
|
* writable `*mut *mut AdNotificationList`. On success `*out` is a
|
|
* non-null handle freed with `ad_notification_list_free`.
|
|
*/
|
|
AdResult ad_list_notifications(const struct AdAdapter *adapter,
|
|
const struct AdNotificationFilter *filter,
|
|
struct AdNotificationList **out);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_notifications`.
|
|
*/
|
|
uint32_t ad_notification_list_count(const struct AdNotificationList *list);
|
|
|
|
/**
|
|
* Borrows a notification entry. Null if `index` is out of range.
|
|
*
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_notifications`.
|
|
*/
|
|
const struct AdNotificationInfo *ad_notification_list_get(const struct AdNotificationList *list,
|
|
uint32_t index);
|
|
|
|
/**
|
|
* Frees the list and each entry's interior strings.
|
|
*
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_notifications`.
|
|
*/
|
|
void ad_notification_list_free(struct AdNotificationList *list);
|
|
|
|
/**
|
|
* Legacy ABI compatibility entrypoint. `AdWindowInfo` cannot carry process
|
|
* generation, so this function fails closed with `AD_RESULT_ERR_INVALID_ARGS`.
|
|
* Use `ad_find_exact`.
|
|
*
|
|
* # Safety
|
|
* `adapter`, `win`, and `query` must be valid pointers. `out_handle`
|
|
* must be a valid writable `*mut AdNativeHandle`. On
|
|
* `AD_RESULT_ERR_ELEMENT_NOT_FOUND` the out-handle is zero-initialized.
|
|
*/
|
|
AdResult ad_find(const struct AdAdapter *adapter,
|
|
const struct AdWindowInfo *win,
|
|
const struct AdFindQuery *query,
|
|
struct AdNativeHandle *out_handle);
|
|
|
|
/**
|
|
* Finds and strictly resolves one element within a generation-pinned window.
|
|
* `AdFindQuery.control.selection` must explicitly request first, last, or nth
|
|
* behavior when duplicate matches are acceptable. The returned native handle
|
|
* is adapter-bound and thread-affine; release it with `ad_free_handle` on the
|
|
* resolving thread.
|
|
*
|
|
* # Safety
|
|
* All pointers must be valid and `out_handle` must be writable.
|
|
*/
|
|
AdResult ad_find_exact(const struct AdAdapter *adapter,
|
|
const struct AdExactWindowInfo *win,
|
|
const struct AdFindQuery *query,
|
|
struct AdNativeHandle *out_handle);
|
|
|
|
/**
|
|
* Reads a single property off a previously-resolved element handle.
|
|
*
|
|
* Supported properties:
|
|
* - `"value"` — live textual value (text fields, sliders, progress
|
|
* indicators). Null out-string when the element has no value.
|
|
* - `"bounds"` — JSON-encoded `{"x":..,"y":..,"width":..,"height":..}`.
|
|
* Null out-string when bounds are unavailable.
|
|
*
|
|
* The returned string must be freed with `ad_free_string`.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be valid. `handle` must be a non-null `AdNativeHandle`
|
|
* produced by the same live adapter and freed before that adapter is destroyed.
|
|
* `property` must be a non-null UTF-8 C string. `out` must be a valid
|
|
* writable `*mut *mut c_char`; it is null-initialized on entry.
|
|
*/
|
|
AdResult ad_get(const struct AdAdapter *adapter,
|
|
const struct AdNativeHandle *handle,
|
|
const char *property,
|
|
char **out);
|
|
|
|
/**
|
|
* Legacy ABI compatibility entrypoint. `AdWindowInfo` cannot carry process
|
|
* generation, so this function fails closed with `AD_RESULT_ERR_INVALID_ARGS`.
|
|
* Use `ad_is_exact`.
|
|
*
|
|
* # Safety
|
|
* All pointers must be valid. `property` must be a non-null UTF-8 C string.
|
|
* `out` must be a valid writable `*mut bool`.
|
|
*/
|
|
AdResult ad_is(const struct AdAdapter *adapter,
|
|
const struct AdWindowInfo *win,
|
|
const struct AdFindQuery *query,
|
|
const char *property,
|
|
bool *out);
|
|
|
|
/**
|
|
* Checks a boolean state within a generation-pinned exact window.
|
|
*
|
|
* # Safety
|
|
* All pointers must be valid and `out` must be writable.
|
|
*/
|
|
AdResult ad_is_exact(const struct AdAdapter *adapter,
|
|
const struct AdExactWindowInfo *win,
|
|
const struct AdFindQuery *query,
|
|
const char *property,
|
|
bool *out);
|
|
|
|
#if defined(AGENT_DESKTOP_TEST_PANIC_INJECTION)
|
|
AdResult ad_test_panic_boundary(void);
|
|
#endif
|
|
|
|
/**
|
|
* Borrowed pointer to the image bytes; valid until the buffer is freed.
|
|
* Returns null if `buf` is null.
|
|
*
|
|
* # Safety
|
|
* `buf` must be null or returned by `ad_screenshot`.
|
|
*/
|
|
const uint8_t *ad_image_buffer_data(const struct AdImageBuffer *buf);
|
|
|
|
/**
|
|
* Byte length of the buffer returned by `ad_image_buffer_data`.
|
|
* Always consistent with the actual allocation (no C-mutable mismatch).
|
|
*
|
|
* # Safety
|
|
* `buf` must be null or returned by `ad_screenshot`.
|
|
*/
|
|
uint64_t ad_image_buffer_size(const struct AdImageBuffer *buf);
|
|
|
|
/**
|
|
* Pixel width of the image.
|
|
*
|
|
* # Safety
|
|
* `buf` must be null or returned by `ad_screenshot`.
|
|
*/
|
|
uint32_t ad_image_buffer_width(const struct AdImageBuffer *buf);
|
|
|
|
/**
|
|
* Pixel height of the image.
|
|
*
|
|
* # Safety
|
|
* `buf` must be null or returned by `ad_screenshot`.
|
|
*/
|
|
uint32_t ad_image_buffer_height(const struct AdImageBuffer *buf);
|
|
|
|
/**
|
|
* Encoding format of the image bytes. Defaults to `PNG` on a null
|
|
* handle — callers must still null-check.
|
|
*
|
|
* # Safety
|
|
* `buf` must be null or returned by `ad_screenshot`.
|
|
*/
|
|
AdImageFormat ad_image_buffer_format(const struct AdImageBuffer *buf);
|
|
|
|
/**
|
|
* Point-to-pixel scale factor for the captured display or window.
|
|
*
|
|
* # Safety
|
|
* `buf` must be null or returned by `ad_screenshot`.
|
|
*/
|
|
double ad_image_buffer_scale_factor(const struct AdImageBuffer *buf);
|
|
|
|
/**
|
|
* Allocates and returns an opaque `AdImageBuffer`. The handle owns its
|
|
* byte buffer; inspect it through `ad_image_buffer_data` /
|
|
* `ad_image_buffer_size` / `ad_image_buffer_format` / `_width` / `_height`
|
|
* and free it with `ad_image_buffer_free`.
|
|
*
|
|
* # Safety
|
|
* `adapter` and `target` must be valid pointers. `out` must be a valid
|
|
* writable `*mut *mut AdImageBuffer`. On error `*out` is null and
|
|
* last-error is set.
|
|
*/
|
|
AdResult ad_screenshot(const struct AdAdapter *adapter,
|
|
const struct AdScreenshotTarget *target,
|
|
struct AdImageBuffer **out);
|
|
|
|
/**
|
|
* Captures one generation-pinned exact window.
|
|
*
|
|
* # Safety
|
|
* `adapter`, `window`, and `out` must be valid pointers. The returned image
|
|
* must be freed with `ad_image_buffer_free`.
|
|
*/
|
|
AdResult ad_screenshot_window_exact(const struct AdAdapter *adapter,
|
|
const struct AdExactWindowInfo *window,
|
|
struct AdImageBuffer **out);
|
|
|
|
/**
|
|
* Frees the image buffer allocated by `ad_screenshot`.
|
|
*
|
|
* # Safety
|
|
* `buf` must be null or a pointer previously returned by `ad_screenshot`.
|
|
* Double-free is undefined behavior.
|
|
*/
|
|
void ad_image_buffer_free(struct AdImageBuffer *buf);
|
|
|
|
/**
|
|
* # Safety
|
|
* `adapter` must be valid. `out` must be a valid writable
|
|
* `*mut *mut AdSurfaceList`. Success produces a list handle freed via
|
|
* `ad_surface_list_free`.
|
|
*/
|
|
AdResult ad_list_surfaces(const struct AdAdapter *adapter,
|
|
uint32_t pid,
|
|
struct AdSurfaceList **out);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_surfaces`.
|
|
*/
|
|
uint32_t ad_surface_list_count(const struct AdSurfaceList *list);
|
|
|
|
/**
|
|
* Borrow a surface info entry. Null if `index` is out of range.
|
|
*
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_surfaces`.
|
|
*/
|
|
const struct AdSurfaceInfo *ad_surface_list_get(const struct AdSurfaceList *list, uint32_t index);
|
|
|
|
/**
|
|
* Frees the list and each entry's interior strings.
|
|
*
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_surfaces`.
|
|
*/
|
|
void ad_surface_list_free(struct AdSurfaceList *list);
|
|
|
|
/**
|
|
* Lists surfaces without dropping their core surface IDs.
|
|
*
|
|
* # Safety
|
|
* `adapter` and `out` must be valid. The returned list must be freed with
|
|
* `ad_exact_surface_list_free`.
|
|
*/
|
|
AdResult ad_list_surfaces_exact(const struct AdAdapter *adapter,
|
|
uint32_t pid,
|
|
struct AdExactSurfaceList **out);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or returned by `ad_list_surfaces_exact`.
|
|
*/
|
|
uint32_t ad_exact_surface_list_count(const struct AdExactSurfaceList *list);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or returned by `ad_list_surfaces_exact`. The result is
|
|
* borrowed until the list is freed.
|
|
*/
|
|
const struct AdExactSurfaceInfo *ad_exact_surface_list_get(const struct AdExactSurfaceList *list,
|
|
uint32_t index);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or returned by `ad_list_surfaces_exact`.
|
|
*/
|
|
void ad_exact_surface_list_free(struct AdExactSurfaceList *list);
|
|
|
|
/**
|
|
* # Safety
|
|
* `tree` must be null or point to a valid `AdNodeTree` previously returned
|
|
* by `flatten_tree` or `ad_get_tree`. After this call the tree is zeroed.
|
|
*/
|
|
void ad_free_tree(struct AdNodeTree *tree);
|
|
|
|
/**
|
|
* Legacy ABI compatibility entrypoint. `AdWindowInfo` cannot carry process
|
|
* generation, so this function fails closed with `AD_RESULT_ERR_INVALID_ARGS`.
|
|
* Use `ad_get_tree_exact`.
|
|
*
|
|
* # Safety
|
|
* All pointers must be non-null and `out` must be writable.
|
|
*/
|
|
AdResult ad_get_tree(const struct AdAdapter *adapter,
|
|
const struct AdWindowInfo *win,
|
|
const struct AdTreeOptions *opts,
|
|
struct AdNodeTree *out);
|
|
|
|
/**
|
|
* Snapshots a generation-pinned window into the flat, owned, breadth-first C
|
|
* tree layout. Direct children are contiguous at
|
|
* `nodes[child_start..child_start + child_count]`; free the result with
|
|
* `ad_free_tree`.
|
|
*
|
|
* This is a raw adapter tree: nodes do not receive refs, no refmap is
|
|
* persisted, and no JSON envelope is produced. `max_depth`, `surface`,
|
|
* `include_bounds`, `interactive_only`, and `compact` are applied; skeleton
|
|
* and drill-down behavior are not. Use `ad_snapshot` for the canonical
|
|
* observe-act workflow with snapshot-qualified refs.
|
|
*
|
|
* # Safety
|
|
* All pointers must be valid and `out` must be writable.
|
|
*/
|
|
AdResult ad_get_tree_exact(const struct AdAdapter *adapter,
|
|
const struct AdExactWindowInfo *win,
|
|
const struct AdTreeOptions *opts,
|
|
struct AdNodeTree *out);
|
|
|
|
size_t ad_action_size(void);
|
|
|
|
size_t ad_action_result_size(void);
|
|
|
|
size_t ad_action_step_size(void);
|
|
|
|
size_t ad_display_info_size(void);
|
|
|
|
size_t ad_drag_params_size(void);
|
|
|
|
size_t ad_element_state_size(void);
|
|
|
|
size_t ad_exact_ref_entry_size(void);
|
|
|
|
size_t ad_exact_surface_info_size(void);
|
|
|
|
size_t ad_exact_window_info_size(void);
|
|
|
|
size_t ad_ref_entry_size(void);
|
|
|
|
/**
|
|
* Returns the size of `AdWaitArgs` as compiled. Ctypes and other
|
|
* foreign bindings must call this and compare against their own
|
|
* `sizeof` before passing args to `ad_wait`.
|
|
*/
|
|
size_t ad_wait_args_size(void);
|
|
|
|
/**
|
|
* Legacy ABI compatibility entrypoint. `AdWindowInfo` cannot carry process
|
|
* generation, so this function fails closed with `AD_RESULT_ERR_INVALID_ARGS`.
|
|
* Use `ad_focus_window_exact`.
|
|
*
|
|
* # Safety
|
|
* `adapter` must be a non-null pointer from `ad_adapter_create`. `win`
|
|
* must be a non-null pointer to an `AdWindowInfo`.
|
|
*/
|
|
AdResult ad_focus_window(const struct AdAdapter *adapter, const struct AdWindowInfo *win);
|
|
|
|
/**
|
|
* Focuses a generation-pinned exact window.
|
|
*
|
|
* # Safety
|
|
* `adapter` and `win` must be valid pointers. `win` must carry the current
|
|
* exact-window version and size.
|
|
*/
|
|
AdResult ad_focus_window_exact(const struct AdAdapter *adapter,
|
|
const struct AdExactWindowInfo *win);
|
|
|
|
/**
|
|
* Releases the heap-allocated string fields (`id`, `title`, `app_name`)
|
|
* inside a single `AdWindowInfo` previously written by `ad_launch_app`
|
|
* or returned through a list accessor. Does not free the `AdWindowInfo`
|
|
* struct itself — that memory is owned by the caller's stack or by the
|
|
* enclosing list.
|
|
*
|
|
* Named `ad_release_window_fields` (not `ad_free_window`) to disambiguate
|
|
* from the now-removed list-free function and make the semantics clear
|
|
* in the header.
|
|
*
|
|
* # Safety
|
|
* `win` must be null or point to a valid `AdWindowInfo` whose string
|
|
* fields were allocated by this crate. Do not call on pointers inside
|
|
* an `AdWindowList` — free the list instead.
|
|
*/
|
|
void ad_release_window_fields(struct AdWindowInfo *win);
|
|
|
|
/**
|
|
* Releases every owned string inside one exact window value.
|
|
*
|
|
* # Safety
|
|
* `win` must be null or point to a value written by `ad_launch_app_exact`.
|
|
*/
|
|
void ad_release_exact_window_fields(struct AdExactWindowInfo *win);
|
|
|
|
/**
|
|
* # Safety
|
|
* `adapter` must be valid. `out` must be a valid writable
|
|
* `*mut *mut AdWindowList`. `app_filter` may be null or a C string.
|
|
* Success produces a list handle freed via `ad_window_list_free`.
|
|
*/
|
|
AdResult ad_list_windows(const struct AdAdapter *adapter,
|
|
const char *app_filter,
|
|
bool focused_only,
|
|
struct AdWindowList **out);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_windows`.
|
|
*/
|
|
uint32_t ad_window_list_count(const struct AdWindowList *list);
|
|
|
|
/**
|
|
* Borrow a window info entry. Null if `index` is out of range.
|
|
*
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_windows`.
|
|
*/
|
|
const struct AdWindowInfo *ad_window_list_get(const struct AdWindowList *list, uint32_t index);
|
|
|
|
/**
|
|
* Frees the list and each entry's interior strings.
|
|
*
|
|
* # Safety
|
|
* `list` must be null or a pointer returned by `ad_list_windows`.
|
|
*/
|
|
void ad_window_list_free(struct AdWindowList *list);
|
|
|
|
/**
|
|
* Lists windows with explicit process-generation evidence.
|
|
*
|
|
* # Safety
|
|
* `adapter` and `out` must be valid. `app_filter` may be null or a valid
|
|
* bounded UTF-8 C string. The returned list must be freed with
|
|
* `ad_exact_window_list_free`.
|
|
*/
|
|
AdResult ad_list_windows_exact(const struct AdAdapter *adapter,
|
|
const char *app_filter,
|
|
bool focused_only,
|
|
struct AdExactWindowList **out);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or returned by `ad_list_windows_exact`.
|
|
*/
|
|
uint32_t ad_exact_window_list_count(const struct AdExactWindowList *list);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or returned by `ad_list_windows_exact`. The returned
|
|
* pointer is borrowed until the list is freed.
|
|
*/
|
|
const struct AdExactWindowInfo *ad_exact_window_list_get(const struct AdExactWindowList *list,
|
|
uint32_t index);
|
|
|
|
/**
|
|
* # Safety
|
|
* `list` must be null or returned by `ad_list_windows_exact`.
|
|
*/
|
|
void ad_exact_window_list_free(struct AdExactWindowList *list);
|
|
|
|
/**
|
|
* Legacy ABI compatibility entrypoint. `AdWindowInfo` cannot carry process
|
|
* generation, so this function fails closed with `AD_RESULT_ERR_INVALID_ARGS`.
|
|
* Use `ad_window_op_exact`.
|
|
*
|
|
* # Safety
|
|
* `adapter` and `win` must be non-null pointers.
|
|
*/
|
|
AdResult ad_window_op(const struct AdAdapter *adapter,
|
|
const struct AdWindowInfo *win,
|
|
struct AdWindowOp op);
|
|
|
|
/**
|
|
* Performs a window-manager operation against an exact generation-pinned
|
|
* window identity.
|
|
*
|
|
* # Safety
|
|
* `adapter` and `win` must be valid pointers. `win` must carry the current
|
|
* exact-window version and size.
|
|
*/
|
|
AdResult ad_window_op_exact(const struct AdAdapter *adapter,
|
|
const struct AdExactWindowInfo *win,
|
|
struct AdWindowOp op);
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif // __cplusplus
|
|
|
|
#endif /* AGENT_DESKTOP_H */
|
|
|
|
/* C11 ABI layout guards — auto-generated; do not hand-edit.
|
|
* Each sizeof check references the AD_*_SIZE macro defined above so the
|
|
* size literal lives in exactly one place (the Rust source). Alignment
|
|
* and offset values are structurally fixed on all 64-bit targets.
|
|
* The one-shot guard makes double-include safe regardless of C standard. */
|
|
#ifndef AGENT_DESKTOP_ABI_ASSERTS
|
|
#define AGENT_DESKTOP_ABI_ASSERTS
|
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
|
_Static_assert(sizeof(AdDragParams) == AD_DRAG_PARAMS_SIZE, "AdDragParams ABI size changed");
|
|
_Static_assert(_Alignof(AdDragParams) == 8, "AdDragParams ABI alignment changed");
|
|
_Static_assert(sizeof(AdAction) == AD_ACTION_SIZE, "AdAction ABI size changed");
|
|
_Static_assert(_Alignof(AdAction) == 8, "AdAction ABI alignment changed");
|
|
_Static_assert(sizeof(AdElementState) == AD_ELEMENT_STATE_SIZE, "AdElementState ABI size changed");
|
|
_Static_assert(_Alignof(AdElementState) == 8, "AdElementState ABI alignment changed");
|
|
_Static_assert(sizeof(AdActionStep) == AD_ACTION_STEP_SIZE, "AdActionStep ABI size changed");
|
|
_Static_assert(_Alignof(AdActionStep) == 8, "AdActionStep ABI alignment changed");
|
|
_Static_assert(offsetof(AdActionStep, label) == 0, "AdActionStep.label offset changed");
|
|
_Static_assert(offsetof(AdActionStep, outcome) == 8, "AdActionStep.outcome offset changed");
|
|
_Static_assert(offsetof(AdActionStep, mechanism) == 16, "AdActionStep.mechanism offset changed");
|
|
_Static_assert(offsetof(AdActionStep, has_mechanism) == 20, "AdActionStep.has_mechanism offset changed");
|
|
_Static_assert(offsetof(AdActionStep, verified) == 21, "AdActionStep.verified offset changed");
|
|
_Static_assert(offsetof(AdActionStep, has_verified) == 22, "AdActionStep.has_verified offset changed");
|
|
_Static_assert(sizeof(AdActionResult) == AD_ACTION_RESULT_SIZE, "AdActionResult ABI size changed");
|
|
_Static_assert(_Alignof(AdActionResult) == 8, "AdActionResult ABI alignment changed");
|
|
_Static_assert(offsetof(AdActionResult, action) == 0, "AdActionResult.action offset changed");
|
|
_Static_assert(offsetof(AdActionResult, ref_id) == 8, "AdActionResult.ref_id offset changed");
|
|
_Static_assert(offsetof(AdActionResult, post_state) == 16, "AdActionResult.post_state offset changed");
|
|
_Static_assert(offsetof(AdActionResult, steps) == 24, "AdActionResult.steps offset changed");
|
|
_Static_assert(offsetof(AdActionResult, step_count) == 32, "AdActionResult.step_count offset changed");
|
|
_Static_assert(offsetof(AdActionResult, details_json) == 40, "AdActionResult.details_json offset changed");
|
|
_Static_assert(offsetof(AdActionResult, disposition) == 48, "AdActionResult.disposition offset changed");
|
|
_Static_assert(sizeof(AdDeliverySemantics) == AD_DELIVERY_SEMANTICS_SIZE, "AdDeliverySemantics ABI size changed");
|
|
_Static_assert(offsetof(AdDeliverySemantics, retry) == 4, "AdDeliverySemantics.retry offset changed");
|
|
_Static_assert(sizeof(AdRefEntry) == AD_REF_ENTRY_SIZE, "AdRefEntry ABI size changed");
|
|
_Static_assert(_Alignof(AdRefEntry) == 8, "AdRefEntry ABI alignment changed");
|
|
_Static_assert(offsetof(AdRefEntry, process) == 0, "AdRefEntry.process offset changed");
|
|
_Static_assert(offsetof(AdRefEntry, identity) == 8, "AdRefEntry.identity offset changed");
|
|
_Static_assert(offsetof(AdRefEntry, geometry) == 48, "AdRefEntry.geometry offset changed");
|
|
_Static_assert(offsetof(AdRefEntry, capabilities) == 96, "AdRefEntry.capabilities offset changed");
|
|
_Static_assert(offsetof(AdRefEntry, source) == 128, "AdRefEntry.source offset changed");
|
|
_Static_assert(offsetof(AdRefEntry, scope) == 168, "AdRefEntry.scope offset changed");
|
|
_Static_assert(sizeof(AdExactRefEntry) == AD_EXACT_REF_ENTRY_SIZE, "AdExactRefEntry ABI size changed");
|
|
_Static_assert(_Alignof(AdExactRefEntry) == 8, "AdExactRefEntry ABI alignment changed");
|
|
_Static_assert(offsetof(AdExactRefEntry, version) == 0, "AdExactRefEntry.version offset changed");
|
|
_Static_assert(offsetof(AdExactRefEntry, size) == 4, "AdExactRefEntry.size offset changed");
|
|
_Static_assert(offsetof(AdExactRefEntry, entry) == 8, "AdExactRefEntry.entry offset changed");
|
|
_Static_assert(offsetof(AdExactRefEntry, process_instance) == 208, "AdExactRefEntry.process_instance offset changed");
|
|
_Static_assert(offsetof(AdExactRefEntry, identifier_kind) == 216, "AdExactRefEntry.identifier_kind offset changed");
|
|
_Static_assert(sizeof(AdExactWindowInfo) == AD_EXACT_WINDOW_INFO_SIZE, "AdExactWindowInfo ABI size changed");
|
|
_Static_assert(_Alignof(AdExactWindowInfo) == 8, "AdExactWindowInfo ABI alignment changed");
|
|
_Static_assert(offsetof(AdExactWindowInfo, version) == 0, "AdExactWindowInfo.version offset changed");
|
|
_Static_assert(offsetof(AdExactWindowInfo, size) == 4, "AdExactWindowInfo.size offset changed");
|
|
_Static_assert(offsetof(AdExactWindowInfo, window) == 8, "AdExactWindowInfo.window offset changed");
|
|
_Static_assert(offsetof(AdExactWindowInfo, process_instance) == 80, "AdExactWindowInfo.process_instance offset changed");
|
|
_Static_assert(sizeof(AdExactSurfaceInfo) == AD_EXACT_SURFACE_INFO_SIZE, "AdExactSurfaceInfo ABI size changed");
|
|
_Static_assert(_Alignof(AdExactSurfaceInfo) == 8, "AdExactSurfaceInfo ABI alignment changed");
|
|
_Static_assert(offsetof(AdExactSurfaceInfo, version) == 0, "AdExactSurfaceInfo.version offset changed");
|
|
_Static_assert(offsetof(AdExactSurfaceInfo, size) == 4, "AdExactSurfaceInfo.size offset changed");
|
|
_Static_assert(offsetof(AdExactSurfaceInfo, id) == 8, "AdExactSurfaceInfo.id offset changed");
|
|
_Static_assert(offsetof(AdExactSurfaceInfo, surface) == 16, "AdExactSurfaceInfo.surface offset changed");
|
|
_Static_assert(sizeof(AdDisplayInfo) == AD_DISPLAY_INFO_SIZE, "AdDisplayInfo ABI size changed");
|
|
_Static_assert(_Alignof(AdDisplayInfo) == 8, "AdDisplayInfo ABI alignment changed");
|
|
_Static_assert(offsetof(AdDisplayInfo, version) == 0, "AdDisplayInfo.version offset changed");
|
|
_Static_assert(offsetof(AdDisplayInfo, size) == 4, "AdDisplayInfo.size offset changed");
|
|
_Static_assert(offsetof(AdDisplayInfo, id) == 8, "AdDisplayInfo.id offset changed");
|
|
_Static_assert(offsetof(AdDisplayInfo, bounds) == 16, "AdDisplayInfo.bounds offset changed");
|
|
_Static_assert(offsetof(AdDisplayInfo, is_primary) == 48, "AdDisplayInfo.is_primary offset changed");
|
|
_Static_assert(offsetof(AdDisplayInfo, scale) == 56, "AdDisplayInfo.scale offset changed");
|
|
_Static_assert(sizeof(AdRefProcess) == AD_REF_PROCESS_SIZE, "AdRefProcess ABI size changed");
|
|
_Static_assert(sizeof(AdRefIdentity) == AD_REF_IDENTITY_SIZE, "AdRefIdentity ABI size changed");
|
|
_Static_assert(offsetof(AdRefIdentity, native_id) == 32, "AdRefIdentity.native_id offset changed");
|
|
_Static_assert(sizeof(AdStringSlice) == AD_STRING_SLICE_SIZE, "AdStringSlice ABI size changed");
|
|
_Static_assert(sizeof(AdRefCapabilities) == AD_REF_CAPABILITIES_SIZE, "AdRefCapabilities ABI size changed");
|
|
_Static_assert(sizeof(AdRefGeometry) == AD_REF_GEOMETRY_SIZE, "AdRefGeometry ABI size changed");
|
|
_Static_assert(offsetof(AdRefGeometry, bounds_hash) == 32, "AdRefGeometry.bounds_hash offset changed");
|
|
_Static_assert(sizeof(AdRefSource) == AD_REF_SOURCE_SIZE, "AdRefSource ABI size changed");
|
|
_Static_assert(offsetof(AdRefSource, window_bounds_hash) == 24, "AdRefSource.window_bounds_hash offset changed");
|
|
_Static_assert(sizeof(AdRefScope) == AD_REF_SCOPE_SIZE, "AdRefScope ABI size changed");
|
|
_Static_assert(offsetof(AdRefScope, path) == 8, "AdRefScope.path offset changed");
|
|
_Static_assert(sizeof(struct AdWaitArgs) == AD_WAIT_ARGS_SIZE, "AdWaitArgs ABI size drift");
|
|
_Static_assert(_Alignof(struct AdWaitArgs) == 8, "AdWaitArgs ABI alignment changed");
|
|
_Static_assert(offsetof(AdWaitArgs, mode) == 0, "AdWaitArgs.mode offset changed");
|
|
_Static_assert(offsetof(AdWaitArgs, predicate) == 48, "AdWaitArgs.predicate offset changed");
|
|
_Static_assert(offsetof(AdWaitArgs, scope) == 96, "AdWaitArgs.scope offset changed");
|
|
_Static_assert(sizeof(AdOptionalU64) == AD_OPTIONAL_U64_SIZE, "AdOptionalU64 ABI size changed");
|
|
_Static_assert(sizeof(AdOptionalUsize) == AD_OPTIONAL_USIZE_SIZE, "AdOptionalUsize ABI size changed");
|
|
_Static_assert(sizeof(AdWaitSurfaceModes) == AD_WAIT_SURFACE_MODES_SIZE, "AdWaitSurfaceModes ABI size changed");
|
|
_Static_assert(sizeof(AdWaitMode) == AD_WAIT_MODE_SIZE, "AdWaitMode ABI size changed");
|
|
_Static_assert(sizeof(AdWaitPredicate) == AD_WAIT_PREDICATE_SIZE, "AdWaitPredicate ABI size changed");
|
|
_Static_assert(sizeof(AdWaitScope) == AD_WAIT_SCOPE_SIZE, "AdWaitScope ABI size changed");
|
|
_Static_assert(sizeof(AdNode) == AD_NODE_SIZE, "AdNode ABI size changed");
|
|
_Static_assert(offsetof(AdNode, content) == 0, "AdNode.content offset changed");
|
|
_Static_assert(offsetof(AdNode, presentation) == 48, "AdNode.presentation offset changed");
|
|
_Static_assert(offsetof(AdNode, relation) == 96, "AdNode.relation offset changed");
|
|
_Static_assert(sizeof(AdNodeContent) == AD_NODE_CONTENT_SIZE, "AdNodeContent ABI size changed");
|
|
_Static_assert(sizeof(AdNodePresentation) == AD_NODE_PRESENTATION_SIZE, "AdNodePresentation ABI size changed");
|
|
_Static_assert(sizeof(AdNodeRelation) == AD_NODE_RELATION_SIZE, "AdNodeRelation ABI size changed");
|
|
_Static_assert(sizeof(AdNotificationIdentity) == AD_NOTIFICATION_IDENTITY_SIZE, "AdNotificationIdentity ABI size changed");
|
|
_Static_assert(sizeof(AdNotificationActionRequest) == AD_NOTIFICATION_ACTION_REQUEST_SIZE, "AdNotificationActionRequest ABI size changed");
|
|
_Static_assert(offsetof(AdNotificationActionRequest, identity) == 16, "AdNotificationActionRequest.identity offset changed");
|
|
_Static_assert(sizeof(AdFindQuery) == AD_FIND_QUERY_SIZE, "AdFindQuery ABI size changed");
|
|
_Static_assert(offsetof(AdFindQuery, filter) == 24, "AdFindQuery.filter offset changed");
|
|
_Static_assert(sizeof(AdFindControl) == AD_FIND_CONTROL_SIZE, "AdFindControl ABI size changed");
|
|
_Static_assert(offsetof(AdFindControl, timeout_ms) == 16, "AdFindControl.timeout_ms offset changed");
|
|
_Static_assert(sizeof(AdFindSelection) == AD_FIND_SELECTION_SIZE, "AdFindSelection ABI size changed");
|
|
_Static_assert(sizeof(AdFindIdentity) == AD_FIND_IDENTITY_SIZE, "AdFindIdentity ABI size changed");
|
|
_Static_assert(sizeof(AdFindStatePredicate) == AD_FIND_STATE_PREDICATE_SIZE, "AdFindStatePredicate ABI size changed");
|
|
_Static_assert(sizeof(AdFindStateSlice) == AD_FIND_STATE_SLICE_SIZE, "AdFindStateSlice ABI size changed");
|
|
_Static_assert(sizeof(AdFindFilter) == AD_FIND_FILTER_SIZE, "AdFindFilter ABI size changed");
|
|
_Static_assert(offsetof(AdFindFilter, exact) == 80, "AdFindFilter.exact offset changed");
|
|
#endif /* __STDC_VERSION__ >= 201112L */
|
|
#endif /* AGENT_DESKTOP_ABI_ASSERTS */
|