From 650ea35c18c53a6ca5772763bbb7102ed3ef5605 Mon Sep 17 00:00:00 2001 From: Kristian Myram Date: Mon, 12 Oct 2026 01:30:55 +0200 Subject: [PATCH] Keep GPU information dialog layout steady --- crates/ui-egui/src/panels/dialogs.rs | 11 ++++++++++- crates/ui-egui/src/panels/forms.rs | 3 ++- crates/ui-egui/tests/ui_settings_info.rs | 20 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/crates/ui-egui/src/panels/dialogs.rs b/crates/ui-egui/src/panels/dialogs.rs index 81fa6bab..71ee85db 100644 --- a/crates/ui-egui/src/panels/dialogs.rs +++ b/crates/ui-egui/src/panels/dialogs.rs @@ -150,6 +150,14 @@ pub fn route_layer_settings(app: &mut EffectcraftApp, id: &str, params: &Value) } pub(crate) fn modal(ctx: &egui::Context, title: &str, size: egui::Vec2, t: &Tokens, body: impl FnOnce(&mut egui::Ui)) { + modal_with_scroll(ctx, title, size, t, false, body); +} + +pub(crate) fn modal_vertical(ctx: &egui::Context, title: &str, size: egui::Vec2, t: &Tokens, body: impl FnOnce(&mut egui::Ui)) { + modal_with_scroll(ctx, title, size, t, true, body); +} + +fn modal_with_scroll(ctx: &egui::Context, title: &str, size: egui::Vec2, t: &Tokens, vertical_only: bool, body: impl FnOnce(&mut egui::Ui)) { let available = (ctx.content_rect().size() - vec2(48.0, 48.0)).max(vec2(120.0, 80.0)); let size = size.min(available); egui::Modal::new(egui::Id::new(("modal", title))) @@ -161,7 +169,8 @@ pub(crate) fn modal(ctx: &egui::Context, title: &str, size: egui::Vec2, t: &Toke // The id stays keyed on the untranslated source, so switching language cannot move it. ui.label(egui::RichText::new(tr(title)).font(Tokens::semibold(15.0)).color(t.tab_text_active)); ui.add_space(10.0); - egui::ScrollArea::both().max_height((available.y - 84.0).max(40.0)).auto_shrink([false, true]).show(ui, body); + let scroll = if vertical_only { egui::ScrollArea::vertical() } else { egui::ScrollArea::both() }; + scroll.max_height((available.y - 84.0).max(40.0)).auto_shrink([false, true]).show(ui, body); }); } diff --git a/crates/ui-egui/src/panels/forms.rs b/crates/ui-egui/src/panels/forms.rs index 039ebb69..1d4fc08e 100644 --- a/crates/ui-egui/src/panels/forms.rs +++ b/crates/ui-egui/src/panels/forms.rs @@ -892,7 +892,8 @@ pub(crate) fn close_info(app: &mut EffectcraftApp) { pub fn show_info(app: &mut EffectcraftApp, ctx: &egui::Context, t: &Tokens) { let (title, body) = app.dialog_state.info.clone(); let mut close = false; - super::dialogs::modal(ctx, &title, vec2(440.0, 160.0), t, |ui| { + // The text wraps within this small dialog; avoid a horizontal scrollbar changing its height. + super::dialogs::modal_vertical(ctx, &title, vec2(440.0, 160.0), t, |ui| { ui.label(tr(&body)); ui.add_space(16.0); ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { diff --git a/crates/ui-egui/tests/ui_settings_info.rs b/crates/ui-egui/tests/ui_settings_info.rs index 64f088fe..d231064b 100644 --- a/crates/ui-egui/tests/ui_settings_info.rs +++ b/crates/ui-egui/tests/ui_settings_info.rs @@ -111,3 +111,23 @@ fn gpu_information_ok_returns_to_settings_and_cancel_restores_preferences() { fn gpu_information_escape_returns_to_settings_and_ok_saves_preferences() { check_info_transaction(true); } + +#[test] +fn gpu_information_dialog_stays_in_place() { + let mut session = Session::default(); + session.prefs.appearance.ui_scale = 125; + session.execute("comp.new", json!({"width":32,"height":32,"duration":2})).unwrap(); + let mut h = Harness::builder().with_size(vec2(1280.0, 720.0)).build_eframe(|_| EffectcraftApp::new(session)); + h.run_steps(4); + let ctx = h.ctx.clone(); + menus::invoke(h.state_mut(), &ctx, "app.settings", json!({"page":"previews"})).unwrap(); + h.run_steps(3); + let button = rect(&h, "settings.button.GPU Information").center(); + click(&mut h, button); + let start = h.get_by_label("GPU Information").rect(); + for _ in 0..20 { + h.step(); + let current = h.get_by_label("GPU Information").rect(); + assert!((current.min - start.min).length() < 1.0, "GPU Information dialog moved"); + } +}