Windows drops the accessibility adapter the reference never had (#2975)
Under Proton-based Wine, `tabtip.exe` is a UI Automation client, and `bevy_winit` gives every window an AccessKit provider. That traffic faults in `rpcrt4` on blocks the game has reused, which damages the heap and later crashes the client at varying addresses. Blocking `tabtip.exe` stops the faults and the crash, and other programs in the same bottle show no such faults. The reference's window has no provider: `WoW.exe` imports no accessibility library and names none of its calls. benilla builds no AccessKit tree either. `VideoPlugin` now drops the adapter when Windows reports a new window, which restores winit's window procedure. Other platforms keep theirs. No test: the adapter needs a real window and the fault a UI Automation client. Built for macOS and Windows. Refs #2932 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -495,9 +495,29 @@ impl Plugin for VideoPlugin {
|
||||
.after(crate::cvars::sync_cvars),
|
||||
),
|
||||
);
|
||||
#[cfg(windows)]
|
||||
app.add_message::<bevy::window::WindowCreated>()
|
||||
.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<bevy::window::WindowCreated>,
|
||||
_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)]
|
||||
|
||||
@@ -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),
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user