From d9b13ab702b3753ae626a72173a513d99860f12a Mon Sep 17 00:00:00 2001 From: PiMinusMax <121135695+PiMinusMax@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:09:26 +0200 Subject: [PATCH 1/2] fix: Cmd/Ctrl + the + key zooms the canvas, not the whole window On layouts with a dedicated + key (German) or Shift+= (US), Zoom In's Cmd+= arrives as Key::Plus. No shortcut matched it, so egui's built-in keyboard zoom scaled the whole UI, and the UI-scale preference reset it on the next frame. Plus now counts as = for shortcuts, and egui's keyboard zoom is off since the UI scale is a preference. --- crates/ui-egui/src/lib.rs | 3 +++ crates/ui-egui/src/menus.rs | 49 +++++++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index fc7a3e63..56866a5d 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -772,6 +772,9 @@ impl DesignApp { ctx.set_zoom_factor(scale); } if !self.styled { + // The UI scale is a preference (applied above); egui's own Cmd+Plus/Minus/0 would rescale the + // whole window instead of the canvas, only to be reset next frame. + ctx.options_mut(|o| o.zoom_with_keyboard = false); theme::install_fonts(ctx, &self.ui.language); self.fonts_lang = self.ui.language.clone(); self.styled = true; diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index 872cb81d..680f0086 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -2172,10 +2172,12 @@ pub fn shortcuts(app: &mut DesignApp, ctx: &egui::Context) { let all = effective_shortcuts(app); for (id, sc) in &all { let id = id.as_str(); + // On layouts with a dedicated + key (German) or Shift+= (US), Cmd+= arrives as Plus. + let plus_for_equals = key == egui::Key::Plus; if let Some((m, k)) = parse_shortcut(sc) - && k == key + && (k == key || (plus_for_equals && k == egui::Key::Equals)) && m.command == modifiers.command - && m.shift == modifiers.shift + && (m.shift == modifiers.shift || (plus_for_equals && !m.shift)) && m.alt == modifiers.alt && (m.command || m.alt || !typing) && !(id == "edit.clear" && typing) @@ -3055,6 +3057,49 @@ mod tests { assert_eq!(app.session.tool_id(), "rectangleFrame"); } + #[test] + fn cmd_plus_zooms_the_canvas_not_the_window() { + // A German keyboard has its own + key, so Cmd+= arrives as Plus; it must zoom the canvas like + // Cmd+- does, not hand the key to egui's whole-window zoom. + let mut app = crate::DesignApp::new(designcraft_engine::Session::new(), crate::Services::default()); + app.session.execute("file.new", &json!({})).unwrap(); + let ctx = egui::Context::default(); + let frame = |app: &mut crate::DesignApp, events: Vec| { + let input = egui::RawInput { + screen_rect: Some(egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1400.0, 900.0))), + events, + ..Default::default() + }; + let mut out = ctx.run_ui(input, |ui| { + app.logic(&ui.ctx().clone()); + app.ui(ui); + }); + out.textures_delta.clear(); + }; + let key = |k: egui::Key, modifiers: egui::Modifiers| { + vec![ + egui::Event::Key { key: k, physical_key: None, pressed: true, repeat: false, modifiers }, + egui::Event::Key { key: k, physical_key: None, pressed: false, repeat: false, modifiers }, + ] + }; + frame(&mut app, vec![]); + frame(&mut app, vec![]); + let scale = ctx.zoom_factor(); + for (k, m, zooms_in) in [ + (egui::Key::Plus, egui::Modifiers::COMMAND, true), + (egui::Key::Plus, egui::Modifiers::COMMAND | egui::Modifiers::SHIFT, true), + (egui::Key::Equals, egui::Modifiers::COMMAND, true), + (egui::Key::Minus, egui::Modifiers::COMMAND, false), + ] { + let z0 = app.view().unwrap().zoom; + frame(&mut app, key(k, m)); + frame(&mut app, vec![]); + let z = app.view().unwrap().zoom; + assert!(if zooms_in { z > z0 } else { z < z0 }, "{k:?} {m:?}: {z0} -> {z}"); + assert_eq!(ctx.zoom_factor(), scale, "{k:?} {m:?} leaves the UI scale alone"); + } + } + #[test] fn the_quick_apply_shortcut_opens_it_without_running_an_entry() { let mut app = crate::DesignApp::new(designcraft_engine::Session::new(), crate::Services::default()); From 049ff99590d7abf78553e8666c533f8024a59e04 Mon Sep 17 00:00:00 2001 From: PiMinusMax <121135695+PiMinusMax@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:23:33 +0200 Subject: [PATCH 2/2] contributors: add PiMinusMax's display name --- contributors/people.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contributors/people.toml b/contributors/people.toml index 67a8fdf3..827d12ad 100644 --- a/contributors/people.toml +++ b/contributors/people.toml @@ -28,5 +28,8 @@ display_name = "insanityxoff" [people.moppeeer] sync_github_name = true +[people.PiMinusMax] +display_name = "PiMinusMax" + [people.thaynej] real_name = "Jeffrey Thayne"