Repository: bevyengine/bevy
File: crates/bevy_ui/src/picking_backend.rs (Rust)

Code before:

        // Nodes that are not rendered should not be interactable
        if node
            .inherited_visibility
            .map(|inherited_visibility| inherited_visibility.get())
            != Some(true)
        {
            continue;
        }
        let Some(camera_entity) = node.target_camera.get() else {
            continue;
        };

        // Nodes with Display::None have a (0., 0.) logical rect and can be ignored
        if node.node.size() == Vec2::ZERO {
            continue;
        }

        let pointers_on_this_cam = pointer_pos_by_camera.get(&camera_entity);

        // Find the normalized cursor position relative to the node.
        // (±0., 0.) is the center with the corners at points (±0.5, ±0.5).
        // Coordinates are relative to the entire node, not just the visible region.
        for (pointer_id, cursor_position) in pointers_on_this_cam.iter().flat_map(|h| h.iter()) {
            if node.node.contains_point(*node.transform, *cursor_position)
                && clip_check_recursive(
                    *cursor_position,
                    *node_entity,
                    &clipping_query,
                    &child_of_query,
                )
            {
                hit_nodes
                    .entry((camera_entity, *pointer_id))
                    .or_default()
                    .push((
                        *node_entity,
                        node.transform.inverse().transform_point2(*cursor_position)
                            / node.node.size(),
                    ));
            }
        }
    }

    for ((camera, pointer), hovered) in hit_nodes.iter() {
        // As soon as a node with a `Block` focus policy is detected, the iteration will stop on it
        // because it "captures" the interaction.
        let mut picks = Vec::new();
        let mut depth = 0.0;

        for (hovered_node, position) in hovered {

Review comment (suggestion):
I stumbled here for a moment... I was like: "What does Display::None have to do with this?" until I figured that I should read the sentence in another way:

"Nodes that have a size of 0 - logical rect of (0., 0.) - are actually "Display::None" and thus can be ignored

Code after:
        let Some(camera_entity) = uinode.target_camera.get() else {
            continue;
        };

        let pointers_on_this_cam = pointer_pos_by_camera.get(&camera_entity);

        // Reverse the iterator to traverse the tree from closest nodes to furthest
        for node_entity in uinodes.iter().rev().cloned() {
            let Ok(node) = node_query.get(node_entity) else {
                continue;
            };

            if settings.require_markers && node.pickable.is_none() {
                continue;
            }

            // Nodes that are not rendered should not be interactable
            if node
                .inherited_visibility
                .map(|inherited_visibility| inherited_visibility.get())
                != Some(true)
            {
                continue;
            }

            // Nodes with Display::None have a (0., 0.) logical rect and can be ignored
            if node.node.size() == Vec2::ZERO {
                continue;
            }

            // Find the normalized cursor position relative to the node.
            // (±0., 0.) is the center with the corners at points (±0.5, ±0.5).
            // Coordinates are relative to the entire node, not just the visible region.
            for (pointer_id, cursor_position) in pointers_on_this_cam.iter().flat_map(|h| h.iter())
            {
                if node.node.contains_point(*node.transform, *cursor_position)
                    && clip_check_recursive(
                        *cursor_position,
                        node_entity,
                        &clipping_query,
                        &child_of_query,
                    )
                {
                    hit_nodes
                        .entry((camera_entity, *pointer_id))
                        .or_default()
                        .push((
                            node_entity,
                            node.transform.inverse().transform_point2(*cursor_position)
                                / node.node.size(),
                        ));