From 85ad9cac7e764bee3a277945b9065b865b75ec2c Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 19 May 2026 15:43:42 +0200 Subject: [PATCH] Rework `Window` margins and set `clip_rect_margin` to zero (#7725) * Follows https://github.com/emilk/egui/pull/7722 * Part of https://github.com/emilk/egui/issues/5605 * Closes https://github.com/emilk/egui/issues/3385 ## What Sets `clip_rect_margin` to zero, and moves the margin of `Window`s with `ScrollAreas`, so that the scroll bars are now on the very edge of the windows they are in. Windows with a bulit-in scroll area now lets the content go all the way to the edges (left image). However, if you just manually add a `ScrollArea` to a `Window`, you won't get this effect (right image). Screenshot 2026-05-18 at 22 04 01 ## Required * #7803 * #7804 * #7805 * #7806 * https://github.com/emilk/egui/pull/7807 * https://github.com/emilk/egui/pull/7808 --- crates/egui/src/containers/frame.rs | 1 + crates/egui/src/containers/window.rs | 45 ++++++++++++------- crates/egui/src/style.rs | 7 ++- .../egui_demo_app/src/apps/custom3d_glow.rs | 2 +- .../egui_demo_app/src/apps/custom3d_wgpu.rs | 2 +- .../tests/snapshots/easymarkeditor.png | 4 +- .../tests/snapshots/demos/Font Book.png | 4 +- .../tests/snapshots/demos/ID Test.png | 4 +- .../tests/snapshots/demos/Misc Demos.png | 4 +- .../tests/snapshots/demos/Panels.png | 4 +- .../tests/snapshots/demos/Scrolling.png | 4 +- .../tests/snapshots/demos/Table.png | 4 +- .../tests/snapshots/demos/Text Layout.png | 4 +- .../tests/snapshots/demos/Tooltips.png | 4 +- .../snapshots/demos/Window Resize Test.png | 4 +- .../tests/snapshots/test_scroll_initial.png | 4 +- .../tests/snapshots/test_scroll_scrolled.png | 4 +- .../snapshots/text_edit_scroll_0_focus.png | 4 +- .../tests/snapshots/text_edit_scroll_1_5.png | 4 +- 19 files changed, 65 insertions(+), 48 deletions(-) diff --git a/crates/egui/src/containers/frame.rs b/crates/egui/src/containers/frame.rs index 3117f7641..d6f751bc2 100644 --- a/crates/egui/src/containers/frame.rs +++ b/crates/egui/src/containers/frame.rs @@ -192,6 +192,7 @@ impl Frame { Self::new().inner_margin(8).fill(style.visuals.panel_fill) } + /// The default frame for an [`crate::Window`]. pub fn window(style: &Style) -> Self { Self::new() .inner_margin(style.spacing.window_margin) diff --git a/crates/egui/src/containers/window.rs b/crates/egui/src/containers/window.rs index 2c249254f..3e0eb4502 100644 --- a/crates/egui/src/containers/window.rs +++ b/crates/egui/src/containers/window.rs @@ -61,7 +61,7 @@ impl<'a> Window<'a> { .with_stroke(false) .min_size([96.0, 32.0]) .default_size([340.0, 420.0]), // Default outer size of a window (includes frame margins, stroke, and title bar) - scroll: ScrollArea::neither().auto_shrink(false), + scroll: ScrollArea::neither().auto_shrink(false).content_margin(0.0), collapsible: true, default_open: true, with_title_bar: true, @@ -493,6 +493,10 @@ impl Window<'_> { let window_frame = frame.unwrap_or_else(|| Frame::window(&style)); + // We apply the window margin by using the `ScrollArea::content_margin`. + let window_margin = window_frame.inner_margin; + let window_frame = window_frame.inner_margin(0.0); + let is_explicitly_closed = matches!(open, Some(false)); let is_open = !is_explicitly_closed || ctx.memory(|mem| mem.everything_is_visible()); let opacity = ctx.animate_bool_with_easing( @@ -564,7 +568,7 @@ impl Window<'_> { title_ui( ui, title, - window_frame, + window_frame.inner_margin(window_margin), &mut collapsing, collapsible, on_top, @@ -575,9 +579,15 @@ impl Window<'_> { collapsing .show_body_unindented(ui, |ui| { if scroll.is_any_scroll_enabled() { - scroll.show(ui, add_contents).inner + scroll + .content_margin(window_margin) + .show(ui, add_contents) + .inner } else { - add_contents(ui) + crate::Frame::NONE + .inner_margin(window_margin) + .show(ui, add_contents) + .inner } }) .map(|inner| inner.inner) @@ -1179,7 +1189,10 @@ fn title_ui( let mut layout = AtomLayout::new(atoms) .gap(spacing) .fallback_font(TextStyle::Heading) - .wrap_mode(TextWrapMode::Truncate); + .wrap_mode(TextWrapMode::Truncate) + .frame(Frame::NONE.inner_margin(frame.inner_margin)); + + let frame = frame.inner_margin(0); // Only applied to the atoms; done above. if expanded { let min_width = if auto_sized { @@ -1244,18 +1257,18 @@ fn title_ui( collapsing.toggle(&child_ui); } - child_ui.set_clip_rect(Rect::EVERYTHING); - let mut header_frame = frame.shadow(Shadow::NONE); - if active { - header_frame = header_frame.fill(ui.visuals().widgets.open.weak_bg_fill); + { + let mut header_frame = frame.shadow(Shadow::NONE); + if active { + header_frame = header_frame.fill(ui.visuals().widgets.open.weak_bg_fill); + } + if expanded { + header_frame.corner_radius.sw = 0; + header_frame.corner_radius.se = 0; + } + ui.painter() + .set(shape_idx, header_frame.paint(layout_response.rect)); } - if expanded { - header_frame.corner_radius.sw = 0; - header_frame.corner_radius.se = 0; - } - child_ui - .painter() - .set(shape_idx, header_frame.paint(layout_response.rect)); let mut advance_rect = child_ui.min_rect(); diff --git a/crates/egui/src/style.rs b/crates/egui/src/style.rs index c036b387a..4218bee46 100644 --- a/crates/egui/src/style.rs +++ b/crates/egui/src/style.rs @@ -1074,7 +1074,10 @@ pub struct Visuals { /// How the text cursor acts. pub text_cursor: TextCursorStyle, - /// Allow child widgets to be just on the border and still have a stroke with some thickness + /// Allow widgets to paint this much outside the scroll area rect. + /// + /// Legacy. Should not be used anymore. + /// Use [`crate::ScrollArea::content_margin`] instead. pub clip_rect_margin: f32, /// Show a background behind buttons. @@ -1500,7 +1503,7 @@ impl Visuals { text_cursor: Default::default(), - clip_rect_margin: 3.0, // should be at least half the size of the widest frame stroke + max WidgetVisuals::expansion + clip_rect_margin: 0.0, button_frame: true, collapsing_header_frame: false, indent_has_left_vline: true, diff --git a/crates/egui_demo_app/src/apps/custom3d_glow.rs b/crates/egui_demo_app/src/apps/custom3d_glow.rs index c218ca0ba..e07da85d3 100644 --- a/crates/egui_demo_app/src/apps/custom3d_glow.rs +++ b/crates/egui_demo_app/src/apps/custom3d_glow.rs @@ -24,7 +24,7 @@ impl Custom3d { impl crate::DemoApp for Custom3d { fn demo_ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { - // TODO(emilk): Use `ScrollArea::inner_margin` + // TODO(emilk): Use `ScrollArea::content_margin` egui::CentralPanel::default().show_inside(ui, |ui| { egui::ScrollArea::both().auto_shrink(false).show(ui, |ui| { ui.horizontal(|ui| { diff --git a/crates/egui_demo_app/src/apps/custom3d_wgpu.rs b/crates/egui_demo_app/src/apps/custom3d_wgpu.rs index d83f000a4..1cc105e28 100644 --- a/crates/egui_demo_app/src/apps/custom3d_wgpu.rs +++ b/crates/egui_demo_app/src/apps/custom3d_wgpu.rs @@ -102,7 +102,7 @@ impl Custom3d { impl crate::DemoApp for Custom3d { fn demo_ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { - // TODO(emilk): Use `ScrollArea::inner_margin` + // TODO(emilk): Use `ScrollArea::content_margin` egui::CentralPanel::default().show_inside(ui, |ui| { egui::ScrollArea::both().auto_shrink(false).show(ui, |ui| { ui.horizontal(|ui| { diff --git a/crates/egui_demo_app/tests/snapshots/easymarkeditor.png b/crates/egui_demo_app/tests/snapshots/easymarkeditor.png index f8237d940..1d370bccd 100644 --- a/crates/egui_demo_app/tests/snapshots/easymarkeditor.png +++ b/crates/egui_demo_app/tests/snapshots/easymarkeditor.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fa67354cfe4d9cb8774c8de614be5975853a4a817ceaf96c3ec7a968de638d8d -size 169740 +oid sha256:406fa40c9e69e353128ea3dde985148773cd0e148c24096ca55ee0cc1aab0258 +size 168849 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png b/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png index 449c2eac0..bd3cd328c 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:157424625dbb855e116a29a008172f29697a37b03512ef06a2e92e502d5e4128 -size 101816 +oid sha256:73429ec71d1ae05518352f1a99304f55647dac362092c9cd5618f709b9ba0d11 +size 99950 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/ID Test.png b/crates/egui_demo_lib/tests/snapshots/demos/ID Test.png index e9aebce92..cbbec3f61 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/ID Test.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/ID Test.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2027f21fdb132542e01fc592d3150aa876cf2ebb4a4268b8c170ff4f523657f0 -size 114074 +oid sha256:d14571fdd7602ea4924d04725008433e1bb53596d8a279f310ddc6c3231b6d32 +size 114106 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png b/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png index 817eebf8f..af5258575 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e00e1dd95278a003c383f5a3f16d25ee4943073171d862db50cb17e90e421bc -size 60272 +oid sha256:2909f098b5edacefef1b5c4d81982b0c84ebd27f896934f0bef92ceb283bbe79 +size 60288 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Panels.png b/crates/egui_demo_lib/tests/snapshots/demos/Panels.png index 2437ae223..ce06d3e81 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Panels.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Panels.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fc1d270e0171cc055fe99579d3f7ab52c63783c793c59aaf8c82027bf1dd3ab8 -size 216484 +oid sha256:1cd58e9912d1db051c93a9b2ea340f3f6dfe64d38ed54aa1b8292bc6f1bf970c +size 215502 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png b/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png index c9b177a18..004257863 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:10e4658168d6a93779463ebb81520f821cbf6eac59391c60d30f5d40ebdf910d -size 152623 +oid sha256:fc28830c402d3aa861a220cfc600c3ce2d7b8ca77307691b3f844a34f27afd1f +size 151376 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Table.png b/crates/egui_demo_lib/tests/snapshots/demos/Table.png index d64d3fca7..1316fe84e 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Table.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Table.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66f35217b0becce12e251c4e7063c31ac92e080340a0318891771fdff54593db -size 67388 +oid sha256:ca08bb7cd0be0b5a9d10833e5c9b65e889f78a5a8056df69d6b0006c3a228227 +size 66050 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png b/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png index bda94ab51..793f77bdd 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29e23e0e45a6e557e569358c89a34dc768ff0b33b47112f864ae8ed119ac6e6e -size 81119 +oid sha256:121c6d5ba129439d2d747da8e505cfff04a023c28d9a0e3aca324d77de1ef418 +size 79186 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png b/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png index b3447e66a..a3fe390e6 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dde445e82732c45f84acbfa83761348b9b89dd2a4fec500ba5124b0c1e58dd29 -size 63060 +oid sha256:3e44cef45d27ddd64b0d2f6de0b7005846147bce54a9b8b1223ba9a0a02c2416 +size 62830 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Window Resize Test.png b/crates/egui_demo_lib/tests/snapshots/demos/Window Resize Test.png index adc67e7ab..3a448e1dd 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Window Resize Test.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Window Resize Test.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9c8eecaedce2bbcbdc4b7975a349b9f986463f189041c7ad6bed64809f18bcd -size 445367 +oid sha256:90c4ea93f234aded298ddeeb98e2d6a0566f07efcdaf5c990e8a47a6533db516 +size 446483 diff --git a/crates/egui_kittest/tests/snapshots/test_scroll_initial.png b/crates/egui_kittest/tests/snapshots/test_scroll_initial.png index e03db834f..3cc77bc75 100644 --- a/crates/egui_kittest/tests/snapshots/test_scroll_initial.png +++ b/crates/egui_kittest/tests/snapshots/test_scroll_initial.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59939d3347679ff27c1de500a559cdc0e6387f633c86ec7ce51f2a36cd92547b -size 7511 +oid sha256:0267c21c4cbe5601263d046a56596275272fbcf727653131f7780aa51ecf6253 +size 6956 diff --git a/crates/egui_kittest/tests/snapshots/test_scroll_scrolled.png b/crates/egui_kittest/tests/snapshots/test_scroll_scrolled.png index a87f09545..2d40e40ba 100644 --- a/crates/egui_kittest/tests/snapshots/test_scroll_scrolled.png +++ b/crates/egui_kittest/tests/snapshots/test_scroll_scrolled.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:df2578c198b29950254ec62c6cc615a4b1c003e7ae3ea027da22fc868b392c74 -size 8342 +oid sha256:46a498433ede5b71abccb5bbeed5788e4ba80949b96f3371b107bd45d5dee28a +size 7964 diff --git a/tests/egui_tests/tests/snapshots/text_edit_scroll_0_focus.png b/tests/egui_tests/tests/snapshots/text_edit_scroll_0_focus.png index 019154ba6..01076e11f 100644 --- a/tests/egui_tests/tests/snapshots/text_edit_scroll_0_focus.png +++ b/tests/egui_tests/tests/snapshots/text_edit_scroll_0_focus.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6f2a57ad8dbdd121cb181e74d76db68d800aba8fdc980d8de4e962e1e85fe8f6 -size 1803 +oid sha256:4b0af10fca47b33752aed2549528dba6b6e8c4818f2fc2b9de60451afdd30a2b +size 1690 diff --git a/tests/egui_tests/tests/snapshots/text_edit_scroll_1_5.png b/tests/egui_tests/tests/snapshots/text_edit_scroll_1_5.png index 6c1ee1d81..b9e0dea1a 100644 --- a/tests/egui_tests/tests/snapshots/text_edit_scroll_1_5.png +++ b/tests/egui_tests/tests/snapshots/text_edit_scroll_1_5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:43dc457cac18107772dbb7e5773961cf502dd685ce1cb4e94338e6b7daedaa77 -size 1861 +oid sha256:7db4a0f33da131ca69771fef974689680c802187cdd8e835131d70457aca775c +size 1639