graphic design tool
git clone https://git.lucas.co/cce-designer.git
fix(network): a second editor hidden behind the network loads closed
Taking the network out of the docks made the next tab in the dock it
fronted come to the front. In a save where the second network editor
waited behind the network, that put a second graph where the network's
plate had been. A second editor waiting behind the network now loads
closed, as it was hidden; one that was in front stays.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CLAUDE.md | 5 ++++-
src/main.rs | 34 ++++++++++++++++++++++++++++++++++
src/project.rs | 16 ++++++++++++++++
3 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index c6282a6..9c02e12 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -2797,7 +2797,10 @@ no menu: the network menu's Plate page went the next day, Detach being the
palette's `detach_circular_window` — and
`set_pane_collapsed` refuses it; the pane-state load takes it out of an
older save's tab lists, the dock it fronted fronting its next tab or
-emptying (`the_params_hud_is_under_the_plates_and_stops_above_the_bottom_ones`
+emptying — except a second editor that waited behind it, which loads
+CLOSED: it was hidden, and fronting it put a second graph where the
+network's plate had been (`a_second_editor_hidden_behind_the_network_loads_closed`;
+the user's own project did exactly that the day the network left the docks) (`the_params_hud_is_under_the_plates_and_stops_above_the_bottom_ones`
loads one). `plate_at` never answers the network. The left dock's right edge
resizes whatever plate is docked there (`on_left_dock_resize_edge`,
`AppDrag::LeftDockResize`, writing `floating_network_layout.2`, which kept
diff --git a/src/main.rs b/src/main.rs
index 397e5f8..3819b28 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1655,6 +1655,40 @@ mod tests {
assert_eq!(state.positions[NETWORK_PANEL2_IDX].2, state.left_dock_width());
}
+ /// An older save docked the network, the second editor sometimes waiting
+ /// behind it as a tab. Both load out of sight: the network in no dock,
+ /// and the second editor CLOSED, since it was hidden — fronting it would
+ /// put a second graph where the network's plate was. A second editor
+ /// that was in front stays where it was.
+ #[test]
+ fn a_second_editor_hidden_behind_the_network_loads_closed() {
+ use crate::app::{Dock, NO_PANE};
+ use crate::slots::{NETWORK_PANEL2_IDX, SPREADSHEET_IDX};
+ let dir = std::env::temp_dir().join(format!("cce-designer-hidden-editor-test-{}", std::process::id()));
+ let _ = fs::remove_dir_all(&dir);
+ let mut a = State::new(false);
+ a.save_to_file(&dir).expect("save");
+ let file = dir.join("state.json");
+ let load_with = |tabs: serde_json::Value| {
+ let mut json: serde_json::Value = serde_json::from_str(&fs::read_to_string(&file).unwrap()).unwrap();
+ json["view_state"]["dock_tabs"] = tabs;
+ fs::write(&file, serde_json::to_string(&json).unwrap()).unwrap();
+ let mut b = State::new(false);
+ b.load_from_file(&dir).expect("load");
+ b
+ };
+
+ let b = load_with(serde_json::json!([["network", "network2"], [], ["spreadsheet"]]));
+ assert_eq!(b.tab_dock_of_pane(NETWORK_PANEL2_IDX), None, "the hidden editor loads closed");
+ assert_eq!(b.pane_in_dock(Dock::Left), NO_PANE);
+ assert_eq!(b.pane_in_dock(Dock::Bottom), SPREADSHEET_IDX);
+
+ let b = load_with(serde_json::json!([["network2", "network"], [], ["spreadsheet"]]));
+ assert_eq!(b.pane_in_dock(Dock::Left), NETWORK_PANEL2_IDX, "a fronted editor stays");
+
+ let _ = fs::remove_dir_all(&dir);
+ }
+
/// Move To Own Plate is offered only on a dock holding more than one
/// tab. With neither the params pane nor the network in the docks, the
/// two tab candidates share three docks, so a dock holding both always
diff --git a/src/project.rs b/src/project.rs
index a63e67d..32c56af 100644
--- a/src/project.rs
+++ b/src/project.rs
@@ -380,6 +380,22 @@ impl State {
// taken out — a dock one fronted fronts its next tab, or is
// empty.
let undocked = |s: usize| s == crate::slots::PARAM_IDX || s == crate::slots::NETWORK_PANEL_IDX;
+ // A dock the network FRONTED showed the network alone: what
+ // waited behind it was hidden. The second editor waiting there
+ // is closed, not brought to the front where the network's plate
+ // was — it would appear as a second graph in the old dock's
+ // place, which is what a save of 2026-10-06 did on 2026-10-07.
+ // (The spreadsheet cannot be closed, and fronts.)
+ let resolved: Vec<Vec<usize>> = resolved
+ .into_iter()
+ .map(|tabs| {
+ if tabs.first() == Some(&crate::slots::NETWORK_PANEL_IDX) {
+ tabs.into_iter().filter(|&s| s != n2).collect()
+ } else {
+ tabs
+ }
+ })
+ .collect();
let resolved: Vec<Vec<usize>> = resolved
.into_iter()
.map(|tabs| tabs.into_iter().filter(|&s| !undocked(s)).collect())