bevy icon indicating copy to clipboard operation
bevy copied to clipboard

UI nodes don't resize when toggling fullscreen

Open benfrankel opened this issue 1 year ago • 3 comments

Bevy version

0.14.0

Relevant system information

Linux with i3wm (tiling window manager).

AdapterInfo { name: "AMD Radeon RX 570 Series (RADV POLARIS10)", vendor: 4098, device: 26591, device_type: DiscreteGpu, driver: "radv", driver_info: "Mesa 24.0.6-arch1.2", backend: Vulkan }

What you did

Toggle fullscreen while looking at my title screen UI.

What went wrong

This is how my UI normally looks:

2024-07-11_1720684551_1215x728

This is how my UI sometimes looks after toggling from fullscreen to windowed:

2024-07-11_1720684545_1215x728

I checked, and the buttons in this case are the same size as they were while in fullscreen.

This issue can happen in reverse as well, with the fullscreen buttons being as small as they were while windowed.

Resizing the window slightly after the bug occurs will snap the buttons back to the correct size.

benfrankel avatar Jul 11 '24 08:07 benfrankel

It seems like the single UI layout update after the window resize isn't enough. You could try a system something like this to force it to reupdate again for few frames after the window resizes:

fn force_ui_reupdate_on_window_resized(
    mut counter: Local<u8>,
    mut window_resized_events: EventReader<WindowResized>,
    mut ui_scale: ResMut<UiScale>,
    mut ui_node_query: Query<(&mut Style, Option<&mut Text>)>,
) {
    if 0 < *counter {
        ui_scale.set_changed();
        for (mut style, maybe_text) in ui_node_query.iter_mut() {
            style.set_changed();
            if let Some(mut text) = maybe_text {
                text.set_changed();
            }
        }
    }   

    *counter = counter.saturating_sub(1);
    if !window_resized_events.is_empty() {
        window_resized_events.clear();
        *counter = 2;
    }
}

I just typed this out quickly, it's not tested but I think it should work. The query might be overkill, maybe it'll correct itself just with setting UiScale to changed the frame directly after the window resize.

ickshonpe avatar Jul 11 '24 10:07 ickshonpe

Duplicate of #14255.

alice-i-cecile avatar Jul 11 '24 13:07 alice-i-cecile

@alice-i-cecile not a duplicate, this is about toggling to fullscreen and #14255 is about resizing the window itself. They seem related though.

UkoeHB avatar Jul 11 '24 17:07 UkoeHB

I'm seeing this bug occasionally in the itch.io release of my jam game as well. This is much more severe than the related bug, because the size difference between windowed and fullscreen makes the UI completely broken instead of "slightly jittery / delayed", and toggling back to windowed -> back to fullscreen -> ... does not fix it for the user.

benfrankel avatar Jul 29 '24 20:07 benfrankel

This appears to be a system ordering bug. I ran the same app 30 times without recompiling and saw the bug 10/30 times. Whenever the bug was present, it happened 100% consistently on every fullscreen toggle.

Also, manually mutating the Style component of a bugged UI node (via inspector) snaps it back to the correct size, but it doesn't fix any of the other bugged nodes' sizes. That's as expected, I suppose.

benfrankel avatar Aug 04 '24 00:08 benfrankel

I suspect that this is a system ordering bug between CameraUpdateSystem and UiSystem::Layout, which both run in PostUpdate with no ordering specified between them. The former contains a system that updates the Camera's viewport size if the window has been resized, while the latter has a system that reads the Camera's viewport size if the window has been resized, and uses that to calculate UI node sizes.

This is probably also causing https://github.com/bevyengine/bevy/issues/14255.

I could test this out but I haven't been able to reproduce the bug in a bevy example yet.

benfrankel avatar Aug 04 '24 02:08 benfrankel

Well. I wasn't able to reproduce the bug in a minimal example with unmodified Bevy 0.14.0, but when I explicitly ordered CameraUpdateSystem after UiSystem::Layout, it triggered the exact buggy behavior I've been seeing -- and when I ordered it before, it didn't cause a crash, which demonstrates that the system sets are ambiguous.

IDK if system order randomization doesn't apply to cargo run --example or if I got supremely unlucky... but that should be enough to prove that that's the cause of the issue, or at least one way it can be caused.

benfrankel avatar Aug 04 '24 05:08 benfrankel

I suspect that this is a system ordering bug between CameraUpdateSystem and UiSystem::Layout, which both run in PostUpdate with no ordering specified between them.

It makes sense to me this would be the issue. Can you open a PR?

UkoeHB avatar Aug 04 '24 06:08 UkoeHB

Opened PR :)

benfrankel avatar Aug 04 '24 06:08 benfrankel