Docking: a flyout saved as openPanel at quit is not docked below Properties after the upgrade

This commit is contained in:
aiongg
2026-10-24 20:45:36 +00:00
parent b264b44de3
commit 753f3ba04a
2 changed files with 51 additions and 6 deletions
+10 -6
View File
@@ -988,6 +988,15 @@ pub const MENUS: &[(&str, &[&str])] = &[
pub const WORKSPACES: &[&str] =
&["Advanced", "Book", "Digital Publishing", "Essentials", "Essentials Classic", "Interactive for PDF", "Printing and Proofing", "Typography"];
/// The built-in workspaces that open a panel below the Properties · Pages · Layers group.
pub const WORKSPACE_OPEN_PANELS: &[(&str, &str)] =
&[("Printing and Proofing", "swatches"), ("Interactive for PDF", "buttons"), ("Digital Publishing", "liquid")];
/// The panel the built-in workspace `name` opens below the Properties · Pages · Layers group.
pub fn workspace_open_panel(name: &str) -> Option<&'static str> {
WORKSPACE_OPEN_PANELS.iter().find(|(workspace, _)| *workspace == name).map(|(_, panel)| *panel)
}
/// Essentials Classic's iconic column: InDesign's iconic panel groups, top to bottom.
pub const CLASSIC_GROUPS: &[&[&str]] = &[
&["pages", "layers", "links"],
@@ -1988,12 +1997,7 @@ fn run_ui_inner(app: &mut DesignApp, id: &str, p: &Value) -> Option<Result<Value
app.ui.dock_tab = tab.into();
app.ui.dock_expanded = true;
}
app.ui.open_panel = match name {
"Printing and Proofing" => Some("swatches".into()),
"Interactive for PDF" => Some("buttons".into()),
"Digital Publishing" => Some("liquid".into()),
_ => None,
};
app.ui.open_panel = workspace_open_panel(name).map(str::to_string);
app.ui.workspace = name.to_string();
Ok(Value::Null)
}
+41
View File
@@ -32,6 +32,7 @@ impl UiState {
}
}
let mut ui: UiState = serde_json::from_value(saved)?;
clear_stale_open_panels(&mut ui);
intact &= migrate(&mut ui.docking, &mut ui.floating, &ui.docking_hidden, ui.dock_expanded, ui.icon_groups.as_deref());
for workspace in &mut ui.custom_workspaces {
let SavedWorkspace { docking, floating, docking_hidden, dock_expanded, icon_groups, .. } = workspace;
@@ -41,6 +42,27 @@ impl UiState {
}
}
/// Files from before the canvas joined the panel layout saved the flyout open at quit as
/// `openPanel`, which is the panel a workspace opens below Properties · Pages · Layers. Only a
/// workspace's own panel stays: a built-in workspace's (Printing and Proofing: Swatches), and in a
/// saved workspace one a built-in workspace opens (saving copies it). The current workspace keeps
/// a saved workspace's panel.
fn clear_stale_open_panels(ui: &mut UiState) {
let built_in = |panel: &str| crate::menus::WORKSPACE_OPEN_PANELS.iter().any(|(_, p)| *p == panel);
for workspace in &mut ui.custom_workspaces {
if workspace.open_panel.as_deref().is_some_and(|panel| !built_in(panel)) {
workspace.open_panel = None;
}
}
let own = match ui.custom_workspaces.iter().find(|w| w.name == ui.workspace) {
Some(saved) => saved.open_panel.as_deref(),
None => crate::menus::workspace_open_panel(&ui.workspace),
};
if ui.open_panel.as_deref() != own {
ui.open_panel = None;
}
}
/// Drop docking data this version cannot read. True when nothing was dropped.
fn recover_docking(saved: &mut Value) -> bool {
let Some(fields) = saved.as_object_mut() else { return true };
@@ -206,6 +228,25 @@ mod tests {
assert_eq!(&layout.floating[0].rect[..2], &[100.0, 120.0]);
}
/// An `openPanel` that was the flyout open at quit is not docked below Properties.
#[test]
fn a_flyout_open_at_quit_is_not_docked() {
let ui = load(json!({
"workspace": "Essentials", "dockExpanded": true, "openPanel": "stroke",
"customWorkspaces": [
{"name": "Mine", "dockExpanded": true, "openPanel": "effects"},
{"name": "Proof", "dockExpanded": true, "openPanel": "swatches"},
],
}));
assert_eq!(ui.open_panel, None);
let layout = crate::panel_docking::default_layout(&ui);
assert_eq!(panels(&dock(&layout)[0]), [vec!["properties", "pages", "layers"]], "Stroke stays in its icon group");
assert_eq!(ui.custom_workspaces[0].open_panel, None);
assert_eq!(ui.custom_workspaces[1].open_panel.as_deref(), Some("swatches"), "saved from Printing and Proofing");
let ui = load(json!({"workspace": "Proof", "openPanel": "swatches", "customWorkspaces": [{"name": "Proof", "openPanel": "swatches"}]}));
assert_eq!(ui.open_panel.as_deref(), Some("swatches"), "the saved workspace's own panel");
}
#[test]
fn dock_only_layout_becomes_the_main_column() {
let ui = load(json!({