From efc2fc6702c9396295db99fe99de4e772e6c23b7 Mon Sep 17 00:00:00 2001 From: skylar taylor-barrick Date: Fri, 9 Oct 2026 22:35:22 -0600 Subject: [PATCH] UI.7: deserialize hidden locations without default panel IDs --- crates/ui/src/docking/model.rs | 1 + crates/ui/src/docking/tests.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/crates/ui/src/docking/model.rs b/crates/ui/src/docking/model.rs index 7a43aa8e..babb3e2f 100644 --- a/crates/ui/src/docking/model.rs +++ b/crates/ui/src/docking/model.rs @@ -80,6 +80,7 @@ pub enum Placement

{ /// Anchors are stable panel identities rather than mutable tree indices. #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(bound(deserialize = "P: serde::Deserialize<'de>")))] pub struct Location

{ pub floating: Option<[f32; 4]>, pub anchor: Option

, diff --git a/crates/ui/src/docking/tests.rs b/crates/ui/src/docking/tests.rs index 763ab065..68abccab 100644 --- a/crates/ui/src/docking/tests.rs +++ b/crates/ui/src/docking/tests.rs @@ -282,6 +282,23 @@ fn saved_layout_and_hidden_location_round_trip() { assert_eq!(serde_json::from_str::>(&encoded).unwrap(), location); } +#[cfg(feature = "serde")] +#[test] +fn old_hidden_locations_accept_panel_ids_without_a_default_identity() { + #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)] + enum Panel { + Layers, + Brushes, + } + let location: Location = serde_json::from_value(serde_json::json!({ + "floating": null, "anchor": "Layers", "placement": {"Tab": {"before": null}}, + "size": null, "stack": null + })) + .unwrap(); + assert!(location.sibling.is_empty()); + assert_eq!(location.anchor, Some(Panel::Layers)); +} + fn frame(ctx: &Context, layout: &Layout, events: Vec, focused: bool) -> (DockOutput, Vec) { let mut output = DockOutput::default(); let mut ids = Vec::new();