Skip to content

Taffy rounding bug can cause UI nodes to expand each update #8911

@ickshonpe

Description

@ickshonpe

Bevy version

main 910f984

What you did

use bevy::prelude::*;
use bevy::window::WindowResolution;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            primary_window: Some(Window {
                resolution: WindowResolution::new(800., 600.).with_scale_factor_override(1.5),
                ..Default::default()
            }),
            ..Default::default()
        }))
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn(Camera2dBundle::default());
    commands
        .spawn(NodeBundle {
            style: Style {
                width: Val::Percent(100.),
                left: Val::Px(1.),
                ..Default::default()
            },
            ..Default::default()
        })
        .with_children(|builder| {
            builder
                .spawn(NodeBundle {
                    style: Style {
                        width: Val::Px(100.),
                        justify_content: JustifyContent::End,
                        ..Default::default()
                    },
                    background_color: Color::BLACK.into(),
                    ..Default::default()
                })
                .with_children(|builder| {
                    builder.spawn(NodeBundle {
                        style: Style {
                            min_width: Val::Px(200.),
                            ..default()
                        },
                        background_color: Color::RED.with_a(0.5).into(),
                        ..Default::default()
                    });
                });
        });
}

What went wrong

Bevy.App.2023-06-21.09-50-57.mp4

The inner leaf node expands by a physical pixel each time the UI updates.

The problem is with how Taffy rounds the layout coordinates. The rust round function rounds away from zero, so x bounds from -100.5 to 99.5 (width 200) will be rounded to -101 to 100 (width 201), gaining a pixel.

The accumulated error resets after a full update (triggered when the window is resized or the scale factor changes).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-UIGraphical user interfaces, styles, layouts, and widgetsC-BugAn unexpected or incorrect behaviorS-BlockedThis cannot move forward until something else changes

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions