bevy/crates/bevy_ui/src
Jannik Obermann 83afcb5a2b
Fix ui picking outside the viewport (#19744)
# Objective

Fixes #19692 

## Solution

- Skip pointers outside the viewport.

## Testing

Tested with the following example:

<details>
<summary>Click to expand code</summary>

```rust
use bevy::{
    prelude::*, render:📷:Viewport, window::SystemCursorIcon, winit::cursor::CursorIcon,
};

fn main() -> AppExit {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .insert_resource(ClearColor(Color::BLACK))
        .run()
}

fn setup(mut commands: Commands, window: Single<&Window>) {
    //
    commands.spawn((
        Camera2d,
        Camera {
            clear_color: ClearColorConfig::Custom(Color::WHITE),
            viewport: Some(Viewport {
                physical_position: UVec2::new(
                    window.physical_width() / 4,
                    window.physical_height() / 4,
                ),
                physical_size: UVec2::new(
                    window.physical_width() / 2,
                    window.physical_height() / 2,
                ),
                ..default()
            }),
            ..default()
        },
    ));

    commands
        .spawn((
            Node {
                top: Val::Px(100.0),
                left: Val::Px(100.0),
                width: Val::Px(200.0),
                height: Val::Px(200.0),
                ..default()
            },
            BackgroundColor(Color::srgb(1.0, 0.0, 0.0)),
        ))
        .observe(|trigger: On<Pointer<Drag>>, mut node: Query<&mut Node>| {
            let mut node = node.get_mut(trigger.target()).unwrap();
            node.left = Val::Px(px(node.left) + trigger.delta.x);
            node.top = Val::Px(px(node.top) + trigger.delta.y);
        })
        .observe(
            |_: On<Pointer<DragStart>>,
             window: Single<Entity, With<Window>>,
             mut commands: Commands| {
                commands
                    .entity(*window)
                    .insert(CursorIcon::from(SystemCursorIcon::Grabbing));
            },
        )
        .observe(
            |_: On<Pointer<DragEnd>>,
             window: Single<Entity, With<Window>>,
             mut commands: Commands| {
                commands.entity(*window).remove::<CursorIcon>();
            },
        );
}

fn px(val: Val) -> f32 {
    match val {
        Val::Px(px) => px,
        _ => 0.0,
    }
}
```
</details>

## Additional information

This is at least also broken on the sprite picking backend. I guess the
fix for other backends are also trivial if this is correct.
(Sprite picking: #19747)
2025-06-30 22:46:56 +00:00
..
experimental Switch ChildOf back to tuple struct (#18672) 2025-04-02 00:10:10 +00:00
layout Component lifecycle reorganization and documentation (#19543) 2025-06-10 00:59:16 +00:00
render Move TextShadow to text widget module (#19579) 2025-06-29 17:37:04 +00:00
widget Move TextShadow to text widget module (#19579) 2025-06-29 17:37:04 +00:00
accessibility.rs Specialized UI transform (#16615) 2025-06-09 19:05:49 +00:00
focus.rs bevy_ui compilation (#19858) 2025-06-29 17:12:11 +00:00
geometry.rs Rename Position to UiPosition in bevy_ui (#19422) 2025-05-29 14:52:44 +00:00
gradients.rs Color interpolation in OKLab, OKLCH spaces for UI gradients (#19330) 2025-06-21 15:06:35 +00:00
interaction_states.rs Core Checkbox (#19665) 2025-06-20 16:37:18 +00:00
lib.rs Move TextShadow to text widget module (#19579) 2025-06-29 17:37:04 +00:00
measurement.rs Use CosmicFontSystem in public bevy_text APIs and remove cosmic_text re-export (#16063) 2024-10-23 20:05:28 +00:00
picking_backend.rs Fix ui picking outside the viewport (#19744) 2025-06-30 22:46:56 +00:00
stack.rs Rename bevy_platform_support to bevy_platform (#18813) 2025-04-11 23:13:28 +00:00
ui_material.rs Type erased materials (#19667) 2025-06-27 22:57:24 +00:00
ui_node.rs Move TextShadow to text widget module (#19579) 2025-06-29 17:37:04 +00:00
ui_transform.rs Specialized UI transform (#16615) 2025-06-09 19:05:49 +00:00
update.rs Opt-out for UI clipping (#19826) 2025-06-27 17:17:09 +00:00