Merge branch 'worktree-agent-a466c08a4014dbcbe' into rustify (I4: AccessKit names)
This commit is contained in:
commit
32a5256a0d
22 files changed
+2251
-22
No files matched your search
@@ -8,6 +8,37 @@ capability that moved. Small and trivial changes do not go here.
|
|||||||
An entry gives the date, what changed, why, and a short before/after where
|
An entry gives the date, what changed, why, and a short before/after where
|
||||||
it helps judge the change without the session that made it. Newest first.
|
it helps judge the change without the session that made it. Newest first.
|
||||||
|
|
||||||
|
## 2026-09-05: accessibility names via AccessKit (RUST.md's I4)
|
||||||
|
|
||||||
|
`.label()` (already in `trait_fns.rs`, previously unused anywhere in-tree)
|
||||||
|
is now load-bearing: it's the one thing that puts a widget in the AccessKit
|
||||||
|
tree `iris_core::ui::access::AccessTree` builds and both backends push
|
||||||
|
out. A widget author who wants a control to be findable by name (and
|
||||||
|
tappable by name, through `ui-trace`/a real screen reader) calls `.label()`
|
||||||
|
on it; nothing else is required, and a widget nobody labels is invisible
|
||||||
|
to this system at zero cost, not just zero UI.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let button = rect(Color::LIME)
|
||||||
|
.on(CursorSense::click(), move |_, rsc| { ... })
|
||||||
|
.label("Add task"); // now findable by uiautomator/AccessKit as "Add task"
|
||||||
|
```
|
||||||
|
|
||||||
|
Two new things a widget author might touch directly:
|
||||||
|
|
||||||
|
- **`Widget::access_role(&self) -> accesskit::Role`**, default `Unknown`.
|
||||||
|
Override it if your widget has a real platform equivalent —
|
||||||
|
`TextEdit` now returns `TextInput`/`MultilineTextInput` by `EditMode`.
|
||||||
|
Only consulted for a widget that also has a `.label()`; an unlabelled
|
||||||
|
widget's `access_role` is never called.
|
||||||
|
- **`Widgets::named() -> impl Iterator<Item = WidgetId>`** — every widget
|
||||||
|
with an explicit label, for anything else that wants to walk the same
|
||||||
|
set `AccessTree` does.
|
||||||
|
|
||||||
|
Nothing about `Painter`, `draw`, or the layout/move machinery changed —
|
||||||
|
this sits entirely beside them, reading `resolved_region`'s output rather
|
||||||
|
than participating in producing it.
|
||||||
|
|
||||||
## 2026-09-05: `List`, a virtualised bottom-anchored list (RUST.md's I3)
|
## 2026-09-05: `List`, a virtualised bottom-anchored list (RUST.md's I3)
|
||||||
|
|
||||||
A new widget, `iris::widget::List` (`iris/src/widget/list.rs` -- read its
|
A new widget, `iris::widget::List` (`iris/src/widget/list.rs` -- read its
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ session spending an afternoon on them again.
|
|||||||
below), **E3 (the Kotlin/Java shell over a JNI bridge into Rust, both
|
below), **E3 (the Kotlin/Java shell over a JNI bridge into Rust, both
|
||||||
pass conditions proved on the emulator — see its own box)**, I0a, I0b
|
pass conditions proved on the emulator — see its own box)**, I0a, I0b
|
||||||
(iris builds on a pinned nightly and runs), I1 (parley + glyph atlas),
|
(iris builds on a pinned nightly and runs), I1 (parley + glyph atlas),
|
||||||
I2 (iris on android-view).
|
I2 (iris on android-view), I3 (`iris::widget::List`).
|
||||||
- **E3 done, 2026-09-05, and unlike E1/E2 it is committed to this repo**
|
- **E3 done, 2026-09-05, and unlike E1/E2 it is committed to this repo**
|
||||||
(`android-shell/` — a JNI-bridge crate on `client-core` — plus a new
|
(`android-shell/` — a JNI-bridge crate on `client-core` — plus a new
|
||||||
Gradle module `app/shellApp/`, left deliberately separate from
|
Gradle module `app/shellApp/`, left deliberately separate from
|
||||||
@@ -61,6 +61,20 @@ session spending an afternoon on them again.
|
|||||||
box for the full account, the exact commands, and what was deliberately
|
box for the full account, the exact commands, and what was deliberately
|
||||||
cut (attachment uploads, a session picker, the on-screen/banner
|
cut (attachment uploads, a session picker, the on-screen/banner
|
||||||
suppression — all pending E4's screen).
|
suppression — all pending E4's screen).
|
||||||
|
- **I4 — accessibility names via AccessKit: host half done and verified
|
||||||
|
2026-09-05, ticked in the box below.** `iris_core::ui::access::AccessTree`
|
||||||
|
builds one flat AccessKit tree from `Widgets::named()` (a side set only
|
||||||
|
`.label()` populates, so an unnamed widget costs this nothing), pushed
|
||||||
|
through `accesskit_winit` on the desktop and `accesskit_android` on
|
||||||
|
Android, updated only when a name/role/bounds actually changes (a
|
||||||
|
counter confirms it: 1 rebuild on first draw, 0 across an unchanged
|
||||||
|
frame, 1 more after a real move). E1's detach-abort mitigation is
|
||||||
|
carried (`android/access.rs`'s `raise_if_enabled`). Every check that
|
||||||
|
doesn't need the emulator is clean — see I4's own box for the exact
|
||||||
|
numbers. **What's left**: the emulator itself is held by another session
|
||||||
|
this pass, so `ui-trace record --do "tap 'pad'"` against
|
||||||
|
`iris-android-app`'s tabs screen (which now has five named buttons) has
|
||||||
|
not been run for real yet — exact commands at the bottom of I4's box.
|
||||||
- **E2 done, 2026-09-05, and its headline finding changes what "decide
|
- **E2 done, 2026-09-05, and its headline finding changes what "decide
|
||||||
from the measurements" (recommendation item 3) can mean right now.**
|
from the measurements" (recommendation item 3) can mean right now.**
|
||||||
Built a real transcript screen (`~/src/android-view/e2-transcript`,
|
Built a real transcript screen (`~/src/android-view/e2-transcript`,
|
||||||
@@ -1772,9 +1786,144 @@ silently on real hardware.
|
|||||||
session screen, i.e. most of I5's work) rather than something this
|
session screen, i.e. most of I5's work) rather than something this
|
||||||
box's scope could finish alone -- recorded here rather than left
|
box's scope could finish alone -- recorded here rather than left
|
||||||
silently undone.
|
silently undone.
|
||||||
- [ ] **I4 — accessibility names via AccessKit.** Every control carries a
|
- [x] **I4 — accessibility names via AccessKit, host half done and verified
|
||||||
name; `ui-trace` can find and tap it by label. Pass: `bench-lib.sh`'s
|
2026-09-05; the emulator half is the one step left, named at the
|
||||||
tap-by-name works against the iris screen unchanged.
|
bottom of this box.** Built `iris_core::ui::access::AccessTree`
|
||||||
|
(`iris/core/src/ui/access.rs`) -- one flat AccessKit tree, a synthetic
|
||||||
|
`Role::Window` root with every **named** widget as a direct child.
|
||||||
|
Deliberately flat rather than mirroring iris's real widget nesting:
|
||||||
|
nothing upstream of a named leaf needs a node, since a screen
|
||||||
|
reader's traversal (and uiautomator's tap-by-name, this box's own
|
||||||
|
pass condition) works from each node's on-screen bounds, not from
|
||||||
|
tree structure -- and mirroring the real tree would rebuild
|
||||||
|
intermediate nodes on every resize of any container above a named
|
||||||
|
widget, which is most frames.
|
||||||
|
|
||||||
|
**Modular the way input's sense registry is.** `Widgets` gained one
|
||||||
|
`HashSet<WidgetId>` (`named`), populated only by `.label()`/
|
||||||
|
`set_label` and drained by `free_next` (the same removal path a
|
||||||
|
freed id already went through -- no second bookkeeping call added
|
||||||
|
anywhere). `AccessTree::update` walks `widgets.named()` directly,
|
||||||
|
never the full widget arena, so a widget nobody named costs this
|
||||||
|
subsystem nothing -- not a visit, not a branch. Roles come from a
|
||||||
|
new `Widget::access_role(&self) -> accesskit::Role` trait method,
|
||||||
|
default `Unknown`; the one override so far is `TextEdit` ->
|
||||||
|
`TextInput`/`MultilineTextInput` by `EditMode`. Bounds come from
|
||||||
|
`UiRenderState::window_region`, which sits on `resolved_region`'s
|
||||||
|
move-chain walk -- so a widget moved via `Offset`/`Scroll` (never
|
||||||
|
redrawn from scratch) still reports where it actually ended up; see
|
||||||
|
`bounds_follow_a_moved_widget_and_updates_stay_incremental` below.
|
||||||
|
|
||||||
|
**Incremental, not per-frame.** `AccessTree` keeps the last
|
||||||
|
`HashMap<WidgetId, Entry>` (name, role, bounds) it sent and only
|
||||||
|
returns a new `TreeUpdate` -- and only then bumps its `rebuilds`
|
||||||
|
counter, `take_rebuilds()`'s the AccessKit twin of
|
||||||
|
`UiRenderState::take_counters` -- when that set actually differs.
|
||||||
|
Confirmed by `bounds_follow_a_moved_widget_and_updates_stay_incremental`
|
||||||
|
(`iris/src/access_tests.rs`): 1 rebuild on the first draw, 0 across an
|
||||||
|
unchanged frame, 1 more after a real move, regardless of how many
|
||||||
|
other widgets are on screen.
|
||||||
|
|
||||||
|
**`SlotId::as_u64`** (`core/src/util/slot.rs`) encodes a `WidgetId`
|
||||||
|
into accesskit's flat `NodeId(u64)`, offset by one so a real widget
|
||||||
|
never collides with the reserved window node (`NodeId(0)`).
|
||||||
|
|
||||||
|
**Pushed through two backends, each behind an inert action/activation
|
||||||
|
handler** -- see below for why inert is correct, not incomplete.
|
||||||
|
`default/access.rs` (winit): `accesskit_winit::Adapter`, built in
|
||||||
|
`DefaultApp::new` with the window created hidden
|
||||||
|
(`with_visible(false)`) and shown only after the adapter exists,
|
||||||
|
which is what that constructor requires. `process_event` runs on
|
||||||
|
every `WindowEvent`; `update_if_active` runs once per
|
||||||
|
`RedrawRequested`, after `render.update()` so bounds reflect the
|
||||||
|
frame just drawn. `android/access.rs` (android-view):
|
||||||
|
`accesskit_android::Adapter` on `AndroidUiState`, `IrisViewPeer` now
|
||||||
|
implements `AccessibilityNodeProvider`
|
||||||
|
(`create_accessibility_node_info`/`find_focus`/`perform_action`), and
|
||||||
|
`render()` (now taking `&mut CallbackCtx`, needed for the JNI handle
|
||||||
|
any `raise` requires) pushes the same `AccessTree::update` after
|
||||||
|
every draw.
|
||||||
|
|
||||||
|
**Why the `ActionHandler`s are empty, not a placeholder for later
|
||||||
|
work**: AGENTS.md's own "Driving the UI" section says it plainly --
|
||||||
|
`ui-trace record --do "tap 'Save'"` resolves the label against the
|
||||||
|
screen and performs a **real touch at that node's bounds**, the same
|
||||||
|
as a person's finger. It does not call into AccessKit's action
|
||||||
|
system at all. So once `AccessTree` reports correct bounds, the
|
||||||
|
ordinary pointer path (already built, already tested) is what
|
||||||
|
answers the tap -- there is nothing for `do_action` to do for this
|
||||||
|
pass condition specifically. A future real screen reader's own
|
||||||
|
double-tap-to-activate gesture works the same way, for the same
|
||||||
|
reason. If iris ever needs to answer an AccessKit `Action::Click`
|
||||||
|
injected without a matching touch (e.g. a switch-access scanner),
|
||||||
|
that is new scope, not a gap in this box.
|
||||||
|
|
||||||
|
**E1's abort mitigation, carried.** `android/access.rs`'s
|
||||||
|
`raise_if_enabled` is the one place `QueuedEvents::raise` may be
|
||||||
|
called: it asks `AccessibilityManager.isEnabled()` (a `getSystemService`
|
||||||
|
JNI call, since android-view has no ready-made wrapper) immediately
|
||||||
|
before every `raise` and drops the events instead when the answer is
|
||||||
|
no. Every call site (`render`'s per-frame push, `perform_action`)
|
||||||
|
goes through it, and each pushes it as a *deferred* callback exactly
|
||||||
|
like android-view's own demo, so it runs after the current JNI
|
||||||
|
callback has released whatever it's holding -- `raise`'s own
|
||||||
|
documented requirement. Not independently re-triggered on this
|
||||||
|
pass (that needs the emulator, see below); the mitigation is coded
|
||||||
|
to the exact mechanism E1 diagnosed (`sendAccessibilityEvent`
|
||||||
|
throwing when accessibility is off) rather than to the symptom, so
|
||||||
|
there is no reason to expect it behaves differently here than it did
|
||||||
|
there.
|
||||||
|
|
||||||
|
**Verified, 2026-09-05, host only.**
|
||||||
|
`cargo fmt --all -- --check`, `cargo build --workspace --all-targets`,
|
||||||
|
`cargo clippy --all-targets` (both plain and `--all-targets`) clean;
|
||||||
|
`cargo test --workspace` -- 28 tests in `iris/`, three of them new
|
||||||
|
(`access_tests::a_named_widget_reaches_the_tree_with_its_role_and_bounds`,
|
||||||
|
`::a_widget_with_no_label_never_reaches_the_tree`,
|
||||||
|
`::bounds_follow_a_moved_widget_and_updates_stay_incremental`).
|
||||||
|
`cd iris/android-app && cargo ndk -t x86_64 -P 26 build` and
|
||||||
|
`... clippy` clean for both `iris` (with the android module) and
|
||||||
|
`iris-android-app`, same shape as I2/I3's checks.
|
||||||
|
`iris/run-headless.sh tabs --shot /tmp/iris_i4_tabs.png --seconds 4`
|
||||||
|
still renders -- **27266 bytes, byte-for-byte identical to I2's own
|
||||||
|
post-fix screenshot** -- confirming the hidden-window-then-adapter
|
||||||
|
change to `DefaultApp::new` cost nothing visible. `tabs-ui`'s five
|
||||||
|
switch buttons (`tabs-ui/src/lib.rs`) now carry `.label()`s matching
|
||||||
|
their on-screen text ("pad", "span", "image span", "text layout",
|
||||||
|
"text edit scroll") -- both so the desktop run above exercises a
|
||||||
|
non-empty tree and so the emulator step below has real names to tap.
|
||||||
|
Not independently checked on this pass: whether `accesskit_winit`'s
|
||||||
|
Linux path (AT-SPI, via `accesskit_unix`) actually reaches a real
|
||||||
|
assistive-technology client on this VM's headless sway -- there is
|
||||||
|
no AT-SPI registry running here, so `default/access.rs`'s handlers
|
||||||
|
are exercised as inert code paths (built, called, no panic) rather
|
||||||
|
than confirmed end-to-end the way the emulator step below confirms
|
||||||
|
the Android path.
|
||||||
|
|
||||||
|
**What remains -- the one check that needs the emulator, held by
|
||||||
|
another session during this pass.** `iris-android-app`'s tabs screen
|
||||||
|
has never been driven by `ui-trace` for real; everything above is
|
||||||
|
"builds, runs, produces the right data" on the host. Once the
|
||||||
|
emulator is free:
|
||||||
|
|
||||||
|
cd iris/android-app && cargo ndk -t x86_64 -P 26 -o app/src/main/jniLibs/ build --release && gradle :app:assembleDebug
|
||||||
|
adb install -r app/build/outputs/apk/debug/app-debug.apk
|
||||||
|
# launch iris-android-app on the emulator, then:
|
||||||
|
ui-trace record --do "tap 'pad'"
|
||||||
|
ui-trace record --do "tap 'span'"
|
||||||
|
ui-trace record --do "tap 'image span'"
|
||||||
|
ui-trace record --do "tap 'text layout'"
|
||||||
|
ui-trace record --do "tap 'text edit scroll'"
|
||||||
|
|
||||||
|
Pass condition: each tap resolves (uiautomator finds a node with
|
||||||
|
that exact label) and switches `main`'s visible pane the way a
|
||||||
|
direct touch on that button already does -- i.e. `bench-lib.sh`'s
|
||||||
|
tap-by-name mechanism, unmodified, driving the iris screen instead
|
||||||
|
of the Compose one. Also worth checking while the emulator is up,
|
||||||
|
since E1 found it exactly this way: run a second `ui-trace record`
|
||||||
|
immediately after the first (attach, detach, attach again) and
|
||||||
|
confirm the process is still alive afterward -- the detach-abort
|
||||||
|
this box's mitigation exists for.
|
||||||
- [ ] **I5 — the transcript screen in iris.** E2's pass conditions, all
|
- [ ] **I5 — the transcript screen in iris.** E2's pass conditions, all
|
||||||
seven behaviours, against the sandbox with `--delay`. This is the
|
seven behaviours, against the sandbox with `--delay`. This is the
|
||||||
point the decision in the recommendation is made at.
|
point the decision in the recommendation is made at.
|
||||||
|
|||||||
Generated
+733
-2
@@ -18,6 +18,126 @@ version = "0.1.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
|
checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit"
|
||||||
|
version = "0.25.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "438a7081a65b95c668db56591a4fef9bc5dad275f448bd6223fc6949d823db38"
|
||||||
|
dependencies = [
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_android"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "929aff36b0d3dd22ddb59191989d5293ed958294d7728bd6c2ec9778f73414aa"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_consumer",
|
||||||
|
"jni",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_atspi_common"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c9d47ad644916f6cb7e432a5ca0dbd7cc78281a9772881057bb72d4aadb93257"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_consumer",
|
||||||
|
"atspi-common",
|
||||||
|
"phf",
|
||||||
|
"serde",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_consumer"
|
||||||
|
version = "0.39.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc882fa0c9c24c53649e256311b51046cf36eca9a8f7e54ff4ef682160b0cb27"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"hashbrown 0.17.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_ios"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d5e9b29c6ba5f4d2e0662e9c562484f061ffc58f658479c538ecca8299ada1e9"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_consumer",
|
||||||
|
"hashbrown 0.17.1",
|
||||||
|
"objc2 0.5.2",
|
||||||
|
"objc2-foundation 0.2.2",
|
||||||
|
"objc2-ui-kit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_macos"
|
||||||
|
version = "0.27.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3f278988416e5fb600f24d0cfffe31a249ebbff980fb9c5a3b5fbed2c579f73"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_consumer",
|
||||||
|
"hashbrown 0.17.1",
|
||||||
|
"objc2 0.5.2",
|
||||||
|
"objc2-app-kit 0.2.2",
|
||||||
|
"objc2-foundation 0.2.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_unix"
|
||||||
|
version = "0.23.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "665c9079b7325a8168a6793437a172dda44b19a05af8ed52d7e32abaada996fe"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_atspi_common",
|
||||||
|
"async-channel",
|
||||||
|
"async-executor",
|
||||||
|
"async-task",
|
||||||
|
"atspi",
|
||||||
|
"futures-lite",
|
||||||
|
"futures-util",
|
||||||
|
"serde",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_windows"
|
||||||
|
version = "0.35.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a59e8d7160cbac991c1345c99153783ab96423644ccb1f20617cf80c97596aa1"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_consumer",
|
||||||
|
"hashbrown 0.17.1",
|
||||||
|
"static_assertions",
|
||||||
|
"windows",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_winit"
|
||||||
|
version = "0.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1eb960a51582305f94b3884a7ff54b3462abe38f0de95a9e7e04dd7ab7b757da"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_ios",
|
||||||
|
"accesskit_macos",
|
||||||
|
"accesskit_unix",
|
||||||
|
"accesskit_windows",
|
||||||
|
"raw-window-handle",
|
||||||
|
"winit",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler2"
|
name = "adler2"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
@@ -191,12 +311,180 @@ dependencies = [
|
|||||||
"libloading",
|
"libloading",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-broadcast"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener",
|
||||||
|
"event-listener-strategy",
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-channel"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
|
||||||
|
dependencies = [
|
||||||
|
"concurrent-queue",
|
||||||
|
"event-listener-strategy",
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-executor"
|
||||||
|
version = "1.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a"
|
||||||
|
dependencies = [
|
||||||
|
"async-task",
|
||||||
|
"concurrent-queue",
|
||||||
|
"fastrand",
|
||||||
|
"futures-lite",
|
||||||
|
"pin-project-lite",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-io"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"cfg-if",
|
||||||
|
"concurrent-queue",
|
||||||
|
"futures-io",
|
||||||
|
"futures-lite",
|
||||||
|
"parking",
|
||||||
|
"polling",
|
||||||
|
"rustix 1.1.3",
|
||||||
|
"slab",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-lock"
|
||||||
|
version = "3.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener",
|
||||||
|
"event-listener-strategy",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-process"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
|
||||||
|
dependencies = [
|
||||||
|
"async-channel",
|
||||||
|
"async-io",
|
||||||
|
"async-lock",
|
||||||
|
"async-signal",
|
||||||
|
"async-task",
|
||||||
|
"blocking",
|
||||||
|
"cfg-if",
|
||||||
|
"event-listener",
|
||||||
|
"futures-lite",
|
||||||
|
"rustix 1.1.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-recursion"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.113",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-signal"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485"
|
||||||
|
dependencies = [
|
||||||
|
"async-io",
|
||||||
|
"async-lock",
|
||||||
|
"atomic-waker",
|
||||||
|
"cfg-if",
|
||||||
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"rustix 1.1.3",
|
||||||
|
"signal-hook-registry",
|
||||||
|
"slab",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-task"
|
||||||
|
version = "4.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.92"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atspi"
|
||||||
|
version = "0.29.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c77886257be21c9cd89a4ae7e64860c6f0eefca799bb79127913052bd0eefb3d"
|
||||||
|
dependencies = [
|
||||||
|
"atspi-common",
|
||||||
|
"atspi-proxies",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atspi-common"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20c5617155740c98003016429ad13fe43ce7a77b007479350a9f8bf95a29f63d"
|
||||||
|
dependencies = [
|
||||||
|
"enumflags2",
|
||||||
|
"serde",
|
||||||
|
"static_assertions",
|
||||||
|
"zbus",
|
||||||
|
"zbus-lockstep",
|
||||||
|
"zbus-lockstep-macros",
|
||||||
|
"zbus_names",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atspi-proxies"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2230e48787ed3eb4088996eab66a32ca20c0b67bbd4fd6cdfe79f04f1f04c9fc"
|
||||||
|
dependencies = [
|
||||||
|
"atspi-common",
|
||||||
|
"serde",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
@@ -303,6 +591,19 @@ dependencies = [
|
|||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blocking"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa"
|
||||||
|
dependencies = [
|
||||||
|
"async-channel",
|
||||||
|
"async-task",
|
||||||
|
"futures-io",
|
||||||
|
"futures-lite",
|
||||||
|
"piper",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "built"
|
name = "built"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@@ -633,6 +934,33 @@ version = "1.15.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "endi"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enumflags2"
|
||||||
|
version = "0.7.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
|
||||||
|
dependencies = [
|
||||||
|
"enumflags2_derive",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enumflags2_derive"
|
||||||
|
version = "0.7.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.113",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equator"
|
name = "equator"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
@@ -675,6 +1003,26 @@ version = "3.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
|
checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener"
|
||||||
|
version = "5.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2"
|
||||||
|
dependencies = [
|
||||||
|
"parking",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener-strategy"
|
||||||
|
version = "0.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "exr"
|
name = "exr"
|
||||||
version = "1.74.0"
|
version = "1.74.0"
|
||||||
@@ -690,6 +1038,12 @@ dependencies = [
|
|||||||
"zune-inflate",
|
"zune-inflate",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fax"
|
name = "fax"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
@@ -811,6 +1165,61 @@ version = "0.3.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
|
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-core"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-lite"
|
||||||
|
version = "2.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad"
|
||||||
|
dependencies = [
|
||||||
|
"fastrand",
|
||||||
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"parking",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-macro"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-task"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-util"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-macro",
|
||||||
|
"futures-task",
|
||||||
|
"pin-project-lite",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fxhash"
|
name = "fxhash"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@@ -977,6 +1386,12 @@ version = "0.5.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hexf-parse"
|
name = "hexf-parse"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@@ -1176,6 +1591,9 @@ dependencies = [
|
|||||||
name = "iris"
|
name = "iris"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_android",
|
||||||
|
"accesskit_winit",
|
||||||
"android-view",
|
"android-view",
|
||||||
"arboard",
|
"arboard",
|
||||||
"image",
|
"image",
|
||||||
@@ -1196,6 +1614,7 @@ dependencies = [
|
|||||||
name = "iris-core"
|
name = "iris-core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"image",
|
"image",
|
||||||
@@ -1428,6 +1847,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "metal"
|
name = "metal"
|
||||||
version = "0.33.0"
|
version = "0.33.0"
|
||||||
@@ -1927,6 +2355,16 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-stream"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_pipe"
|
name = "os_pipe"
|
||||||
version = "1.2.3"
|
version = "1.2.3"
|
||||||
@@ -1946,6 +2384,12 @@ dependencies = [
|
|||||||
"ttf-parser",
|
"ttf-parser",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.5"
|
version = "0.12.5"
|
||||||
@@ -2031,6 +2475,49 @@ dependencies = [
|
|||||||
"indexmap",
|
"indexmap",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "010378780309880b08997fae13be7834dba947d36393bd372f2b1556deb2a2f6"
|
||||||
|
dependencies = [
|
||||||
|
"phf_macros",
|
||||||
|
"phf_shared",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_generator"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aeb62e0959d5a1bebc965f4d15d9e2b7cea002b6b0f5ba8cde6cc26738467100"
|
||||||
|
dependencies = [
|
||||||
|
"fastrand",
|
||||||
|
"phf_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_macros"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fa8d0ca26d424d27630da600c6624696e7dec8bf7b3b492b383c5dc49e5e085"
|
||||||
|
dependencies = [
|
||||||
|
"phf_generator",
|
||||||
|
"phf_shared",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.113",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c6fd9027e2d9319be6349febd1db4e8d02aa544921200c9b777720ac34a3aa89"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.1.10"
|
version = "1.1.10"
|
||||||
@@ -2057,6 +2544,17 @@ version = "0.2.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "piper"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-waker",
|
||||||
|
"fastrand",
|
||||||
|
"futures-io",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.32"
|
version = "0.3.32"
|
||||||
@@ -2500,12 +2998,33 @@ dependencies = [
|
|||||||
"syn 2.0.113",
|
"syn 2.0.113",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_repr"
|
||||||
|
version = "0.1.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
||||||
|
dependencies = [
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simd-adler32"
|
name = "simd-adler32"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
@@ -2521,6 +3040,12 @@ dependencies = [
|
|||||||
"quote",
|
"quote",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "skrifa"
|
name = "skrifa"
|
||||||
version = "0.44.0"
|
version = "0.44.0"
|
||||||
@@ -2664,6 +3189,19 @@ dependencies = [
|
|||||||
"iris",
|
"iris",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.25.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1"
|
||||||
|
dependencies = [
|
||||||
|
"fastrand",
|
||||||
|
"getrandom",
|
||||||
|
"once_cell",
|
||||||
|
"rustix 1.1.3",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
@@ -2790,7 +3328,7 @@ dependencies = [
|
|||||||
"indexmap",
|
"indexmap",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"toml_parser",
|
"toml_parser",
|
||||||
"winnow",
|
"winnow 0.7.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2799,7 +3337,7 @@ version = "1.0.6+spec-1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44"
|
checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winnow",
|
"winnow 0.7.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2809,14 +3347,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.113",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.36"
|
version = "0.1.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tree_magic_mini"
|
name = "tree_magic_mini"
|
||||||
@@ -2835,6 +3388,17 @@ version = "0.25.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
|
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uds_windows"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
|
||||||
|
dependencies = [
|
||||||
|
"memoffset",
|
||||||
|
"tempfile",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ui-events"
|
name = "ui-events"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -2869,6 +3433,17 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.26.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5772d71c9be8a8a6ac2117d949c5b224c1b72241bb611d9a3012edcf8af7812"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"serde_core",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "v_frame"
|
name = "v_frame"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@@ -3659,6 +4234,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-bindgen"
|
name = "wit-bindgen"
|
||||||
version = "0.46.0"
|
version = "0.46.0"
|
||||||
@@ -3798,6 +4382,112 @@ dependencies = [
|
|||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus"
|
||||||
|
version = "5.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5db4be7c075cb421e4b7ee645541604239bd243ba7c357511f4ff3a74b555907"
|
||||||
|
dependencies = [
|
||||||
|
"async-broadcast",
|
||||||
|
"async-executor",
|
||||||
|
"async-io",
|
||||||
|
"async-lock",
|
||||||
|
"async-process",
|
||||||
|
"async-recursion",
|
||||||
|
"async-task",
|
||||||
|
"async-trait",
|
||||||
|
"blocking",
|
||||||
|
"enumflags2",
|
||||||
|
"event-listener",
|
||||||
|
"futures-core",
|
||||||
|
"futures-lite",
|
||||||
|
"hex",
|
||||||
|
"libc",
|
||||||
|
"ordered-stream",
|
||||||
|
"rustix 1.1.3",
|
||||||
|
"serde",
|
||||||
|
"serde_repr",
|
||||||
|
"tracing",
|
||||||
|
"uds_windows",
|
||||||
|
"uuid",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
"winnow 1.0.4",
|
||||||
|
"zbus_macros",
|
||||||
|
"zbus_names",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus-lockstep"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6998de05217a084b7578728a9443d04ea4cd80f2a0839b8d78770b76ccd45863"
|
||||||
|
dependencies = [
|
||||||
|
"zbus_xml",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus-lockstep-macros"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10da05367f3a7b7553c8cdf8fa91aee6b64afebe32b51c95177957efc47ca3a0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.113",
|
||||||
|
"zbus-lockstep",
|
||||||
|
"zbus_xml",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus_macros"
|
||||||
|
version = "5.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2990635d09ade6df1868f72f8cac69a876a90981e8bd3c40b1be413f8dc88f40"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-crate",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
"zbus_names",
|
||||||
|
"zvariant",
|
||||||
|
"zvariant_utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus_names"
|
||||||
|
version = "4.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8bf88b4a3ff53e883001e0e0115b297a9d53c31b9c1edd2bfdd853e3428624e"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"winnow 1.0.4",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus_xml"
|
||||||
|
version = "5.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1586c021a01ca0a9216dcd874e546382e156a5cbab5fab6cb5f10087e22682a"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"winnow 1.0.4",
|
||||||
|
"zbus_names",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zcheapstr"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1afec51604565183aeb5c54c20aeab286120d4e4460f7f76e3e8bb8c0d99473"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeno"
|
name = "zeno"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@@ -3918,3 +4608,44 @@ checksum = "e35aee689668bf9bd6f6f3a6c60bb29ba1244b3b43adfd50edd554a371da37d5"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"zune-core 0.5.0",
|
"zune-core 0.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zvariant"
|
||||||
|
version = "5.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1d34c27cc6cdd1f458427519dd6b8612f7b7e3f7b9a0b2355d041dda9869147"
|
||||||
|
dependencies = [
|
||||||
|
"endi",
|
||||||
|
"enumflags2",
|
||||||
|
"serde",
|
||||||
|
"winnow 1.0.4",
|
||||||
|
"zcheapstr",
|
||||||
|
"zvariant_derive",
|
||||||
|
"zvariant_utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zvariant_derive"
|
||||||
|
version = "5.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "864155e69b4352db0c7f374917bf45d1e0c8d17659c8b3dbf9795f3673f8c497"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-crate",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
"zvariant_utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zvariant_utils"
|
||||||
|
version = "4.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bad0294361a320b694a328460dc73add56c306150f5cb6bfafc44446120008a3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"syn 3.0.5",
|
||||||
|
"winnow 1.0.4",
|
||||||
|
]
|
||||||
@@ -13,6 +13,7 @@ swash = { workspace = true }
|
|||||||
pollster = { workspace = true }
|
pollster = { workspace = true }
|
||||||
wgpu = { workspace = true }
|
wgpu = { workspace = true }
|
||||||
image = { workspace = true }
|
image = { workspace = true }
|
||||||
|
accesskit = { workspace = true }
|
||||||
tokio = { workspace = true, features = ["sync", "rt", "rt-multi-thread"] }
|
tokio = { workspace = true, features = ["sync", "rt", "rt-multi-thread"] }
|
||||||
|
|
||||||
# winit everywhere except Android; android-view (below) is what stands in
|
# winit everywhere except Android; android-view (below) is what stands in
|
||||||
@@ -27,6 +28,11 @@ tokio = { workspace = true, features = ["sync", "rt", "rt-multi-thread"] }
|
|||||||
[target.'cfg(not(target_os = "android"))'.dependencies]
|
[target.'cfg(not(target_os = "android"))'.dependencies]
|
||||||
winit = { workspace = true }
|
winit = { workspace = true }
|
||||||
arboard = { workspace = true, features = ["wayland-data-control"] }
|
arboard = { workspace = true, features = ["wayland-data-control"] }
|
||||||
|
# I4 (RUST.md): the desktop half of the AccessKit push, `winit`'s own
|
||||||
|
# adapter over `accesskit`. No pin needed the way android-view's rev is
|
||||||
|
# pinned -- this is an ordinary crates.io release with no local abort to
|
||||||
|
# track (that finding is Android-only, see below).
|
||||||
|
accesskit_winit = "0.34.0"
|
||||||
|
|
||||||
# Pinned to the exact commit RUST.md's E1 (2026-09-04) measured on this
|
# Pinned to the exact commit RUST.md's E1 (2026-09-04) measured on this
|
||||||
# emulator -- real Vulkan rendering, a working `InputConnection`, and the
|
# emulator -- real Vulkan rendering, a working `InputConnection`, and the
|
||||||
@@ -35,6 +41,14 @@ arboard = { workspace = true, features = ["wayland-data-control"] }
|
|||||||
# is dated rather than floating.
|
# is dated rather than floating.
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
android-view = { git = "https://github.com/rust-mobile/android-view.git", rev = "bec6c62a96cef8239b0fd7fedeef9b184d02e3a1" }
|
android-view = { git = "https://github.com/rust-mobile/android-view.git", rev = "bec6c62a96cef8239b0fd7fedeef9b184d02e3a1" }
|
||||||
|
# I4 (RUST.md): the Android half of the AccessKit push, over android-view's
|
||||||
|
# `AccessibilityNodeProvider`. **0.8.0 carries the same detach-abort E1
|
||||||
|
# found on 0.4.0** (the `State` enum still never returns to `Inactive`,
|
||||||
|
# and `send_completed_event` still unwraps a Java exception) -- advancing
|
||||||
|
# the version is not the fix, so pinning to a specific rev buys nothing
|
||||||
|
# here the way it does for android-view itself. `android/view.rs`'s
|
||||||
|
# `raise_if_enabled` is the mitigation, carried from E1.
|
||||||
|
accesskit_android = "0.8.0"
|
||||||
# Not re-exported by android-view (only `jni` and `ndk` are), and needed
|
# Not re-exported by android-view (only `jni` and `ndk` are), and needed
|
||||||
# for `android/insets.rs`'s own id -> state map -- the same reason
|
# for `android/insets.rs`'s own id -> state map -- the same reason
|
||||||
# android-view's own `PEER_MAP` carries one.
|
# android-view's own `PEER_MAP` carries one.
|
||||||
@@ -82,6 +96,7 @@ parley = "0.11.1"
|
|||||||
swash = "0.2.10"
|
swash = "0.2.10"
|
||||||
fxhash = "0.2.1"
|
fxhash = "0.2.1"
|
||||||
arboard = "3.6.1"
|
arboard = "3.6.1"
|
||||||
|
accesskit = "0.25.0"
|
||||||
iris-core = { path = "core" }
|
iris-core = { path = "core" }
|
||||||
iris-macro = { path = "macro" }
|
iris-macro = { path = "macro" }
|
||||||
tokio = "1.49.0"
|
tokio = "1.49.0"
|
||||||
Generated
+698
@@ -18,6 +18,126 @@ version = "0.1.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
|
checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit"
|
||||||
|
version = "0.25.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "438a7081a65b95c668db56591a4fef9bc5dad275f448bd6223fc6949d823db38"
|
||||||
|
dependencies = [
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_android"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "929aff36b0d3dd22ddb59191989d5293ed958294d7728bd6c2ec9778f73414aa"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_consumer",
|
||||||
|
"jni 0.21.1",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_atspi_common"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c9d47ad644916f6cb7e432a5ca0dbd7cc78281a9772881057bb72d4aadb93257"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_consumer",
|
||||||
|
"atspi-common",
|
||||||
|
"phf",
|
||||||
|
"serde",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_consumer"
|
||||||
|
version = "0.39.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc882fa0c9c24c53649e256311b51046cf36eca9a8f7e54ff4ef682160b0cb27"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"hashbrown 0.17.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_ios"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d5e9b29c6ba5f4d2e0662e9c562484f061ffc58f658479c538ecca8299ada1e9"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_consumer",
|
||||||
|
"hashbrown 0.17.1",
|
||||||
|
"objc2 0.5.2",
|
||||||
|
"objc2-foundation 0.2.2",
|
||||||
|
"objc2-ui-kit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_macos"
|
||||||
|
version = "0.27.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3f278988416e5fb600f24d0cfffe31a249ebbff980fb9c5a3b5fbed2c579f73"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_consumer",
|
||||||
|
"hashbrown 0.17.1",
|
||||||
|
"objc2 0.5.2",
|
||||||
|
"objc2-app-kit 0.2.2",
|
||||||
|
"objc2-foundation 0.2.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_unix"
|
||||||
|
version = "0.23.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "665c9079b7325a8168a6793437a172dda44b19a05af8ed52d7e32abaada996fe"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_atspi_common",
|
||||||
|
"async-channel",
|
||||||
|
"async-executor",
|
||||||
|
"async-task",
|
||||||
|
"atspi",
|
||||||
|
"futures-lite",
|
||||||
|
"futures-util",
|
||||||
|
"serde",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_windows"
|
||||||
|
version = "0.35.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a59e8d7160cbac991c1345c99153783ab96423644ccb1f20617cf80c97596aa1"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_consumer",
|
||||||
|
"hashbrown 0.17.1",
|
||||||
|
"static_assertions",
|
||||||
|
"windows",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "accesskit_winit"
|
||||||
|
version = "0.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1eb960a51582305f94b3884a7ff54b3462abe38f0de95a9e7e04dd7ab7b757da"
|
||||||
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_ios",
|
||||||
|
"accesskit_macos",
|
||||||
|
"accesskit_unix",
|
||||||
|
"accesskit_windows",
|
||||||
|
"raw-window-handle",
|
||||||
|
"winit",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler2"
|
name = "adler2"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
@@ -215,12 +335,180 @@ dependencies = [
|
|||||||
"libloading",
|
"libloading",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-broadcast"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener",
|
||||||
|
"event-listener-strategy",
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-channel"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
|
||||||
|
dependencies = [
|
||||||
|
"concurrent-queue",
|
||||||
|
"event-listener-strategy",
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-executor"
|
||||||
|
version = "1.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a"
|
||||||
|
dependencies = [
|
||||||
|
"async-task",
|
||||||
|
"concurrent-queue",
|
||||||
|
"fastrand",
|
||||||
|
"futures-lite",
|
||||||
|
"pin-project-lite",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-io"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"cfg-if",
|
||||||
|
"concurrent-queue",
|
||||||
|
"futures-io",
|
||||||
|
"futures-lite",
|
||||||
|
"parking",
|
||||||
|
"polling",
|
||||||
|
"rustix 1.1.4",
|
||||||
|
"slab",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-lock"
|
||||||
|
version = "3.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener",
|
||||||
|
"event-listener-strategy",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-process"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
|
||||||
|
dependencies = [
|
||||||
|
"async-channel",
|
||||||
|
"async-io",
|
||||||
|
"async-lock",
|
||||||
|
"async-signal",
|
||||||
|
"async-task",
|
||||||
|
"blocking",
|
||||||
|
"cfg-if",
|
||||||
|
"event-listener",
|
||||||
|
"futures-lite",
|
||||||
|
"rustix 1.1.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-recursion"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-signal"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485"
|
||||||
|
dependencies = [
|
||||||
|
"async-io",
|
||||||
|
"async-lock",
|
||||||
|
"atomic-waker",
|
||||||
|
"cfg-if",
|
||||||
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"rustix 1.1.4",
|
||||||
|
"signal-hook-registry",
|
||||||
|
"slab",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-task"
|
||||||
|
version = "4.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.92"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atspi"
|
||||||
|
version = "0.29.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c77886257be21c9cd89a4ae7e64860c6f0eefca799bb79127913052bd0eefb3d"
|
||||||
|
dependencies = [
|
||||||
|
"atspi-common",
|
||||||
|
"atspi-proxies",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atspi-common"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20c5617155740c98003016429ad13fe43ce7a77b007479350a9f8bf95a29f63d"
|
||||||
|
dependencies = [
|
||||||
|
"enumflags2",
|
||||||
|
"serde",
|
||||||
|
"static_assertions",
|
||||||
|
"zbus",
|
||||||
|
"zbus-lockstep",
|
||||||
|
"zbus-lockstep-macros",
|
||||||
|
"zbus_names",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atspi-proxies"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2230e48787ed3eb4088996eab66a32ca20c0b67bbd4fd6cdfe79f04f1f04c9fc"
|
||||||
|
dependencies = [
|
||||||
|
"atspi-common",
|
||||||
|
"serde",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
@@ -327,6 +615,19 @@ dependencies = [
|
|||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blocking"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa"
|
||||||
|
dependencies = [
|
||||||
|
"async-channel",
|
||||||
|
"async-task",
|
||||||
|
"futures-io",
|
||||||
|
"futures-lite",
|
||||||
|
"piper",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "built"
|
name = "built"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
@@ -648,6 +949,33 @@ version = "1.18.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34"
|
checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "endi"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enumflags2"
|
||||||
|
version = "0.7.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
|
||||||
|
dependencies = [
|
||||||
|
"enumflags2_derive",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enumflags2_derive"
|
||||||
|
version = "0.7.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_filter"
|
name = "env_filter"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
@@ -700,6 +1028,26 @@ version = "3.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b5343afd4a8365a643ac588dab4cf234a190c7f6c88c9f6dd6ffe00837661b7"
|
checksum = "0b5343afd4a8365a643ac588dab4cf234a190c7f6c88c9f6dd6ffe00837661b7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener"
|
||||||
|
version = "5.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2"
|
||||||
|
dependencies = [
|
||||||
|
"parking",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener-strategy"
|
||||||
|
version = "0.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "exr"
|
name = "exr"
|
||||||
version = "1.74.2"
|
version = "1.74.2"
|
||||||
@@ -717,6 +1065,12 @@ dependencies = [
|
|||||||
"zune-inflate",
|
"zune-inflate",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fax"
|
name = "fax"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
@@ -831,6 +1185,36 @@ version = "0.3.34"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
|
checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-lite"
|
||||||
|
version = "2.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad"
|
||||||
|
dependencies = [
|
||||||
|
"fastrand",
|
||||||
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"parking",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-macro"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.34"
|
version = "0.3.34"
|
||||||
@@ -844,6 +1228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
|
checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-macro",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"slab",
|
"slab",
|
||||||
@@ -1026,6 +1411,12 @@ version = "0.5.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284"
|
checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hexf-parse"
|
name = "hexf-parse"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@@ -1225,6 +1616,9 @@ dependencies = [
|
|||||||
name = "iris"
|
name = "iris"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
|
"accesskit_android",
|
||||||
|
"accesskit_winit",
|
||||||
"android-view",
|
"android-view",
|
||||||
"arboard",
|
"arboard",
|
||||||
"image",
|
"image",
|
||||||
@@ -1255,6 +1649,7 @@ dependencies = [
|
|||||||
name = "iris-core"
|
name = "iris-core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"accesskit",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"image",
|
"image",
|
||||||
@@ -1541,6 +1936,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "metal"
|
name = "metal"
|
||||||
version = "0.33.0"
|
version = "0.33.0"
|
||||||
@@ -2069,6 +2473,16 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-stream"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_pipe"
|
name = "os_pipe"
|
||||||
version = "1.2.3"
|
version = "1.2.3"
|
||||||
@@ -2088,6 +2502,12 @@ dependencies = [
|
|||||||
"ttf-parser",
|
"ttf-parser",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.5"
|
version = "0.12.5"
|
||||||
@@ -2173,6 +2593,49 @@ dependencies = [
|
|||||||
"indexmap",
|
"indexmap",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "010378780309880b08997fae13be7834dba947d36393bd372f2b1556deb2a2f6"
|
||||||
|
dependencies = [
|
||||||
|
"phf_macros",
|
||||||
|
"phf_shared",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_generator"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aeb62e0959d5a1bebc965f4d15d9e2b7cea002b6b0f5ba8cde6cc26738467100"
|
||||||
|
dependencies = [
|
||||||
|
"fastrand",
|
||||||
|
"phf_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_macros"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fa8d0ca26d424d27630da600c6624696e7dec8bf7b3b492b383c5dc49e5e085"
|
||||||
|
dependencies = [
|
||||||
|
"phf_generator",
|
||||||
|
"phf_shared",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c6fd9027e2d9319be6349febd1db4e8d02aa544921200c9b777720ac34a3aa89"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.1.13"
|
version = "1.1.13"
|
||||||
@@ -2199,6 +2662,17 @@ version = "0.2.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "piper"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-waker",
|
||||||
|
"fastrand",
|
||||||
|
"futures-io",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.34"
|
version = "0.3.34"
|
||||||
@@ -2733,12 +3207,33 @@ dependencies = [
|
|||||||
"syn 3.0.5",
|
"syn 3.0.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_repr"
|
||||||
|
version = "0.1.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
||||||
|
dependencies = [
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simd-adler32"
|
name = "simd-adler32"
|
||||||
version = "0.3.10"
|
version = "0.3.10"
|
||||||
@@ -2770,6 +3265,12 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "skrifa"
|
name = "skrifa"
|
||||||
version = "0.44.0"
|
version = "0.44.0"
|
||||||
@@ -2913,6 +3414,19 @@ dependencies = [
|
|||||||
"iris",
|
"iris",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.27.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
|
||||||
|
dependencies = [
|
||||||
|
"fastrand",
|
||||||
|
"getrandom 0.4.3",
|
||||||
|
"once_cell",
|
||||||
|
"rustix 1.1.4",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
@@ -3058,14 +3572,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.36"
|
version = "0.1.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tree_magic_mini"
|
name = "tree_magic_mini"
|
||||||
@@ -3084,6 +3613,17 @@ version = "0.25.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
|
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uds_windows"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
|
||||||
|
dependencies = [
|
||||||
|
"memoffset",
|
||||||
|
"tempfile",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ui-events"
|
name = "ui-events"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -3118,6 +3658,17 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.26.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5772d71c9be8a8a6ac2117d949c5b224c1b72241bb611d9a3012edcf8af7812"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"serde_core",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "v_frame"
|
name = "v_frame"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@@ -4044,6 +4595,112 @@ dependencies = [
|
|||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus"
|
||||||
|
version = "5.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5db4be7c075cb421e4b7ee645541604239bd243ba7c357511f4ff3a74b555907"
|
||||||
|
dependencies = [
|
||||||
|
"async-broadcast",
|
||||||
|
"async-executor",
|
||||||
|
"async-io",
|
||||||
|
"async-lock",
|
||||||
|
"async-process",
|
||||||
|
"async-recursion",
|
||||||
|
"async-task",
|
||||||
|
"async-trait",
|
||||||
|
"blocking",
|
||||||
|
"enumflags2",
|
||||||
|
"event-listener",
|
||||||
|
"futures-core",
|
||||||
|
"futures-lite",
|
||||||
|
"hex",
|
||||||
|
"libc",
|
||||||
|
"ordered-stream",
|
||||||
|
"rustix 1.1.4",
|
||||||
|
"serde",
|
||||||
|
"serde_repr",
|
||||||
|
"tracing",
|
||||||
|
"uds_windows",
|
||||||
|
"uuid",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
"winnow",
|
||||||
|
"zbus_macros",
|
||||||
|
"zbus_names",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus-lockstep"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6998de05217a084b7578728a9443d04ea4cd80f2a0839b8d78770b76ccd45863"
|
||||||
|
dependencies = [
|
||||||
|
"zbus_xml",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus-lockstep-macros"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10da05367f3a7b7553c8cdf8fa91aee6b64afebe32b51c95177957efc47ca3a0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
"zbus-lockstep",
|
||||||
|
"zbus_xml",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus_macros"
|
||||||
|
version = "5.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2990635d09ade6df1868f72f8cac69a876a90981e8bd3c40b1be413f8dc88f40"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-crate",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
"zbus_names",
|
||||||
|
"zvariant",
|
||||||
|
"zvariant_utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus_names"
|
||||||
|
version = "4.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8bf88b4a3ff53e883001e0e0115b297a9d53c31b9c1edd2bfdd853e3428624e"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"winnow",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus_xml"
|
||||||
|
version = "5.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1586c021a01ca0a9216dcd874e546382e156a5cbab5fab6cb5f10087e22682a"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"winnow",
|
||||||
|
"zbus_names",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zcheapstr"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1afec51604565183aeb5c54c20aeab286120d4e4460f7f76e3e8bb8c0d99473"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeno"
|
name = "zeno"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@@ -4155,3 +4812,44 @@ checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"zune-core",
|
"zune-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zvariant"
|
||||||
|
version = "5.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1d34c27cc6cdd1f458427519dd6b8612f7b7e3f7b9a0b2355d041dda9869147"
|
||||||
|
dependencies = [
|
||||||
|
"endi",
|
||||||
|
"enumflags2",
|
||||||
|
"serde",
|
||||||
|
"winnow",
|
||||||
|
"zcheapstr",
|
||||||
|
"zvariant_derive",
|
||||||
|
"zvariant_utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zvariant_derive"
|
||||||
|
version = "5.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "864155e69b4352db0c7f374917bf45d1e0c8d17659c8b3dbf9795f3673f8c497"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-crate",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
"zvariant_utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zvariant_utils"
|
||||||
|
version = "4.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bad0294361a320b694a328460dc73add56c306150f5cb6bfafc44446120008a3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"syn 3.0.5",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
@@ -10,3 +10,4 @@ image = { workspace = true }
|
|||||||
parley = { workspace = true }
|
parley = { workspace = true }
|
||||||
swash = { workspace = true }
|
swash = { workspace = true }
|
||||||
fxhash = { workspace = true }
|
fxhash = { workspace = true }
|
||||||
|
accesskit = { workspace = true }
|
||||||
@@ -421,7 +421,7 @@ impl Display for UiRegion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct PixelRegion {
|
pub struct PixelRegion {
|
||||||
pub top_left: Vec2,
|
pub top_left: Vec2,
|
||||||
pub bot_right: Vec2,
|
pub bot_right: Vec2,
|
||||||
|
|||||||
@@ -0,0 +1,152 @@
|
|||||||
|
//! I4 (RUST.md): an AccessKit tree built from iris's own widget tree,
|
||||||
|
//! shared by both backends -- `android/view.rs` pushes its `TreeUpdate`s
|
||||||
|
//! through `accesskit_android::Adapter`, `default/mod.rs` through
|
||||||
|
//! `accesskit_winit::Adapter`. Kept modular the way input's sense registry
|
||||||
|
//! is: `Widgets::named()` is a side set populated only by `.label()`, so a
|
||||||
|
//! widget nobody named is never visited here at all, not even to decide it
|
||||||
|
//! has no name.
|
||||||
|
//!
|
||||||
|
//! The tree itself is deliberately flat -- one synthetic `Role::Window`
|
||||||
|
//! root with every named widget as a direct child, in no particular order.
|
||||||
|
//! iris's actual widget nesting (a label three `Span`s deep inside a
|
||||||
|
//! `Scroll`) carries no accessibility meaning of its own here: nothing
|
||||||
|
//! upstream of a named leaf needs a node, since a screen reader's own
|
||||||
|
//! traversal (and uiautomator's tap-by-name, the pass condition this was
|
||||||
|
//! built for) works from each node's on-screen bounds rather than from
|
||||||
|
//! tree structure. Mirroring the real widget tree exactly would also mean
|
||||||
|
//! rebuilding intermediate nodes whenever *any* container above a named
|
||||||
|
//! widget resizes, which is most frames -- the flat shape is what keeps
|
||||||
|
//! rebuilds tied to "a name, a role or a position actually changed".
|
||||||
|
|
||||||
|
use crate::{PixelRegion, UiRenderState, UiRsc, WidgetId, Widgets, util::HashMap};
|
||||||
|
use accesskit::{Node, NodeId, Rect, Role, TreeId, TreeInfo, TreeUpdate};
|
||||||
|
|
||||||
|
/// Reserved for the synthetic root; every real widget's `SlotId::as_u64`
|
||||||
|
/// starts at 1, so this can never collide with one (see that method's
|
||||||
|
/// doc comment).
|
||||||
|
const WINDOW_NODE: NodeId = NodeId(0);
|
||||||
|
|
||||||
|
fn node_id(id: WidgetId) -> NodeId {
|
||||||
|
NodeId(id.as_u64())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq)]
|
||||||
|
struct Entry {
|
||||||
|
name: String,
|
||||||
|
role: Role,
|
||||||
|
bounds: PixelRegion,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn entry_node(entry: &Entry) -> Node {
|
||||||
|
let mut node = Node::new(entry.role);
|
||||||
|
node.set_label(entry.name.clone());
|
||||||
|
node.set_bounds(Rect {
|
||||||
|
x0: entry.bounds.top_left.x as f64,
|
||||||
|
y0: entry.bounds.top_left.y as f64,
|
||||||
|
x1: entry.bounds.bot_right.x as f64,
|
||||||
|
y1: entry.bounds.bot_right.y as f64,
|
||||||
|
});
|
||||||
|
node
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Owns the last tree pushed out, so `update` can tell "nothing
|
||||||
|
/// accessibility-relevant changed" from "something did" without asking
|
||||||
|
/// the platform adapter to diff two `Node`s itself. One of these per
|
||||||
|
/// window/view -- `default::DefaultUiState` and `android::AndroidUiState`
|
||||||
|
/// each keep one.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct AccessTree {
|
||||||
|
known: HashMap<WidgetId, Entry>,
|
||||||
|
/// `TreeUpdate`s actually produced since the last `take_rebuilds` --
|
||||||
|
/// the AccessKit-tree twin of `UiRenderState::take_counters`. Should
|
||||||
|
/// stay at 0 across an unchanged frame and move by exactly 1 when a
|
||||||
|
/// named widget's position, name or role changes, however many other
|
||||||
|
/// widgets are on screen; see `iris/src/access_tests.rs`.
|
||||||
|
rebuilds: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AccessTree {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn collect(
|
||||||
|
widgets: &Widgets,
|
||||||
|
render: &UiRenderState,
|
||||||
|
rsc: &dyn UiRsc,
|
||||||
|
) -> HashMap<WidgetId, Entry> {
|
||||||
|
let mut current = HashMap::default();
|
||||||
|
for id in widgets.named() {
|
||||||
|
let Some(bounds) = render.window_region(&id, rsc) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(widget) = widgets.get_dyn(id) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
current.insert(
|
||||||
|
id,
|
||||||
|
Entry {
|
||||||
|
name: widgets.label(id).clone(),
|
||||||
|
role: widget.access_role(),
|
||||||
|
bounds,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
current
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Walks `widgets.named()`, looks up each one's current screen bounds
|
||||||
|
/// via `render.window_region` (which resolves the same move-chain
|
||||||
|
/// `resolved_region` does, so a moved subtree reports where it
|
||||||
|
/// actually is), and returns a full `TreeUpdate` if and only if that
|
||||||
|
/// set differs from the last call -- added, removed, renamed, or
|
||||||
|
/// moved/resized. A widget that is named but not currently active
|
||||||
|
/// (not drawn this frame) is left out, the same as one never named at
|
||||||
|
/// all.
|
||||||
|
pub fn update(
|
||||||
|
&mut self,
|
||||||
|
widgets: &Widgets,
|
||||||
|
render: &UiRenderState,
|
||||||
|
rsc: &dyn UiRsc,
|
||||||
|
) -> Option<TreeUpdate> {
|
||||||
|
let current = Self::collect(widgets, render, rsc);
|
||||||
|
if current == self.known {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
self.known = current.clone();
|
||||||
|
self.rebuilds += 1;
|
||||||
|
Some(build_update(¤t))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The unconditional twin of `update`, for a platform adapter's
|
||||||
|
/// activation handler (`android/access.rs`'s `AndroidAccessSource`) --
|
||||||
|
/// AccessKit asks for a full tree the first time a client attaches,
|
||||||
|
/// which is exactly the case `update`'s diff-against-`known` is not
|
||||||
|
/// meant to answer (it may have already sent this same snapshot to a
|
||||||
|
/// client that has since detached and reattached).
|
||||||
|
pub fn build_full(widgets: &Widgets, render: &UiRenderState, rsc: &dyn UiRsc) -> TreeUpdate {
|
||||||
|
build_update(&Self::collect(widgets, render, rsc))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads and zeroes the rebuild counter, the same call shape as
|
||||||
|
/// `UiRenderState::take_counters`.
|
||||||
|
pub fn take_rebuilds(&mut self) -> u64 {
|
||||||
|
std::mem::take(&mut self.rebuilds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_update(current: &HashMap<WidgetId, Entry>) -> TreeUpdate {
|
||||||
|
let mut window = Node::new(Role::Window);
|
||||||
|
let mut nodes = Vec::with_capacity(current.len() + 1);
|
||||||
|
for (&id, entry) in current {
|
||||||
|
window.push_child(node_id(id));
|
||||||
|
nodes.push((node_id(id), entry_node(entry)));
|
||||||
|
}
|
||||||
|
nodes.push((WINDOW_NODE, window));
|
||||||
|
TreeUpdate {
|
||||||
|
nodes,
|
||||||
|
tree: Some(TreeInfo::new(WINDOW_NODE)),
|
||||||
|
tree_id: TreeId::ROOT,
|
||||||
|
focus: WINDOW_NODE,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,10 +2,12 @@ use crate::{
|
|||||||
Mask, MoveOffset, TextData, Textures, WeakWidget, WidgetId, Widgets, util::TrackedArena,
|
Mask, MoveOffset, TextData, Textures, WeakWidget, WidgetId, Widgets, util::TrackedArena,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod access;
|
||||||
mod active;
|
mod active;
|
||||||
mod painter;
|
mod painter;
|
||||||
mod render_state;
|
mod render_state;
|
||||||
|
|
||||||
|
pub use access::*;
|
||||||
pub use active::*;
|
pub use active::*;
|
||||||
pub use painter::Painter;
|
pub use painter::Painter;
|
||||||
pub use render_state::*;
|
pub use render_state::*;
|
||||||
|
|||||||
@@ -4,6 +4,17 @@ pub struct SlotId {
|
|||||||
genr: u32,
|
genr: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SlotId {
|
||||||
|
/// A stable, collision-free `u64` encoding of this id -- for a caller
|
||||||
|
/// (accesskit's `NodeId`, today) that wants a flat integer key rather
|
||||||
|
/// than the two `u32`s. `idx` is offset by one so no real id ever
|
||||||
|
/// encodes to 0, which callers can then reserve for their own
|
||||||
|
/// out-of-band root/window node.
|
||||||
|
pub fn as_u64(&self) -> u64 {
|
||||||
|
((self.idx as u64) + 1) << 32 | self.genr as u64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct SlotVec<T> {
|
pub struct SlotVec<T> {
|
||||||
data: Vec<(u32, Option<T>)>,
|
data: Vec<(u32, Option<T>)>,
|
||||||
free: Vec<u32>,
|
free: Vec<u32>,
|
||||||
|
|||||||
@@ -29,6 +29,18 @@ pub trait Widget: Any {
|
|||||||
fn is_size_independent(&self) -> bool {
|
fn is_size_independent(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// What kind of control this is, for the AccessKit tree `ui::access`
|
||||||
|
/// builds (RUST.md's I4). Only consulted for a widget that also has an
|
||||||
|
/// explicit `.label()` -- an unnamed widget is never visited by that
|
||||||
|
/// tree at all, named or not, so the default here costs nothing except
|
||||||
|
/// at the handful of call sites that opt in. Default `Unknown` (a
|
||||||
|
/// generic control with no more specific semantics); a widget with a
|
||||||
|
/// real platform equivalent -- `TextEdit`'s `MultilineTextInput` --
|
||||||
|
/// overrides it.
|
||||||
|
fn access_role(&self) -> accesskit::Role {
|
||||||
|
accesskit::Role::Unknown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for () {
|
impl Widget for () {
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ pub struct Widgets {
|
|||||||
send: Sender<WidgetId>,
|
send: Sender<WidgetId>,
|
||||||
recv: Receiver<WidgetId>,
|
recv: Receiver<WidgetId>,
|
||||||
pub(crate) waiting: HashSet<WidgetId>,
|
pub(crate) waiting: HashSet<WidgetId>,
|
||||||
|
/// Every widget that has ever been given an explicit `.label()` --
|
||||||
|
/// `ui::access::AccessTree` walks exactly this set, not the whole
|
||||||
|
/// arena, so a widget nobody named costs it nothing. Symmetric with
|
||||||
|
/// `free_next` below, which is this set's one removal path.
|
||||||
|
named: HashSet<WidgetId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widgets {
|
impl Widgets {
|
||||||
@@ -20,6 +25,7 @@ impl Widgets {
|
|||||||
needs_redraw: Default::default(),
|
needs_redraw: Default::default(),
|
||||||
vec: Default::default(),
|
vec: Default::default(),
|
||||||
waiting: Default::default(),
|
waiting: Default::default(),
|
||||||
|
named: Default::default(),
|
||||||
send,
|
send,
|
||||||
recv,
|
recv,
|
||||||
}
|
}
|
||||||
@@ -95,9 +101,20 @@ impl Widgets {
|
|||||||
&self.data(id.id()).unwrap().label
|
&self.data(id.id()).unwrap().label
|
||||||
}
|
}
|
||||||
|
|
||||||
/// useful for debugging
|
/// Also the one place a widget opts into `ui::access`'s AccessKit tree
|
||||||
|
/// (RUST.md's I4) -- see `named`'s doc comment.
|
||||||
pub fn set_label(&mut self, id: impl IdLike, label: String) {
|
pub fn set_label(&mut self, id: impl IdLike, label: String) {
|
||||||
self.data_mut(id.id()).unwrap().label = label;
|
let id = id.id();
|
||||||
|
self.data_mut(id).unwrap().label = label;
|
||||||
|
self.named.insert(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Every widget with an explicit name, for `ui::access::AccessTree` to
|
||||||
|
/// walk. Order is unspecified; `AccessTree` doesn't need one; a screen
|
||||||
|
/// reader's own traversal is worked out by uiautomator from each
|
||||||
|
/// node's on-screen bounds instead.
|
||||||
|
pub fn named(&self) -> impl Iterator<Item = WidgetId> + '_ {
|
||||||
|
self.named.iter().copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn data_mut(&mut self, id: impl IdLike) -> Option<&mut WidgetData> {
|
pub fn data_mut(&mut self, id: impl IdLike) -> Option<&mut WidgetData> {
|
||||||
@@ -107,6 +124,7 @@ impl Widgets {
|
|||||||
pub fn free_next(&mut self) -> Option<WidgetId> {
|
pub fn free_next(&mut self) -> Option<WidgetId> {
|
||||||
let next = self.recv.try_recv().ok()?;
|
let next = self.recv.try_recv().ok()?;
|
||||||
self.vec.free(next);
|
self.vec.free(next);
|
||||||
|
self.named.remove(&next);
|
||||||
Some(next)
|
Some(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
//! Pass conditions for RUST.md's I4, exercised the same way
|
||||||
|
//! `layout_tests.rs` exercises LAYOUT.md's: `AccessTree` only touches
|
||||||
|
//! `Widgets`/`UiRenderState`, neither of which needs a GPU or a window, so
|
||||||
|
//! it can be driven directly against `layout_tests::TestRsc`.
|
||||||
|
|
||||||
|
use crate::layout_tests::TestRsc;
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_named_widget_reaches_the_tree_with_its_role_and_bounds() {
|
||||||
|
let mut rsc = TestRsc {
|
||||||
|
ui: UiData::default(),
|
||||||
|
};
|
||||||
|
let leaf: WeakWidget<Rect> = rect(UiColor::WHITE).label("Add task").add(&mut rsc);
|
||||||
|
let root = leaf.upgrade(&mut rsc).any();
|
||||||
|
let mut render = UiRenderState::new();
|
||||||
|
render.resize((800.0, 600.0));
|
||||||
|
render.update(&root, &mut rsc);
|
||||||
|
|
||||||
|
let mut access = AccessTree::new();
|
||||||
|
let update = access
|
||||||
|
.update(rsc.widgets(), &render, &rsc)
|
||||||
|
.expect("a first draw with a named widget must produce a tree");
|
||||||
|
|
||||||
|
// One node for the widget, one for the synthetic window root.
|
||||||
|
assert_eq!(update.nodes.len(), 2);
|
||||||
|
let (_, node) = update
|
||||||
|
.nodes
|
||||||
|
.iter()
|
||||||
|
.find(|(_, n)| n.role() != accesskit::Role::Window)
|
||||||
|
.expect("the named widget's own node");
|
||||||
|
assert_eq!(node.label(), Some("Add task"));
|
||||||
|
assert_eq!(node.role(), accesskit::Role::Unknown);
|
||||||
|
let bounds = node.bounds().expect("a drawn widget reports its bounds");
|
||||||
|
let region = render
|
||||||
|
.window_region(&leaf, &rsc)
|
||||||
|
.expect("the widget is active after render.update");
|
||||||
|
assert_eq!(bounds.x0, region.top_left.x as f64);
|
||||||
|
assert_eq!(bounds.y0, region.top_left.y as f64);
|
||||||
|
assert_eq!(bounds.x1, region.bot_right.x as f64);
|
||||||
|
assert_eq!(bounds.y1, region.bot_right.y as f64);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_widget_with_no_label_never_reaches_the_tree() {
|
||||||
|
let mut rsc = TestRsc {
|
||||||
|
ui: UiData::default(),
|
||||||
|
};
|
||||||
|
let root = rsc.ui.widgets.add_strong(rect(UiColor::WHITE));
|
||||||
|
let mut render = UiRenderState::new();
|
||||||
|
render.resize((800.0, 600.0));
|
||||||
|
render.update(&root.any(), &mut rsc);
|
||||||
|
|
||||||
|
let mut access = AccessTree::new();
|
||||||
|
assert!(
|
||||||
|
access.update(rsc.widgets(), &render, &rsc).is_none(),
|
||||||
|
"no widget was ever `.label()`ed, so there is nothing to report -- \
|
||||||
|
not even an empty tree change"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// LAYOUT.md's "a moved subtree" lesson applies here too: `resolved_region`
|
||||||
|
/// (which `window_region` sits on) walks the move-offset chain, so a
|
||||||
|
/// widget moved via `Offset` -- not redrawn from scratch -- must still
|
||||||
|
/// report where it actually ended up.
|
||||||
|
#[test]
|
||||||
|
fn bounds_follow_a_moved_widget_and_updates_stay_incremental() {
|
||||||
|
let mut rsc = TestRsc {
|
||||||
|
ui: UiData::default(),
|
||||||
|
};
|
||||||
|
let leaf: WeakWidget<Rect> = rect(UiColor::WHITE).label("thing").add(&mut rsc);
|
||||||
|
let leaf_strong = leaf.upgrade(&mut rsc).any();
|
||||||
|
let offset = rsc.ui.widgets.add_strong(Offset {
|
||||||
|
inner: leaf_strong,
|
||||||
|
amt: UiVec2::ZERO,
|
||||||
|
});
|
||||||
|
let offset_id = offset.weak();
|
||||||
|
let root = offset.any();
|
||||||
|
let mut render = UiRenderState::new();
|
||||||
|
render.resize((800.0, 600.0));
|
||||||
|
render.update(&root, &mut rsc);
|
||||||
|
|
||||||
|
let mut access = AccessTree::new();
|
||||||
|
access
|
||||||
|
.update(rsc.widgets(), &render, &rsc)
|
||||||
|
.expect("the first draw is always a change");
|
||||||
|
assert_eq!(access.take_rebuilds(), 1);
|
||||||
|
|
||||||
|
// Unchanged frame: nothing moved, nothing renamed -- `update` must
|
||||||
|
// report no change, and the rebuild counter (I4's twin of
|
||||||
|
// `take_counters`) must stay at 0.
|
||||||
|
render.update(&root, &mut rsc);
|
||||||
|
assert!(access.update(rsc.widgets(), &render, &rsc).is_none());
|
||||||
|
assert_eq!(access.take_rebuilds(), 0);
|
||||||
|
|
||||||
|
// Move the child via `Offset` (a move-offset write, not necessarily a
|
||||||
|
// full redraw of the leaf -- see `resolve_move_chain`) and confirm the
|
||||||
|
// reported bounds shifted by exactly that amount, in exactly one more
|
||||||
|
// rebuild.
|
||||||
|
let before = render
|
||||||
|
.window_region(&leaf, &rsc)
|
||||||
|
.expect("active before the move");
|
||||||
|
rsc.ui.widgets.get_mut(&offset_id).unwrap().amt = UiVec2::abs(Vec2::new(50.0, 0.0));
|
||||||
|
render.update(&root, &mut rsc);
|
||||||
|
let update = access
|
||||||
|
.update(rsc.widgets(), &render, &rsc)
|
||||||
|
.expect("a moved named widget is a change");
|
||||||
|
assert_eq!(access.take_rebuilds(), 1);
|
||||||
|
|
||||||
|
let after = render
|
||||||
|
.window_region(&leaf, &rsc)
|
||||||
|
.expect("still active after the move");
|
||||||
|
// Not asserting the exact delta: `Offset`'s own `amt` -> pixel mapping
|
||||||
|
// is that widget's business, not this tree's. What I4 owns is that
|
||||||
|
// `AccessTree` reports whatever `window_region` says *now* -- so the
|
||||||
|
// node must have moved, and in the direction the offset moved it.
|
||||||
|
assert!(
|
||||||
|
after.top_left.x > before.top_left.x,
|
||||||
|
"the leaf's reported bounds must move right along with its offset"
|
||||||
|
);
|
||||||
|
|
||||||
|
let (_, node) = update
|
||||||
|
.nodes
|
||||||
|
.iter()
|
||||||
|
.find(|(_, n)| n.role() != accesskit::Role::Window)
|
||||||
|
.unwrap();
|
||||||
|
let bounds = node.bounds().unwrap();
|
||||||
|
assert_eq!(bounds.x0, after.top_left.x as f64);
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
//! I4 (RUST.md): the Android half of the AccessKit push, over
|
||||||
|
//! `accesskit_android::Adapter` and android-view's
|
||||||
|
//! `AccessibilityNodeProvider`. Carries E1's mitigation for the adapter's
|
||||||
|
//! reproducible abort: `accesskit_android`'s `State` (0.4.0 and 0.8.0
|
||||||
|
//! alike) never moves back to `Inactive` once a client attaches, so once
|
||||||
|
//! one has, every later `QueuedEvents::raise` reaches
|
||||||
|
//! `AccessibilityManager.sendAccessibilityEvent` -- which throws if
|
||||||
|
//! accessibility has since been switched off (or the client detached),
|
||||||
|
//! and android-view's `panic = "abort"` turns that Java exception into a
|
||||||
|
//! process kill. `raise_if_enabled` is the gate: ask
|
||||||
|
//! `AccessibilityManager.isEnabled()` immediately before every `raise`
|
||||||
|
//! and drop the events instead of calling it when the answer is no. See
|
||||||
|
//! RUST.md's E1 box for the full repro.
|
||||||
|
use accesskit::{ActionHandler, ActionRequest, ActivationHandler, TreeUpdate};
|
||||||
|
use accesskit_android::QueuedEvents;
|
||||||
|
use android_view::{
|
||||||
|
View,
|
||||||
|
jni::{JNIEnv, objects::JObject},
|
||||||
|
};
|
||||||
|
use iris_core::{AccessTree, UiRenderState, UiRsc, Widgets};
|
||||||
|
|
||||||
|
/// The `ActivationHandler` `accesskit_android::Adapter` asks for its
|
||||||
|
/// initial tree from -- unlike `accesskit_winit`'s handlers (see
|
||||||
|
/// `default/access.rs`), this one is only ever invoked synchronously from
|
||||||
|
/// inside a JNI callback that already holds everything it needs, so it can
|
||||||
|
/// just borrow `IrisViewPeer`'s own fields for the length of one call
|
||||||
|
/// rather than going through a channel.
|
||||||
|
pub(super) struct AndroidAccessSource<'a> {
|
||||||
|
pub widgets: &'a Widgets,
|
||||||
|
pub render: &'a UiRenderState,
|
||||||
|
pub rsc: &'a dyn UiRsc,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActivationHandler for AndroidAccessSource<'_> {
|
||||||
|
fn request_initial_tree(&mut self) -> Option<TreeUpdate> {
|
||||||
|
Some(AccessTree::build_full(self.widgets, self.render, self.rsc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Every AccessKit action request is inert here -- see this module's doc
|
||||||
|
/// comment and `default/access.rs`'s matching handler for why: a screen
|
||||||
|
/// reader's tap on a named node is a real touch delivered at that node's
|
||||||
|
/// bounds, which the ordinary pointer path already handles once the
|
||||||
|
/// bounds `AccessTree` reports are right.
|
||||||
|
pub(super) struct NullActionHandler;
|
||||||
|
impl ActionHandler for NullActionHandler {
|
||||||
|
fn do_action(&mut self, _request: ActionRequest) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_accessibility_enabled<'local>(env: &mut JNIEnv<'local>, view: &View<'local>) -> bool {
|
||||||
|
let context = view.context(env);
|
||||||
|
let name = env.new_string("accessibility").unwrap();
|
||||||
|
let manager: JObject = env
|
||||||
|
.call_method(
|
||||||
|
&context.0,
|
||||||
|
"getSystemService",
|
||||||
|
"(Ljava/lang/String;)Ljava/lang/Object;",
|
||||||
|
&[(&name).into()],
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.l()
|
||||||
|
.unwrap();
|
||||||
|
if manager.is_null() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
env.call_method(&manager, "isEnabled", "()Z", &[])
|
||||||
|
.unwrap()
|
||||||
|
.z()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The one place `QueuedEvents::raise` may be called -- see this module's
|
||||||
|
/// doc comment. Every call site pushes this as a deferred callback rather
|
||||||
|
/// than calling it inline, matching android-view's own demo: `raise`
|
||||||
|
/// itself asks not to be called while the caller holds locks a framework
|
||||||
|
/// callback might, and a deferred callback runs after the current one has
|
||||||
|
/// returned them.
|
||||||
|
pub(super) fn raise_if_enabled<'local>(
|
||||||
|
env: &mut JNIEnv<'local>,
|
||||||
|
view: &View<'local>,
|
||||||
|
events: QueuedEvents,
|
||||||
|
) {
|
||||||
|
if is_accessibility_enabled(env, view) {
|
||||||
|
events.raise(env, &view.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
//! counterpart: winit cannot drive an IME beyond `Ime::Preedit`/`Commit`
|
//! counterpart: winit cannot drive an IME beyond `Ime::Preedit`/`Commit`
|
||||||
//! (RUST.md's E1) and has no concept of Android's window insets at all.
|
//! (RUST.md's E1) and has no concept of Android's window insets at all.
|
||||||
|
|
||||||
|
mod access;
|
||||||
mod attr;
|
mod attr;
|
||||||
mod ime;
|
mod ime;
|
||||||
mod input;
|
mod input;
|
||||||
|
|||||||
+108
-6
@@ -1,8 +1,10 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::task::RequestRedraw;
|
use crate::task::RequestRedraw;
|
||||||
|
use accesskit_android::Adapter as AccessAdapter;
|
||||||
use android_view::{
|
use android_view::{
|
||||||
CallbackCtx, Context, InputConnection, KeyEvent, MotionEvent, Rect, View, ViewPeer,
|
AccessibilityNodeInfo, AccessibilityNodeProvider, Bundle, CallbackCtx, Context,
|
||||||
jni::JNIEnv,
|
InputConnection, KeyEvent, MotionEvent, Rect, View, ViewPeer,
|
||||||
|
jni::{JNIEnv, sys::jint},
|
||||||
ndk::event::{Keycode, MotionAction},
|
ndk::event::{Keycode, MotionAction},
|
||||||
};
|
};
|
||||||
// `marker::Sized` explicitly: `crate::prelude::*` below also brings in the
|
// `marker::Sized` explicitly: `crate::prelude::*` below also brings in the
|
||||||
@@ -18,6 +20,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
access::{AndroidAccessSource, NullActionHandler, raise_if_enabled},
|
||||||
insets::{Insets, Shared},
|
insets::{Insets, Shared},
|
||||||
render::{AndroidRedrawHandle, AndroidRenderer},
|
render::{AndroidRedrawHandle, AndroidRenderer},
|
||||||
};
|
};
|
||||||
@@ -47,6 +50,13 @@ pub struct AndroidUiState {
|
|||||||
/// path -- see `android/insets.rs` for why they need a registry of
|
/// path -- see `android/insets.rs` for why they need a registry of
|
||||||
/// their own.
|
/// their own.
|
||||||
shared: Rc<RefCell<Shared>>,
|
shared: Rc<RefCell<Shared>>,
|
||||||
|
/// I4 (RUST.md): pushed from `IrisViewPeer::render` and consulted by
|
||||||
|
/// the `AccessibilityNodeProvider` impl below; see `android/access.rs`
|
||||||
|
/// for the abort mitigation every `raise` on it goes through.
|
||||||
|
pub access_adapter: AccessAdapter,
|
||||||
|
/// The AccessKit tree itself -- see `iris_core::AccessTree`'s doc
|
||||||
|
/// comment.
|
||||||
|
pub access: AccessTree,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AndroidUiState {
|
impl AndroidUiState {
|
||||||
@@ -60,6 +70,8 @@ impl AndroidUiState {
|
|||||||
compose_len: 0,
|
compose_len: 0,
|
||||||
pending_show_keyboard: false,
|
pending_show_keyboard: false,
|
||||||
shared,
|
shared,
|
||||||
|
access_adapter: Default::default(),
|
||||||
|
access: AccessTree::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +246,7 @@ impl<State: AndroidAppState> IrisViewPeer<State> {
|
|||||||
/// it -- on both the Vulkan/SwiftShader and GLES/virgl backends. Leave
|
/// it -- on both the Vulkan/SwiftShader and GLES/virgl backends. Leave
|
||||||
/// these in until that is root-caused; removing them loses the exact
|
/// these in until that is root-caused; removing them loses the exact
|
||||||
/// evidence a `logcat` capture needs to reproduce the state.
|
/// evidence a `logcat` capture needs to reproduce the state.
|
||||||
fn render(&mut self) {
|
fn render(&mut self, ctx: &mut CallbackCtx) {
|
||||||
let ui_state = self.state.android_state();
|
let ui_state = self.state.android_state();
|
||||||
if ui_state.renderer.is_none() {
|
if ui_state.renderer.is_none() {
|
||||||
return;
|
return;
|
||||||
@@ -267,6 +279,26 @@ impl<State: AndroidAppState> IrisViewPeer<State> {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|r| self.render.window_region(r, &self.rsc)),
|
.and_then(|r| self.render.window_region(r, &self.rsc)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// I4 (RUST.md): only produces a `TreeUpdate` -- and so only queues
|
||||||
|
// anything to raise -- when the named set actually changed this
|
||||||
|
// frame; see `AccessTree`'s doc comment. Deferred rather than
|
||||||
|
// raised inline so it runs after this callback releases whatever
|
||||||
|
// it's holding, matching android-view's own demo and `raise`'s own
|
||||||
|
// contract.
|
||||||
|
let ui_state = self.state.android_state_mut();
|
||||||
|
if let Some(tree_update) =
|
||||||
|
ui_state
|
||||||
|
.access
|
||||||
|
.update(self.rsc.widgets(), &self.render, &self.rsc)
|
||||||
|
{
|
||||||
|
let ui_state = self.state.android_state_mut();
|
||||||
|
if let Some(events) = ui_state.access_adapter.update_if_active(|| tree_update) {
|
||||||
|
ctx.push_dynamic_deferred_callback(move |env, view| {
|
||||||
|
raise_if_enabled(env, view, events);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +416,7 @@ impl<State: AndroidAppState> ViewPeer for IrisViewPeer<State> {
|
|||||||
let ui_state = self.state.android_state_mut();
|
let ui_state = self.state.android_state_mut();
|
||||||
ui_state.renderer = None;
|
ui_state.renderer = None;
|
||||||
ui_state.renderer = Some(AndroidRenderer::new(window, width as u32, height as u32));
|
ui_state.renderer = Some(AndroidRenderer::new(window, width as u32, height as u32));
|
||||||
self.render();
|
self.render(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn surface_destroyed<'local>(
|
fn surface_destroyed<'local>(
|
||||||
@@ -395,14 +427,84 @@ impl<State: AndroidAppState> ViewPeer for IrisViewPeer<State> {
|
|||||||
self.state.android_state_mut().renderer = None;
|
self.state.android_state_mut().renderer = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_frame(&mut self, _ctx: &mut CallbackCtx, _frame_time_nanos: i64) {
|
fn do_frame(&mut self, ctx: &mut CallbackCtx, _frame_time_nanos: i64) {
|
||||||
self.drain_tasks();
|
self.drain_tasks();
|
||||||
self.render();
|
self.render(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_input_connection(&mut self) -> Option<&mut dyn InputConnection> {
|
fn as_input_connection(&mut self) -> Option<&mut dyn InputConnection> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_accessibility_node_provider(&mut self) -> Option<&mut dyn AccessibilityNodeProvider> {
|
||||||
|
Some(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<State: AndroidAppState> AccessibilityNodeProvider for IrisViewPeer<State> {
|
||||||
|
fn create_accessibility_node_info<'local>(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut CallbackCtx<'local>,
|
||||||
|
virtual_view_id: jint,
|
||||||
|
) -> AccessibilityNodeInfo<'local> {
|
||||||
|
let mut source = AndroidAccessSource {
|
||||||
|
widgets: self.rsc.widgets(),
|
||||||
|
render: &self.render,
|
||||||
|
rsc: &self.rsc,
|
||||||
|
};
|
||||||
|
let ui_state = self.state.android_state_mut();
|
||||||
|
AccessibilityNodeInfo(ui_state.access_adapter.create_accessibility_node_info(
|
||||||
|
&mut source,
|
||||||
|
&mut ctx.env,
|
||||||
|
&ctx.view.0,
|
||||||
|
virtual_view_id,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_focus<'local>(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut CallbackCtx<'local>,
|
||||||
|
focus_type: jint,
|
||||||
|
) -> AccessibilityNodeInfo<'local> {
|
||||||
|
let mut source = AndroidAccessSource {
|
||||||
|
widgets: self.rsc.widgets(),
|
||||||
|
render: &self.render,
|
||||||
|
rsc: &self.rsc,
|
||||||
|
};
|
||||||
|
let ui_state = self.state.android_state_mut();
|
||||||
|
AccessibilityNodeInfo(ui_state.access_adapter.find_focus(
|
||||||
|
&mut source,
|
||||||
|
&mut ctx.env,
|
||||||
|
&ctx.view.0,
|
||||||
|
focus_type,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn perform_action<'local>(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut CallbackCtx<'local>,
|
||||||
|
virtual_view_id: jint,
|
||||||
|
action: jint,
|
||||||
|
arguments: &Bundle<'local>,
|
||||||
|
) -> bool {
|
||||||
|
let Some(action) =
|
||||||
|
accesskit_android::PlatformAction::from_java(&mut ctx.env, action, &arguments.0)
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let ui_state = self.state.android_state_mut();
|
||||||
|
let Some(events) = ui_state.access_adapter.perform_action(
|
||||||
|
&mut NullActionHandler,
|
||||||
|
virtual_view_id,
|
||||||
|
&action,
|
||||||
|
) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
ctx.push_dynamic_deferred_callback(move |env, view| {
|
||||||
|
raise_if_enabled(env, view, events);
|
||||||
|
});
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers `IrisViewPeer<State>`'s native methods and builds one on every
|
/// Registers `IrisViewPeer<State>`'s native methods and builds one on every
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
//! I4 (RUST.md): the desktop half of the AccessKit push, over
|
||||||
|
//! `accesskit_winit`. `bench-lib.sh`'s tap-by-name goes through the
|
||||||
|
//! platform's real accessibility tree, so this crate only has to keep that
|
||||||
|
//! tree in sync with `ui::access::AccessTree`'s output -- nothing here
|
||||||
|
//! reacts to an AccessKit action request, which is why the three handlers
|
||||||
|
//! below are inert. See RUST.md's I4 box for why: on Android (and, by the
|
||||||
|
//! same platform convention, everywhere else) a screen reader's element tap
|
||||||
|
//! is a real touch delivered at the node's own bounds, not an action
|
||||||
|
//! request synthesised in-process -- so the ordinary pointer path already
|
||||||
|
//! handles it once the bounds are right.
|
||||||
|
use accesskit::{ActionHandler, ActionRequest, ActivationHandler, DeactivationHandler, TreeUpdate};
|
||||||
|
|
||||||
|
pub struct NullActivationHandler;
|
||||||
|
impl ActivationHandler for NullActivationHandler {
|
||||||
|
fn request_initial_tree(&mut self) -> Option<TreeUpdate> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NullActionHandler;
|
||||||
|
impl ActionHandler for NullActionHandler {
|
||||||
|
fn do_action(&mut self, _request: ActionRequest) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NullDeactivationHandler;
|
||||||
|
impl DeactivationHandler for NullDeactivationHandler {
|
||||||
|
fn deactivate_accessibility(&mut self) {}
|
||||||
|
}
|
||||||
+46
-3
@@ -11,11 +11,13 @@ use winit::{
|
|||||||
window::{Window, WindowAttributes},
|
window::{Window, WindowAttributes},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod access;
|
||||||
mod app;
|
mod app;
|
||||||
mod attr;
|
mod attr;
|
||||||
mod input;
|
mod input;
|
||||||
mod render;
|
mod render;
|
||||||
|
|
||||||
|
pub use access::*;
|
||||||
pub use app::*;
|
pub use app::*;
|
||||||
pub use input::*;
|
pub use input::*;
|
||||||
pub use render::*;
|
pub use render::*;
|
||||||
@@ -31,6 +33,17 @@ pub struct DefaultUiState {
|
|||||||
pub window: Arc<Window>,
|
pub window: Arc<Window>,
|
||||||
pub ime: usize,
|
pub ime: usize,
|
||||||
pub last_click: Instant,
|
pub last_click: Instant,
|
||||||
|
/// I4 (RUST.md): pushed through in `DefaultApp::window_event`'s
|
||||||
|
/// `RedrawRequested` arm, from `access`'s output. Built in
|
||||||
|
/// `DefaultApp::new`, which is the only place with the
|
||||||
|
/// `&ActiveEventLoop` `accesskit_winit::Adapter::with_direct_handlers`
|
||||||
|
/// needs -- see that constructor's doc comment on why the window must
|
||||||
|
/// still be invisible when it is called.
|
||||||
|
pub access_adapter: accesskit_winit::Adapter,
|
||||||
|
/// The AccessKit tree itself -- see `iris_core::AccessTree`'s doc
|
||||||
|
/// comment for the flat shape and why it only rebuilds on a real
|
||||||
|
/// change.
|
||||||
|
pub access: AccessTree,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasRoot for DefaultUiState {
|
impl HasRoot for DefaultUiState {
|
||||||
@@ -40,7 +53,7 @@ impl HasRoot for DefaultUiState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DefaultUiState {
|
impl DefaultUiState {
|
||||||
pub fn new(window: impl Into<Arc<Window>>) -> Self {
|
pub fn new(window: impl Into<Arc<Window>>, access_adapter: accesskit_winit::Adapter) -> Self {
|
||||||
let window = window.into();
|
let window = window.into();
|
||||||
Self {
|
Self {
|
||||||
root: None,
|
root: None,
|
||||||
@@ -51,6 +64,8 @@ impl DefaultUiState {
|
|||||||
ime: 0,
|
ime: 0,
|
||||||
last_click: Instant::now(),
|
last_click: Instant::now(),
|
||||||
focus: None,
|
focus: None,
|
||||||
|
access_adapter,
|
||||||
|
access: AccessTree::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,10 +194,24 @@ impl<State: DefaultAppState> AppState for DefaultApp<State> {
|
|||||||
type Event = State::Event;
|
type Event = State::Event;
|
||||||
|
|
||||||
fn new(event_loop: &ActiveEventLoop, proxy: EventLoopProxy<Self::Event>) -> Self {
|
fn new(event_loop: &ActiveEventLoop, proxy: EventLoopProxy<Self::Event>) -> Self {
|
||||||
|
// `accesskit_winit::Adapter::with_direct_handlers` panics if the
|
||||||
|
// window is already visible when it's built, so the window is
|
||||||
|
// created hidden and only shown once the adapter exists -- the one
|
||||||
|
// extra step I4 (RUST.md) needs here. The three handlers are inert
|
||||||
|
// (see `access.rs`): a screen reader's tap is a real touch at the
|
||||||
|
// node's bounds, not an action request this process has to answer.
|
||||||
let window = event_loop
|
let window = event_loop
|
||||||
.create_window(State::window_attributes())
|
.create_window(State::window_attributes().with_visible(false))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let default_state = DefaultUiState::new(window);
|
let access_adapter = accesskit_winit::Adapter::with_direct_handlers(
|
||||||
|
event_loop,
|
||||||
|
&window,
|
||||||
|
NullActivationHandler,
|
||||||
|
NullActionHandler,
|
||||||
|
NullDeactivationHandler,
|
||||||
|
);
|
||||||
|
window.set_visible(true);
|
||||||
|
let default_state = DefaultUiState::new(window, access_adapter);
|
||||||
let (mut rsc, task_recv) = DefaultRsc::init(default_state.window.clone());
|
let (mut rsc, task_recv) = DefaultRsc::init(default_state.window.clone());
|
||||||
let state = State::new(default_state, &mut rsc, proxy);
|
let state = State::new(default_state, &mut rsc, proxy);
|
||||||
let render = UiRenderState::new();
|
let render = UiRenderState::new();
|
||||||
@@ -211,6 +240,12 @@ impl<State: DefaultAppState> AppState for DefaultApp<State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let ui_state = state.default_state_mut();
|
let ui_state = state.default_state_mut();
|
||||||
|
// Required by `accesskit_winit` on every window event, not just the
|
||||||
|
// ones this backend otherwise cares about -- some platform adapters
|
||||||
|
// rely on it to notice activation (a screen reader turning on).
|
||||||
|
ui_state
|
||||||
|
.access_adapter
|
||||||
|
.process_event(&ui_state.window, &event);
|
||||||
let input_changed = ui_state.input.event(&event);
|
let input_changed = ui_state.input.event(&event);
|
||||||
let cursor_state = ui_state.cursor_state().clone();
|
let cursor_state = ui_state.cursor_state().clone();
|
||||||
let old = ui_state.focus;
|
let old = ui_state.focus;
|
||||||
@@ -233,6 +268,14 @@ impl<State: DefaultAppState> AppState for DefaultApp<State> {
|
|||||||
render.update(&ui_state.root, rsc);
|
render.update(&ui_state.root, rsc);
|
||||||
ui_state.renderer.update(&mut rsc.ui, render);
|
ui_state.renderer.update(&mut rsc.ui, render);
|
||||||
ui_state.renderer.draw();
|
ui_state.renderer.draw();
|
||||||
|
// I4 (RUST.md): only produces a `TreeUpdate` when the named
|
||||||
|
// set actually changed this frame -- see `AccessTree`'s doc
|
||||||
|
// comment. `render` reflects the draw that just happened,
|
||||||
|
// so `resolved_region`/`window_region` inside it report a
|
||||||
|
// moved subtree's *new* position, not last frame's.
|
||||||
|
if let Some(tree_update) = ui_state.access.update(rsc.widgets(), render, rsc) {
|
||||||
|
ui_state.access_adapter.update_if_active(|| tree_update);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
WindowEvent::Resized(size) => {
|
WindowEvent::Resized(size) => {
|
||||||
render.resize((size.width, size.height));
|
render.resize((size.width, size.height));
|
||||||
|
|||||||
@@ -7,9 +7,11 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
/// The minimal `UiRsc` a test needs: just the shared `UiData`, none of the
|
/// The minimal `UiRsc` a test needs: just the shared `UiData`, none of the
|
||||||
/// event/window/state plumbing `DefaultRsc` carries.
|
/// event/window/state plumbing `DefaultRsc` carries. `pub(crate)` so
|
||||||
struct TestRsc {
|
/// `access_tests.rs` (I4, RUST.md) can reuse it rather than keeping a
|
||||||
ui: UiData,
|
/// second copy of the same harness.
|
||||||
|
pub(crate) struct TestRsc {
|
||||||
|
pub(crate) ui: UiData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UiRsc for TestRsc {
|
impl UiRsc for TestRsc {
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ pub mod state;
|
|||||||
pub mod task;
|
pub mod task;
|
||||||
pub mod widget;
|
pub mod widget;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod access_tests;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod layout_tests;
|
mod layout_tests;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -114,6 +114,15 @@ impl Widget for TextEdit {
|
|||||||
);
|
);
|
||||||
used
|
used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// I4 (RUST.md): the one override that exists so far -- everything
|
||||||
|
/// else falls back to `Widget::access_role`'s default `Unknown`.
|
||||||
|
fn access_role(&self) -> accesskit::Role {
|
||||||
|
match self.mode {
|
||||||
|
EditMode::SingleLine => accesskit::Role::TextInput,
|
||||||
|
EditMode::MultiLine => accesskit::Role::MultilineTextInput,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const CARET_WIDTH: f32 = 1.0;
|
const CARET_WIDTH: f32 = 1.0;
|
||||||
|
|||||||
@@ -177,7 +177,14 @@ where
|
|||||||
)
|
)
|
||||||
.on(CursorSense::HoverEnd, move |ctx, rsc| {
|
.on(CursorSense::HoverEnd, move |ctx, rsc| {
|
||||||
ctx.widget(rsc).color = color;
|
ctx.widget(rsc).color = color;
|
||||||
});
|
})
|
||||||
|
// I4 (RUST.md): the tabs screen's only named controls, and the
|
||||||
|
// ones the emulator step at the bottom of that box taps by
|
||||||
|
// name -- `ui-trace record --do "tap 'pad'"` and so on. `.label`
|
||||||
|
// slots into this chain like any other widget combinator
|
||||||
|
// (`RefFnTag` in `core/src/widget/tag.rs`); it does not have to
|
||||||
|
// be the last thing before `.add`.
|
||||||
|
.label(label);
|
||||||
(rect, wtext(label).size(30).text_align(Align::CENTER)).stack()
|
(rect, wtext(label).size(30).text_align(Align::CENTER)).stack()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user