diff --git a/crates/bevy_winit/src/accessibility.rs b/crates/bevy_winit/src/accessibility.rs index cd5a573ae9..309d4fd9cc 100644 --- a/crates/bevy_winit/src/accessibility.rs +++ b/crates/bevy_winit/src/accessibility.rs @@ -86,55 +86,93 @@ fn update_accessibility_nodes( )>, node_entities: Query>, ) { - if let Ok((primary_window_id, primary_window)) = primary_window.get_single() { - if let Some(adapter) = adapters.get(&primary_window_id) { - let should_run = focus.is_changed() || !nodes.is_empty(); - if should_run { - adapter.update_if_active(|| { - let mut to_update = vec![]; - let mut name = None; - if primary_window.focused { - let title = primary_window.title.clone(); - name = Some(title.into_boxed_str()); - } - let focus_id = (*focus).unwrap_or_else(|| primary_window_id).to_bits(); - let mut root_children = vec![]; - for (entity, node, children, parent) in &nodes { - let mut node = (**node).clone(); - if let Some(parent) = parent { - if !node_entities.contains(**parent) { - root_children.push(NodeId(entity.to_bits())); - } - } else { - root_children.push(NodeId(entity.to_bits())); - } - if let Some(children) = children { - for child in children { - if node_entities.contains(*child) { - node.push_child(NodeId(child.to_bits())); - } - } - } - to_update.push(( - NodeId(entity.to_bits()), - node.build(&mut NodeClassSet::lock_global()), - )); - } - let mut root = NodeBuilder::new(Role::Window); - if let Some(name) = name { - root.set_name(name); - } - root.set_children(root_children); - let root = root.build(&mut NodeClassSet::lock_global()); - let window_update = (NodeId(primary_window_id.to_bits()), root); - to_update.insert(0, window_update); - TreeUpdate { - nodes: to_update, - tree: None, - focus: NodeId(focus_id), - } - }); - } + let Ok((primary_window_id, primary_window)) = primary_window.get_single() else { + return; + }; + let Some(adapter) = adapters.get(&primary_window_id) else { + return; + }; + if focus.is_changed() || !nodes.is_empty() { + adapter.update_if_active(|| { + update_adapter( + nodes, + node_entities, + primary_window, + primary_window_id, + focus, + ) + }); + } +} + +fn update_adapter( + nodes: Query<( + Entity, + &AccessibilityNode, + Option<&Children>, + Option<&Parent>, + )>, + node_entities: Query>, + primary_window: &Window, + primary_window_id: Entity, + focus: Res, +) -> TreeUpdate { + let mut to_update = vec![]; + let mut window_children = vec![]; + for (entity, node, children, parent) in &nodes { + let mut node = (**node).clone(); + queue_node_for_update(entity, parent, &node_entities, &mut window_children); + add_children_nodes(children, &node_entities, &mut node); + let node_id = NodeId(entity.to_bits()); + let node = node.build(&mut NodeClassSet::lock_global()); + to_update.push((node_id, node)); + } + let mut window_node = NodeBuilder::new(Role::Window); + if primary_window.focused { + let title = primary_window.title.clone(); + window_node.set_name(title.into_boxed_str()); + } + window_node.set_children(window_children); + let window_node = window_node.build(&mut NodeClassSet::lock_global()); + let node_id = NodeId(primary_window_id.to_bits()); + let window_update = (node_id, window_node); + to_update.insert(0, window_update); + TreeUpdate { + nodes: to_update, + tree: None, + focus: NodeId(focus.unwrap_or(primary_window_id).to_bits()), + } +} + +#[inline] +fn queue_node_for_update( + node_entity: Entity, + parent: Option<&Parent>, + node_entities: &Query>, + window_children: &mut Vec, +) { + let should_push = if let Some(parent) = parent { + node_entities.contains(parent.get()) + } else { + true + }; + if should_push { + window_children.push(NodeId(node_entity.to_bits())); + } +} + +#[inline] +fn add_children_nodes( + children: Option<&Children>, + node_entities: &Query>, + node: &mut NodeBuilder, +) { + let Some(children) = children else { + return; + }; + for child in children { + if node_entities.contains(*child) { + node.push_child(NodeId(child.to_bits())); } } }