fix: Keep the window draggable while a design opens (#643)

The loading box was a full-window modal whose backdrop covered the custom title bar. It is now a light overlay under the title bar, so dragging, snapping, resizing and the window buttons keep working during open, import and recovery. The timeline rebuild shows feature N of M, and Cancel or Esc stops it at the next feature (solidcraft_doc::progress). Recovery restore now runs off the window thread too. A control or MCP doc.open or import is answered once the file is in and doesn't block frames; edits sent meanwhile wait their turn. The web build still opens in place.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
bherbruckandClaude Opus 5.5 authored and GitHub committed 2026-10-13 06:59:20 -04:00
1 parent 8be0f64f5a
commit 392fae1af4
11 files changed
+734 -125

No files matched your search

+9 -4
View File
@@ -128,9 +128,12 @@ fn report_rect(bar: Rect, captions: f32, tabs_start: f32) -> (Rect, bool) {
(Rect::from_min_size(pos2(right - width, bar.top() + 4.0), vec2(width, 26.0)), labeled)
}
/// The application bar's height: the window's title bar on desktop builds.
pub const APP_BAR_HEIGHT: f32 = 34.0;
pub fn app_bar(app: &mut SolveApp, ui: &mut egui::Ui) {
let t = Tokens::get();
egui::Panel::top("sc_appbar").exact_size(34.0).show_separator_line(false).frame(egui::Frame::NONE.fill(t.app_bar)).show(ui, |ui| {
egui::Panel::top("sc_appbar").exact_size(APP_BAR_HEIGHT).show_separator_line(false).frame(egui::Frame::NONE.fill(t.app_bar)).show(ui, |ui| {
let r = ui.max_rect();
// The bar is the window's title bar: its empty space moves the window.
if app.custom_titlebar || app.integrated_titlebar {
@@ -211,9 +214,11 @@ pub fn app_bar(app: &mut SolveApp, ui: &mut egui::Ui) {
let clicked = resp.on_hover_text(tip).clicked();
enabled && clicked
};
let file = click(ui, "folder", app.tr("ui.file"), true);
// While a file loads the design waits: no menus or commands from the bar.
let idle = !app.file_load.busy();
let file = click(ui, "folder", app.tr("ui.file"), idle);
// Save, Undo and Redo act on the design, which Home hides.
let shown = design_shown(app);
let shown = design_shown(app) && idle;
let tip = |id: &str, key: &str| {
let label = app.tr(id);
if shown { format!("{label} ({key})") } else { crate::i18n::format("ui.needs_design", &[("command", label)]) }
@@ -228,7 +233,7 @@ pub fn app_bar(app: &mut SolveApp, ui: &mut egui::Ui) {
if click(ui, "redo", &redo_tip, shown) {
let _ = app.run("edit.redo", json!({}));
}
if click(ui, "home", app.tr("ui.home"), true) {
if click(ui, "home", app.tr("ui.home"), idle) {
let rev = app.session.revision;
app.home.show(rev);
}