diff --git a/crates/benilla-app/src/video.rs b/crates/benilla-app/src/video.rs index 2645d7b93..7b65f2738 100644 --- a/crates/benilla-app/src/video.rs +++ b/crates/benilla-app/src/video.rs @@ -495,9 +495,29 @@ impl Plugin for VideoPlugin { .after(crate::cvars::sync_cvars), ), ); + #[cfg(windows)] + app.add_message::() + .add_systems(First, drop_accessibility_adapter); } } +/// Drops the AccessKit adapter `bevy_winit` gives a new window, which restores winit's window +/// procedure. The reference's window serves no accessibility client (`WoW.exe` imports no such +/// library and names none of its calls), and benilla builds no tree for one to read. The adapter's +/// UI Automation provider is not inert where a client runs: Proton-based Wine's `tabtip.exe` queries +/// the focused window, and that traffic faults in `rpcrt4` on reused memory and damages the heap. +#[cfg_attr(not(windows), allow(dead_code))] +fn drop_accessibility_adapter( + mut created: MessageReader, + _main_thread: bevy::ecs::system::NonSendMarker, +) { + bevy::winit::accessibility::ACCESS_KIT_ADAPTERS.with_borrow_mut(|adapters| { + for created in created.read() { + adapters.remove(&created.window); + } + }); +} + /// How many `RestartGx()` calls the interface has made. A counter, not a flag: each applier keeps /// its own last value, so one bump forces one re-assertion in each, in any order. #[derive(Resource, Default, Clone, Copy, PartialEq, Eq, Debug)] diff --git a/crates/benilla-app/tests/cover_input_wall.rs b/crates/benilla-app/tests/cover_input_wall.rs index 90dd9adfd..facea2266 100644 --- a/crates/benilla-app/tests/cover_input_wall.rs +++ b/crates/benilla-app/tests/cover_input_wall.rs @@ -96,6 +96,7 @@ const VERDICTS: &[(&str, Verdict)] = &[ ("MouseScrollUnit", Plumbing), ("NativeKey", Plumbing), ("NativeKeyCode", Plumbing), + ("ACCESS_KIT_ADAPTERS", Plumbing), ("ExitCondition", Plumbing), ("Monitor", Plumbing), ("MonitorSelection", Plumbing), @@ -104,6 +105,7 @@ const VERDICTS: &[(&str, Verdict)] = &[ ("RawHandleWrapper", Plumbing), ("VideoMode", Plumbing), ("Window", Plumbing), + ("WindowCreated", Plumbing), ("WindowLevel", Plumbing), ("WindowMode", Plumbing), ("WindowPlugin", Plumbing), diff --git a/docs/DEVIATIONS.md b/docs/DEVIATIONS.md index 81209a98c..8b3acdee6 100644 --- a/docs/DEVIATIONS.md +++ b/docs/DEVIATIONS.md @@ -501,7 +501,7 @@ Each entry is the first sentence of a `Deviation:` comment, linking to where it - `gxWindow "0"` is borderless fullscreen, not 1.12's exclusive mode-set at `gxResolution`, because Wayland has no client mode-setting (winit ignores `Fullscreen::Exclusive` there), and X11's XRandR changes the desktop's mode and a crash leaves it changed. Bevy's `WindowMode::Fullscreen` also panics on a live change that cannot resolve a monitor (`bevy_winit::winit_windows:91`, `system.rs:333`). ([`src/video.rs:5`](../crates/benilla-app/src/video.rs#L5)) - On Windows, NVIDIA's Vulkan driver (610.88 seen) crashes inside `vkQueuePresentKHR` on the first present after any swapchain resize while the present mode is `Fifo`, `FifoRelaxed` or `AutoVsync` (a maximize is a resize). The fault is in the driver's own DXGI present (`d3d11.dll`): it stays with `VK_LAYER_NV_present` disabled, and the validation layer reports nothing before it. `Mailbox`, `AutoNoVsync` and DX12 survive, so there "vsync on" is `AutoNoVsync` paced to the monitor's refresh rate (`present_choice`) because that keeps the synced look without the crash. `$WOW_PRESENT=fifo` restores plain `Fifo`. ([`src/video.rs:17`](../crates/benilla-app/src/video.rs#L17)) -- Sizes are logical px, because the windowed `gxResolution` is a logical inner size here. Read at each verb (`DisplayLive`), so the list follows the display and `widescreen`; the reference builds its list once and never invalidates it. ([`src/video.rs:619`](../crates/benilla-app/src/video.rs#L619)) +- Sizes are logical px, because the windowed `gxResolution` is a logical inner size here. Read at each verb (`DisplayLive`), so the list follows the display and `widescreen`; the reference builds its list once and never invalidates it. ([`src/video.rs:639`](../crates/benilla-app/src/video.rs#L639)) #### vplates