From 3dd1276b6a5e2bc625d99f78ee9402d7cb286111 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Wed, 17 Jun 2026 00:09:04 +0300 Subject: [PATCH] refactor(ui): remove dead OS-window machinery after Plan B With every dialog now an in-canvas modal, the per-dialog `*_window: Option` fields are never set. Remove all 17 fields and their inits, trim `OsWindowClosed` to just the main window (exit), drop the dialog branches from the window `title` closure, the leftover `gain_focus` guards in the open handlers, and the now-unused `iced::window` import in update.rs. Page-setup apply clears `active_modal` instead of closing a window. No behaviour change; native + web build, 75 tests pass. Co-Authored-By: Claude Opus 4.8 --- src/app/mod.rs | 87 +----------------------------------- src/app/update.rs | 111 ++-------------------------------------------- 2 files changed, 4 insertions(+), 194 deletions(-) diff --git a/src/app/mod.rs b/src/app/mod.rs index bd6c9435d..1353d3fc7 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -277,33 +277,18 @@ pub(super) struct OpenCADStudio { /// Last point committed by a drawing command — used as ortho/polar base. last_point: Option, /// OS window Id for the floating Layer Properties Manager (None when closed). - layer_window: Option, /// OS window Id of the primary application window. main_window: Option, // ── Floating panel windows ──────────────────────────────────────────── - page_setup_window: Option, - textstyle_window: Option, - tablestyle_window: Option, - mlstyle_window: Option, - mleaderstyle_window: Option, - layout_manager_window: Option, - plotstyle_window: Option, - dimstyle_window: Option, /// Standalone "Select Color" palette window + the field it targets. - color_pick_window: Option, color_pick_target: Option, - shortcuts_window: Option, - about_window: Option, /// The open in-canvas modal dialog, if any (Plan B: shared overlay instead /// of OS windows). active_modal: Option, - plugin_manager_window: Option, /// New-release notification window — opened on startup when the /// GitHub releases API reports a newer version than this build. - update_notice_window: Option, /// First-launch "make Open CAD Studio the default for .dwg/.dxf?" prompt /// window. Shown once, gated on `default_assoc_prompted`. - assoc_prompt_window: Option, /// Whether the one-time default-association prompt has already been shown. /// Persisted via [`settings::UserSettings`] so it survives restarts. default_assoc_prompted: bool, @@ -334,7 +319,6 @@ pub(super) struct OpenCADStudio { last_vp_click_time: Option, /// Screen position of the previous viewport left-click release. last_vp_click_pos: Option, - // page_setup_open: moved to page_setup_window: Option /// Editable paper width buffer for the Page Setup panel (string while typing). page_setup_w: String, /// Editable paper height buffer for the Page Setup panel (string while typing). @@ -462,11 +446,9 @@ pub(super) struct OpenCADStudio { /// Set when the user tries to close a tab or quit while there are unsaved changes. pending_close: Option, /// OS window for the unsaved-changes confirmation dialog. - unsaved_dialog_window: Option, // ── Custom Save-As dialog ───────────────────────────────────────────── /// OS window for the custom Save As dialog. - save_dialog_window: Option, /// Currently selected format string, e.g. "DWG 2013". save_dialog_format: String, /// Editable filename (without path), e.g. "drawing.dwg". @@ -1429,24 +1411,9 @@ impl OpenCADStudio { show_file_tabs: true, show_layout_tabs: true, last_point: None, - layer_window: None, main_window: None, - page_setup_window: None, - textstyle_window: None, - tablestyle_window: None, - mlstyle_window: None, - mleaderstyle_window: None, - layout_manager_window: None, - plotstyle_window: None, - dimstyle_window: None, - color_pick_window: None, color_pick_target: None, - shortcuts_window: None, - about_window: None, active_modal: None, - plugin_manager_window: None, - update_notice_window: None, - assoc_prompt_window: None, default_assoc_prompted: false, update_notice_version: None, update_notice_body: None, @@ -1469,8 +1436,6 @@ impl OpenCADStudio { page_setup_scale: "Fit".to_string(), opening: None, pending_close: None, - unsaved_dialog_window: None, - save_dialog_window: None, save_dialog_format: "DWG 2018".to_string(), save_dialog_filename: "drawing.dwg".to_string(), save_dialog_folder: std::env::var("HOME") @@ -1722,57 +1687,7 @@ pub fn run() -> iced::Result { ) .subscription(OpenCADStudio::subscription) .title(|state: &OpenCADStudio, window_id: window::Id| { - if Some(window_id) == state.layer_window { - return "Layer Properties Manager".into(); - } - if Some(window_id) == state.color_pick_window { - return "Select Color".into(); - } - if Some(window_id) == state.page_setup_window { - return "Page Setup".into(); - } - if Some(window_id) == state.textstyle_window { - return "Text Style".into(); - } - if Some(window_id) == state.tablestyle_window { - return "Table Style".into(); - } - if Some(window_id) == state.mlstyle_window { - return "Multiline Style".into(); - } - if Some(window_id) == state.mleaderstyle_window { - return "Multileader Style".into(); - } - if Some(window_id) == state.layout_manager_window { - return "Layout Manager".into(); - } - if Some(window_id) == state.plotstyle_window { - return "Plot Style Table Editor".into(); - } - if Some(window_id) == state.dimstyle_window { - return "Dimension Style Manager".into(); - } - if Some(window_id) == state.shortcuts_window { - return "Keyboard Shortcuts".into(); - } - if Some(window_id) == state.about_window { - return "About Open CAD Studio".into(); - } - if Some(window_id) == state.plugin_manager_window { - return "Plugin Manager".into(); - } - if Some(window_id) == state.update_notice_window { - return "Update Available".into(); - } - if Some(window_id) == state.assoc_prompt_window { - return "Set Default Application".into(); - } - if Some(window_id) == state.unsaved_dialog_window { - return "Unsaved Changes".into(); - } - if Some(window_id) == state.save_dialog_window { - return "Save As".into(); - } + let _ = window_id; // all dialogs are in-canvas modals now if let Some(tab) = state.tabs.get(state.active_tab) { let dot = if tab.dirty { "● " } else { "" }; let name = tab.tab_display_name(); diff --git a/src/app/update.rs b/src/app/update.rs index 75efe3bd0..6323deb3a 100644 --- a/src/app/update.rs +++ b/src/app/update.rs @@ -13,7 +13,6 @@ use crate::ui::PropertiesPanel; use acadrust::types::Color as AcadColor; use acadrust::{EntityType as AcadEntityType, Handle}; use iced::time::Instant; -use iced::window; use iced::{mouse, Task}; const VIEWCUBE_HIT_SIZE: f32 = VIEWCUBE_DRAW_PX; @@ -1665,101 +1664,11 @@ impl OpenCADStudio { } Message::OsWindowClosed(id) => { + // Only the main window exists now; all dialogs are in-canvas + // modals (Plan B). Closing it exits. if self.main_window == Some(id) { - // Main window was explicitly closed by us — exit. return iced::exit(); } - if self.unsaved_dialog_window == Some(id) { - // User closed the dialog window via OS ✕ — treat as Cancel. - self.unsaved_dialog_window = None; - self.pending_close = None; - return Task::none(); - } - if self.save_dialog_window == Some(id) { - self.save_dialog_window = None; - return Task::none(); - } - // A style manager closed via OS ✕ counts as Cancel: discard any - // staged (not-yet-applied) changes by restoring the snapshot - // taken when it opened. - if self.textstyle_window == Some(id) - || self.dimstyle_window == Some(id) - || self.tablestyle_window == Some(id) - || self.mleaderstyle_window == Some(id) - || self.mlstyle_window == Some(id) - { - self.style_stage_discard(); - } - // Each popup window that's launched from a ribbon tool - // also turns that tool blue (`activate_tool`); when the - // window closes, the matching tool needs to be cleared - // or the button stays highlighted with no window behind - // it. The mapped IDs are the ribbon `ToolDef.id`s that - // dispatched the open in the first place. See #40. - if self.layer_window == Some(id) { - self.layer_window = None; - self.ribbon.deactivate_tool_if("LAYERS"); - } - if self.page_setup_window == Some(id) { - self.page_setup_window = None; - self.ribbon.deactivate_tool_if("PAGESETUP"); - } - if self.textstyle_window == Some(id) { - self.textstyle_window = None; - self.ribbon.deactivate_tool_if("STYLE"); - self.ribbon.deactivate_tool_if("TEXTSTYLE"); - } - if self.tablestyle_window == Some(id) { - self.tablestyle_window = None; - self.ribbon.deactivate_tool_if("TABLESTYLE"); - } - if self.mlstyle_window == Some(id) { - self.mlstyle_window = None; - self.ribbon.deactivate_tool_if("MLSTYLE"); - } - if self.mleaderstyle_window == Some(id) { - self.mleaderstyle_window = None; - self.ribbon.deactivate_tool_if("MLEADERSTYLE"); - } - if self.layout_manager_window == Some(id) { - self.layout_manager_window = None; - self.ribbon.deactivate_tool_if("LAYOUTMANAGER"); - self.ribbon.deactivate_tool_if("LAYOUTPANEL"); - } - if self.plotstyle_window == Some(id) { - self.plotstyle_window = None; - self.ribbon.deactivate_tool_if("PLOTSTYLE"); - self.ribbon.deactivate_tool_if("STYLESMANAGER"); - } - if self.dimstyle_window == Some(id) { - self.dimstyle_window = None; - self.ribbon.deactivate_tool_if("DIMSTYLE"); - } - if self.color_pick_window == Some(id) { - self.color_pick_window = None; - self.color_pick_target = None; - } - if self.shortcuts_window == Some(id) { - self.shortcuts_window = None; - self.ribbon.deactivate_tool_if("SHORTCUTS"); - self.ribbon.deactivate_tool_if("KEYBOARD"); - } - if self.about_window == Some(id) { - self.about_window = None; - self.ribbon.deactivate_tool_if("ABOUT"); - } - if self.plugin_manager_window == Some(id) { - self.plugin_manager_window = None; - } - if self.update_notice_window == Some(id) { - self.update_notice_window = None; - } - // Closing the default-association prompt via the window chrome - // counts as answering it — never nag again. - if self.assoc_prompt_window == Some(id) { - self.assoc_prompt_window = None; - self.mark_assoc_prompted(); - } Task::none() } @@ -5960,9 +5869,7 @@ impl OpenCADStudio { center={center} rot={rotation}°" )); } - if let Some(id) = self.page_setup_window.take() { - return window::close(id); - } + self.active_modal = None; Task::none() } @@ -6522,9 +6429,6 @@ impl OpenCADStudio { }) .unwrap_or_else(|| "Standard".to_string()); self.load_tablestyle_bufs(i); - if let Some(id) = self.tablestyle_window { - return window::gain_focus(id); - } self.active_modal = Some(super::ModalKind::TableStyle); self.style_stage_begin(); Task::none() @@ -6926,9 +6830,6 @@ impl OpenCADStudio { .unwrap_or_else(|| "Standard".to_string()) }; self.load_mleaderstyle_bufs(i); - if let Some(id) = self.mleaderstyle_window { - return window::gain_focus(id); - } self.active_modal = Some(super::ModalKind::MLeaderStyle); self.style_stage_begin(); Task::none() @@ -7274,9 +7175,6 @@ impl OpenCADStudio { }; self.dimstyle_selected = selected.clone(); self.load_dimstyle_bufs(i); - if let Some(id) = self.dimstyle_window { - return window::gain_focus(id); - } self.active_modal = Some(super::ModalKind::DimStyle); self.style_stage_begin(); Task::none() @@ -8513,9 +8411,6 @@ impl OpenCADStudio { /// Populate edit buffers from the currently selected text style. fn open_save_dialog_window(&mut self, tab_idx: usize) -> Task { - if let Some(id) = self.save_dialog_window { - return window::gain_focus(id); - } // Pre-fill filename and folder from current path or defaults. if let Some(p) = &self.tabs[tab_idx].current_path.clone() { if let Some(name) = p.file_name() {