Skip to content

Fix ui picking outside the viewport #19744

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

jannik4
Copy link
Contributor

@jannik4 jannik4 commented Jun 19, 2025

Objective

Fixes #19692

Solution

  • Skip pointers outside the viewport.

Testing

Tested with the following example:

Click to expand code
use bevy::{
    prelude::*, render::camera::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,
    }
}

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)

@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior A-Picking Pointing at and selecting objects of all sorts labels Jun 19, 2025
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.

This is a reasonable fix. I'd prefer to do this across all of our backends at once though.

@alice-i-cecile alice-i-cecile added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Jun 19, 2025
@jannik4
Copy link
Contributor Author

jannik4 commented Jun 19, 2025

Already created another PR for sprites:)

@jannik4
Copy link
Contributor Author

jannik4 commented Jun 19, 2025

Not sure about the mesh backend, I don't find any code related to viewport there. Not sure if this is implemented on another "level".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Picking Pointing at and selecting objects of all sorts C-Bug An unexpected or incorrect behavior S-Needs-Review Needs reviewer attention (from anyone!) to move forward
Projects
None yet
Development

Successfully merging this pull request may close these issues.

(UI) picking unexpectedly triggers outside the viewport
2 participants