refactor(ui): remove dead OS-window machinery after Plan B

With every dialog now an in-canvas modal, the per-dialog
`*_window: Option<window::Id>` 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 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-17 00:09:04 +03:00
commit 3dd1276b6a
2 changed files with 4 additions and 194 deletions

View file

@ -277,33 +277,18 @@ pub(super) struct OpenCADStudio {
/// Last point committed by a drawing command — used as ortho/polar base.
last_point: Option<glam::Vec3>,
/// OS window Id for the floating Layer Properties Manager (None when closed).
layer_window: Option<window::Id>,
/// OS window Id of the primary application window.
main_window: Option<window::Id>,
// ── Floating panel windows ────────────────────────────────────────────
page_setup_window: Option<window::Id>,
textstyle_window: Option<window::Id>,
tablestyle_window: Option<window::Id>,
mlstyle_window: Option<window::Id>,
mleaderstyle_window: Option<window::Id>,
layout_manager_window: Option<window::Id>,
plotstyle_window: Option<window::Id>,
dimstyle_window: Option<window::Id>,
/// Standalone "Select Color" palette window + the field it targets.
color_pick_window: Option<window::Id>,
color_pick_target: Option<ColorPickTarget>,
shortcuts_window: Option<window::Id>,
about_window: Option<window::Id>,
/// The open in-canvas modal dialog, if any (Plan B: shared overlay instead
/// of OS windows).
active_modal: Option<ModalKind>,
plugin_manager_window: Option<window::Id>,
/// New-release notification window — opened on startup when the
/// GitHub releases API reports a newer version than this build.
update_notice_window: Option<window::Id>,
/// First-launch "make Open CAD Studio the default for .dwg/.dxf?" prompt
/// window. Shown once, gated on `default_assoc_prompted`.
assoc_prompt_window: Option<window::Id>,
/// 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<Instant>,
/// Screen position of the previous viewport left-click release.
last_vp_click_pos: Option<Point>,
// page_setup_open: moved to page_setup_window: Option<window::Id>
/// 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<PendingClose>,
/// OS window for the unsaved-changes confirmation dialog.
unsaved_dialog_window: Option<window::Id>,
// ── Custom Save-As dialog ─────────────────────────────────────────────
/// OS window for the custom Save As dialog.
save_dialog_window: Option<window::Id>,
/// 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();

View file

@ -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<Message> {
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() {