1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-26 14:49:06 -04:00

Fix: ScrollArea layout jitter with floating bars and zoom levels (#7944)

Fix: ScrollArea layout jitter with floating bars and zoom levels

* Closes #7937 
* Closes #7942 

This PR improves the stability of `ScrollArea` by addressing two layout
issues:

1. **Discrete Layout for Floating Bars:** Fixed content "shaking" in
`floating` mode when a non-zero `allocated_width` is used. By using
discrete visibility (`show_bars`) instead of the animated factor for
space allocation, we ensure the layout remains stable during scrollbar
animations.
2. **Zoom-level Stability:** Introduced a small epsilon (0.1) when
checking if content exceeds the viewport. This prevents scrollbars from
flickering on and off due to floating-point rounding errors at specific
zoom factors (e.g., 1.01 or 0.95).
This commit is contained in:
rustbasic
2026-06-10 16:57:44 +09:00
committed by GitHub
parent 0b920aae42
commit 5012603e03

View File

@@ -753,7 +753,12 @@ impl ScrollArea {
ctx.animate_bool_responsive(id.with("v"), show_bars[1]),
);
let current_bar_use = show_bars_factor.yx() * ui.spacing().scroll.allocated_width();
let scroll_style = ui.spacing().scroll;
let current_bar_use = if scroll_style.floating {
show_bars.to_vec2().yx() * scroll_style.allocated_width()
} else {
show_bars_factor.yx() * scroll_style.allocated_width()
};
let available_outer = ui.available_rect_before_wrap();
@@ -1187,9 +1192,15 @@ impl Prepared {
let outer_rect = Rect::from_min_size(inner_rect.min, inner_rect.size() + current_bar_use);
let limit_rect = if ui.spacing().scroll.floating {
outer_rect
} else {
inner_rect
};
let content_is_too_large = Vec2b::new(
direction_enabled[0] && inner_rect.width() < content_size.x,
direction_enabled[1] && inner_rect.height() < content_size.y,
direction_enabled[0] && (limit_rect.width().ceil() < content_size.x),
direction_enabled[1] && (limit_rect.height().ceil() < content_size.y),
);
let max_offset = content_size - inner_rect.size();