emilk / emilk/egui

Second frame jitter in `Area` despite the forced sizing pass

Open
#8,086 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
30.6k
Forks
2.1k
Avg merge
1d 9h
Merged PRs (30d)
72

Description

**Describe the bug**

There are two layers to this bug: `sizing_pass(false)` is ignored for the very first frame of an area, while jitter still occurs during the second in spite of it.
The jitter appears to be caused by a combination of `ui.horizontal` and `pivot` and seems to be impossible to prevent, to the point it still happens even when fixed size and position are provided.

**To Reproduce**
```
fn main() -> eframe::Result
{
let mut show = false;

eframe::run_ui_native("test", eframe::NativeOptions::default(), move |ctx, _frame|
{
egui::CentralPanel::default().show(ctx, |ui|
{
ui.request_repaint();

let resp = ui.button( if show {"hide"} else {"show"} );
if resp.clicked() {show = !show}

if show
{
// predetermined size and position
let size = Vec2::splat(30.0);
let pos = resp.rect.max + Vec2::splat(100.0);

Area::new(Id::new("test_area"))
.pivot(Align2::RIGHT_BOTTOM) // <- important
.default_size(size)
.fixed_pos(pos)
.sizing_pass(false)
.fade_in(false)
.show(ui, |ui|
{
ui.horizontal(|ui| // <- important
{
ui.add_sized(
size,
Button::new("Hi")
)
});
});
}
});
})
}
```

**Expected behavior**

Either the first frame is a sizing pass and the `Area` is then properly positioned the following frame OR it is immediately shown without delay but with a potential jitter. Even better, perhaps there should be neither delays nor jitter if position and size are predetermined and manually specified.

**Screenshots**

https://github.com/user-attachments/assets/650f7d35-028d-4d1c-acb0-932c327e57b5

A few key facts:
- The app is frame-limited to 2fps to better highlight the issue.
- The vertical jitter happening the first time the "Hi" button is shown is NOT the expected behavior and is what this issue is about.
- The horizontal jitter IS expected however, as it is explicitely used to more clearly illustrate the problem.

Notice how when the "Hi" button appears the 2nd and 3rd times the trigger button is still "show". This is what causes the horizontal shift later as "show" turns to "hide" (expected behavior). We don't see any such thing the first time though, because a sizing pass is presumably being done so the "Hi" button only appears AFTER the trigger button has switched to "hide". Despite the sizing pass happening however, the "Hi" button is still incorrectly placed during its SECOND frame, which kind of defeats the purpose of the sizing pass.

**Desktop:**
- OS: win10
- Version: 0.34.1

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the example with Area, sizing_pass(false), pivot, fixed_pos, and the nested ui.horizontal at 2 fps. Trace the first and second frame layout behavior, then verify that a predetermined size and position no longer produce the unexpected vertical jitter while the documented horizontal shift remains.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.