diff --git a/crates/egui/src/containers/frame.rs b/crates/egui/src/containers/frame.rs index 72134dd29..1b28719ec 100644 --- a/crates/egui/src/containers/frame.rs +++ b/crates/egui/src/containers/frame.rs @@ -298,15 +298,22 @@ impl Frame { self } - /// Expand the frame without affecting layout. + /// Handle `stroke` and `expansion` without affecting layout. /// /// This handles `expansion` by subtracting it from the outer margin and adding it to the - /// inner margin. It also corrects for a stroke changing on hover, by subtracting the stroke - /// width from `inner_margin`. + /// inner margin. It also corrects for `stroke`, by subtracting the stroke width from `inner_margin`. + /// + /// Use this when stroke or expansion might change on hover, and you don't want it to cause + /// layout shifts. #[inline] - pub fn expand_in_place(mut self, expansion: f32) -> Self { + pub fn apply_stroke_and_expansion_without_layout_shift( + mut self, + stroke: Stroke, + expansion: f32, + ) -> Self { self.outer_margin = self.outer_margin - Margin::from(expansion); - self.inner_margin = self.inner_margin + Margin::from(expansion - self.stroke.width); + self.inner_margin = self.inner_margin + Margin::from(expansion - stroke.width); + self.stroke = stroke; self } diff --git a/crates/egui/src/theme/default_style.rs b/crates/egui/src/theme/default_style.rs index 5c0f93754..88912f3cb 100644 --- a/crates/egui/src/theme/default_style.rs +++ b/crates/egui/src/theme/default_style.rs @@ -55,13 +55,15 @@ impl StyleProvider for DefaultStyle { let painted_frame = Frame { fill: widget_visuals.weak_bg_fill, - stroke: widget_visuals.bg_stroke, corner_radius: widget_visuals.corner_radius, inner_margin, ..Default::default() } // Ensure changing expansion and stroke don't affect layout: - .expand_in_place(widget_visuals.expansion); + .apply_stroke_and_expansion_without_layout_shift( + widget_visuals.bg_stroke, + widget_visuals.expansion, + ); let has_frame = classes.has_class(&Button::CLASS_FRAME) || (!classes.has_class(&Button::CLASS_NO_FRAME) && style.visuals.button_frame);