Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow AccessKit to filter WindowEvents before they reach the engine. #10239

Closed
wants to merge 7 commits into from

Conversation

ndarilek
Copy link
Contributor

This should have been part of #9989 but I didn't know it was necessary at the time.

Without this merged, AccessKit won't completely work on macOS or Unix.

It's draft at the moment because I don't know how to get this borrow working:

error[E0502]: cannot borrow `app.world` as immutable because it is also borrowed as mutable                             
   --> crates\bevy_winit\src\lib.rs:442:41                                                                              
    |                                                                                                                   
422 |                       event_writer_system_state.get_mut(&mut app.world);                                          
    |                                                         -------------- mutable borrow occurs here                 
...                                                                                                                     
442 |                   if let Some(adapters) = app.world.get_non_send_resource::<AccessKitAdapters>() {                
    |                                           ^^^^^^^^^ immutable borrow occurs here                                  
...                                                                                                                     
475 | /                         event_writers                                                                           
476 | |                             .window_close_requested                                                             
    | |___________________________________________________- mutable borrow later used here                              

Help welcome.

@alice-i-cecile alice-i-cecile added O-Linux Specific to the Linux desktop operating system O-MacOS Specific to the MacOS (Apple) desktop operating system A-Accessibility A problem that prevents users with disabilities from using Bevy P-High This is particularly urgent, and deserves immediate attention C-Bug An unexpected or incorrect behavior labels Oct 23, 2023
@alice-i-cecile alice-i-cecile added this to the 0.12 milestone Oct 23, 2023
@SkiFire13
Copy link
Contributor

It's draft at the moment because I don't know how to get this borrow working:

I think you need to change the event_writer_system_state parameter (line 310) to contain a Option<NonSend<AccessKitAdapters>> as well, then destructure it at line 421.

@ndarilek
Copy link
Contributor Author

Hmm, would that require systems to use that signature, though? Wondering if that'd cause needed systems to not be retrieved/called unless they too access the adapters.

Thanks for taking the time to look into this.

@alice-i-cecile
Copy link
Member

alice-i-cecile commented Oct 23, 2023

It's draft at the moment because I don't know how to get this borrow working:

I think you need to change the event_writer_system_state parameter (line 310) to contain a Option<NonSend<AccessKitAdapters>> as well, then destructure it at line 421.

Done in ndarilek#2

Fix borrow checker errors in A11y patch
@ndarilek ndarilek marked this pull request as ready for review October 23, 2023 14:13
@ndarilek
Copy link
Contributor Author

Just tested it with the ui example here and it seems to work as well as it did before. Thanks for the help!

Copy link
Member

@mockersf mockersf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a reason accesskit should be allowed to filter events, could you expand on that?

And looking at the code, it always return true. I would prefer to call the on_event from accesskit but not filter on it.

@ndarilek
Copy link
Contributor Author

CC @mwcampbell and @DataTriny Sorry, can't seem to do a quote reply for some reason but there's confusion about why the event filtering is needed and I don't want to speculate.

Also, be sure you're looking at the right implementation. The Windows version returns true but the Unix version doesn't, so it's definitely doing something.

Looks like more changes may be needed based on emilk/egui#3475 (comment). Going to try getting those in today but this exact moment isn't the best for me to be pivoting away from other projects so those may have to get punted to 0.12.1 if someone else can't get to them. Maybe AccessKit upgrade/migration notes might be a useful thing to have--sorry if they're there and I missed them.

@DataTriny
Copy link

Event filtering is currently unused by AccessKit but there is a high probability it will unfortunately be in the future. We initially needed it for keyboard events on Unix, but worked around the issue on X11. We decided to keep it anyway due to the big architecture constraints it puts on implementors like Bevy.

It will probably be of use for what we call a self-voicing adaptor, which will help provide accessibility on platforms where there is no accessibility stack, like game consoles.

Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a closer look at this code, and filed AccessKit/accesskit#300 requesting improvements to this API. I've left a suggestion for an improved version of Francois's suggestion: the fact that merely calling adapter.on_event has side effects was surprising to me.

We definitely want to call that, but until event filtering is actually implemented and we can test to verify that it does what we want, I don't think we should proactively filter events. Even if this is needed on console, it currently seems unlikely that Bevy's console integration will use winit itself.

@ndarilek
Copy link
Contributor Author

If it's not used then I'm in favor of skipping it as well, though based on emilk/egui#3475 (comment) it sounded like a hard requirement (I.e. used for focus-tracking on macOS and hit-testing on Unix.)

I'd like some clarity on whether this is actually used or not. Thanks.

@alice-i-cecile
Copy link
Member

Yep, @mattcampbell @DataTriny I'd appreciate more clarification on this point. We're fine to retrofit this change in the future once that API is active: the changes we need to make look straightforward.

@DataTriny
Copy link

As I said in emilk/egui#3475: calling on_event is required. I would strongly recommend to not ignore its return value, but since it currently is of no use at the moment I can't really convince anyone. So the suggested changes are acceptable to me.

I agree that the name of this function is not great and that it should be documented, I'll take care of that for accesskit_winit's next release.

@alice-i-cecile
Copy link
Member

Thanks a ton @DataTriny: your expertise here was very helpful.

@mockersf
Copy link
Member

Until there is a clear need for it, I think we should not filter events.

And in the future, I would prefer a design where events are marked as being handled by accessibility, but still have the option to handle them in Bevy or in other plugins that would answer other needs.

@alice-i-cecile
Copy link
Member

I've swapped this over to the non-filtering design for now: happy to revisit in the future but we do need to make and ship this change currently.

@mockersf if this has your approval please go ahead and merge.

@cart
Copy link
Member

cart commented Nov 3, 2023

This fails rustfmt. @ndarilek's branch doesn't support pushes from me so I can't fix it like I normally would.

@ndarilek
Copy link
Contributor Author

ndarilek commented Nov 3, 2023

Oh strange, "Allow edits and access to secrets by maintainers " is checked on my end. Is there something more I need to do?

@cart
Copy link
Member

cart commented Nov 3, 2023

Generally that should be enough. I've encountered this once before and we worked around it by giving me write access to the dev's bevy fork, but thats a nuclear option / not my preference. If you can just run rustfmt on bevy_winit/src/lib.rs and commit, that should solve our immediate problem.

@mockersf
Copy link
Member

mockersf commented Nov 3, 2023

I think the error reported in CI is due to a change on main and this PR needs rebasing.

@ndarilek can you try and fix CI? I can open a PR with your change and get it in shape otherwise

@mockersf
Copy link
Member

mockersf commented Nov 3, 2023

opened #10356 to fix CI

@alice-i-cecile
Copy link
Member

Adopted! Merging the linked PR: you'll be credited appropriately :)

github-merge-queue bot pushed a commit that referenced this pull request Nov 3, 2023
…#10356)

# Objective

- Adopt #10239 to get it in time for the release
- Fix accessibility on macOS and linux

## Solution

- call `on_event` from AcccessKit adapter on winit events

---------

Co-authored-by: Nolan Darilek <nolan@thewordnerd.info>
Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
aevyrie added a commit to aevyrie/bevy that referenced this pull request Nov 4, 2023
Fix branding inconsistencies

don't Implement `Display` for `Val` (bevyengine#10345)

- Revert bevyengine#10296

- Avoid implementing `Display` without a justification
- `Display` implementation is a guarantee without a direct use, takes
additional time to compile and require work to maintain
- `Debug`, `Reflect` or `Serialize` should cover all needs

Combine visibility queries in check_visibility_system (bevyengine#10196)

Alternative to bevyengine#7310

Implemented the suggestion from
bevyengine#7310 (comment)

I am guessing that these were originally split as an optimization, but I
am not sure since I believe the original author of the code is the one
speculating about combining them up there.

I ran three benchmarks to compare main, this PR, and the approach from
([updated](https://github.com/rparrett/bevy/commits/rebased-parallel-check-visibility)
to the same commit on main).

This seems to perform slightly better than main in scenarios where most
entities have AABBs, and a bit worse when they don't (`many_lights`).
That seems to make sense to me.

Either way, the difference is ~-20 microseconds in the more common
scenarios or ~+100 microseconds in the less common scenario. I would
speculate that this might perform **very slightly** worse in
single-threaded scenarios.

Benches were run in release mode for 2000 frames while capturing a trace
with tracy.

| bench | commit | check_visibility_system mean μs |
| -- | -- | -- |
| many_cubes | main | 929.5 |
| many_cubes | this | 914.0 |
| many_cubes | 7310 | 1003.5 |
| | |
| many_foxes | main | 191.6 |
| many_foxes | this | 173.2 |
| many_foxes | 7310 | 167.9 |
| | |
| many_lights | main | 619.3 |
| many_lights | this | 703.7 |
| many_lights | 7310 | 842.5 |

Technically this behaves slightly differently -- prior to this PR, view
visibility was determined even for entities without `GlobalTransform`. I
don't think this has any practical impact though.

IMO, I don't think we need to do this. But I opened a PR because it
seemed like the handiest way to share the code / benchmarks.

I have done some rudimentary testing with the examples above, but I can
do some screenshot diffing if it seems like we want to do this.

Make VERTEX_COLORS usable in prepass shader, if available (bevyengine#10341)

I was working with forward rendering prepass fragment shaders and ran
into an issue of not being able to access vertex colors in the prepass.
I was able to access vertex colors in regular fragment shaders as well
as in deferred shaders.

It seems like this `if` was nested unintentionally as moving it outside
of the `deferred` block works.

---

Enable vertex colors in forward rendering prepass fragment shaders

allow DeferredPrepass to work without other prepass markers (bevyengine#10223)

fix crash / misbehaviour when `DeferredPrepass` is used without
`DepthPrepass`.

- Deferred lighting requires the depth prepass texture to be present, so
that the depth texture is available for binding. without it the deferred
lighting pass will use 0 for depth of all meshes.
- When `DeferredPrepass` is used without other prepass markers, and with
any materials that use `OpaqueRenderMode::Forward`, those entities will
try to queue to the `Opaque3dPrepass` render phase, which doesn't exist,
causing a crash.

- check if the prepass phases exist before queueing
- generate prepass textures if `Opaque3dDeferred` is present
- add a note to the DeferredPrepass marker to note that DepthPrepass is
also required by the default deferred lighting pass
- also changed some `With<T>.is_some()`s to `Has<T>`s

UI batching Fix (bevyengine#9610)

Reimplement bevyengine#8793 on top of the recent rendering changes.

The batch creation logic is quite convoluted, but I tested it on enough
examples to convince myself that it works.

The initial value of `batch_image_handle` is changed from
`HandleId::Id(Uuid::nil(), u64::MAX)` to `DEFAULT_IMAGE_HANDLE.id()`,
which allowed me to make the if-block simpler I think.

The default image from `DEFAULT_IMAGE_HANDLE` is always inserted into
`UiImageBindGroups` even if it's not used. I tried to add a check so
that it would be only inserted when there is only one batch using the
default image but this crashed.

---

`prepare_uinodes`
* Changed the initial value of `batch_image_handle` to
`DEFAULT_IMAGE_HANDLE.id()`.
* The default image is added to the UI image bind groups before
assembling the batches.
* A new `UiBatch` isn't created when the next `ExtractedUiNode`s image
is set to `DEFAULT_IMAGE_HANDLE` (unless it is the first item in the UI
phase items list).

Increase default normal bias to avoid common artifacts (bevyengine#10346)

Bevy's default bias values for directional and spot lights currently
cause significant artifacts. We should fix that so shadows look good by
default!

This is a less controversial/invasive alternative to bevyengine#10188, which might
enable us to keep the default bias value low, but also has its own sets
of concerns and caveats that make it a risky choice for Bevy 0.12.

Bump the default normal bias from `0.6` to `1.8`. There is precedent for
values in this general area as Godot has a default normal bias of `2.0`.

![image](https://github.com/superdump/bevy/assets/2694663/a5828011-33fc-4427-90ed-f093d7389053)

![image](https://github.com/bevyengine/bevy/assets/2694663/0f2b16b0-c116-41ab-9886-1ace9e00efd6)

The default `shadow_normal_bias` value for `DirectionalLight` and
`SpotLight` has changed to accommodate artifacts introduced with the new
shadow PCF changes. It is unlikely (especially given the new PCF shadow
behaviors with these values), but you might need to manually tweak this
value if your scene requires a lower bias and it relied on the previous
default value.

Make `DirectionalLight` `Cascades` computation generic over `CameraProjection` (bevyengine#9226)

Fixes bevyengine#9077 (see this issue for
motivations)

Implement 1 and 2 of the "How to fix it" section of
bevyengine#9077

`update_directional_light_cascades` is split into
`clear_directional_light_cascades` and a generic
`build_directional_light_cascades`, to clear once and potentially insert
many times.

---

`DirectionalLight`'s computation is now generic over `CameraProjection`
and can work with custom camera projections.

If you have a component `MyCustomProjection` that implements
`CameraProjection`:
- You need to implement a new required associated method,
`get_frustum_corners`, returning an array of the corners of a subset of
the frustum with given `z_near` and `z_far`, in local camera space.
- You can now add the
`build_directional_light_cascades::<MyCustomProjection>` system in
`SimulationLightSystems::UpdateDirectionalLightCascades` after
`clear_directional_light_cascades` for your projection to work with
directional lights.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>

Update default `ClearColor` to better match Bevy's branding (bevyengine#10339)

- Changes the default clear color to match the code block color on
Bevy's website.

- Changed the clear color, updated text in examples to ensure adequate
contrast. Inconsistent usage of white text color set to use the default
color instead, which is already white.
- Additionally, updated the `3d_scene` example to make it look a bit
better, and use bevy's branding colors.

![image](https://github.com/bevyengine/bevy/assets/2632925/540a22c0-826c-4c33-89aa-34905e3e313a)

Corrected incorrect doc comment on read_asset_bytes (bevyengine#10352)

Fixes bevyengine#10302

- Removed the incorrect comment.

Allow AccessKit to react to WindowEvents before they reach the engine (bevyengine#10356)

- Adopt bevyengine#10239 to get it in time for the release
- Fix accessibility on macOS and linux

- call `on_event` from AcccessKit adapter on winit events

---------

Co-authored-by: Nolan Darilek <nolan@thewordnerd.info>
Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>

Fix typo in window.rs (bevyengine#10358)

Fixes a small typo in `bevy_window/src/window.rs`

Change `Should be used instead 'scale_factor' when set.` to `Should be
used instead of 'scale_factor' when set.`

Add UI Materials (bevyengine#9506)

- Add Ui Materials so that UI can render more complex and animated
widgets.
- Fixes bevyengine#5607

- Create a UiMaterial trait for specifying a Shader Asset and Bind Group
Layout/Data.
- Create a pipeline for rendering these Materials inside the Ui
layout/tree.
- Create a MaterialNodeBundle for simple spawning.

- Created a `UiMaterial` trait for specifying a Shader asset and Bind
Group.
- Created a `UiMaterialPipeline` for rendering said Materials.
- Added Example [`ui_material`
](https://github.com/MarkusTheOrt/bevy/blob/ui_material/examples/ui/ui_material.rs)
for example usage.
- Created
[`UiVertexOutput`](https://github.com/MarkusTheOrt/bevy/blob/ui_material/crates/bevy_ui/src/render/ui_vertex_output.wgsl)
export as VertexData for shaders.
- Created
[`material_ui`](https://github.com/MarkusTheOrt/bevy/blob/ui_material/crates/bevy_ui/src/render/ui_material.wgsl)
shader as default for both Vertex and Fragment shaders.

---------

Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
Co-authored-by: François <mockersf@gmail.com>

support file operations in single threaded context (bevyengine#10312)

- Fixes bevyengine#10209
- Assets should work in single threaded

- In single threaded mode, don't use `async_fs` but fallback on
`std::fs` with a thin layer to mimic the async API
- file `file_asset.rs` is the async imps from `mod.rs`
- file `sync_file_asset.rs` is the same with `async_fs` APIs replaced by
`std::fs`
- which module is used depends on the `multi-threaded` feature

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>

Fix gizmo crash when prepass enabled (bevyengine#10360)

- Fix gizmo crash when prepass enabled

- Add the prepass to the view key

Fixes: bevyengine#10347
ameknite pushed a commit to ameknite/bevy that referenced this pull request Nov 6, 2023
…bevyengine#10356)

# Objective

- Adopt bevyengine#10239 to get it in time for the release
- Fix accessibility on macOS and linux

## Solution

- call `on_event` from AcccessKit adapter on winit events

---------

Co-authored-by: Nolan Darilek <nolan@thewordnerd.info>
Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
rdrpenguin04 pushed a commit to rdrpenguin04/bevy that referenced this pull request Jan 9, 2024
…bevyengine#10356)

# Objective

- Adopt bevyengine#10239 to get it in time for the release
- Fix accessibility on macOS and linux

## Solution

- call `on_event` from AcccessKit adapter on winit events

---------

Co-authored-by: Nolan Darilek <nolan@thewordnerd.info>
Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Accessibility A problem that prevents users with disabilities from using Bevy C-Bug An unexpected or incorrect behavior O-Linux Specific to the Linux desktop operating system O-MacOS Specific to the MacOS (Apple) desktop operating system P-High This is particularly urgent, and deserves immediate attention
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants