Second frame jitter in `Area` despite the forced sizing pass
- 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
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