From af4d1f54a72c265e392f983c936a1c3f7b61e7b0 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sat, 31 Oct 2026 08:45:28 +0000 Subject: [PATCH 1/2] Keep unequal margins when merging full settings with linkMargins on Found while testing crates/slideshow/src/settings.rs:233 and :267 (merged) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/slideshow/src/settings.rs | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/crates/slideshow/src/settings.rs b/crates/slideshow/src/settings.rs index fd3b327ef1..c17c2bba6c 100644 --- a/crates/slideshow/src/settings.rs +++ b/crates/slideshow/src/settings.rs @@ -218,22 +218,35 @@ impl SlideSettings { /// These settings with the keys `p` names changed (the others kept), validated and clamped. /// A wrong type, an unknown key or a non-finite number is an error, and nothing changes. - /// With `linkMargins` on (already, or set in `p`), a margin given sets all four; `margins` + /// With `linkMargins` on (already, or set in `p`), a margin given sets all four (unless all four are given); `margins` /// sets all four in any case. pub fn merged(&self, p: &Value) -> Result { let Some(obj) = p.as_object() else { return Err("parameters must be an object".into()) }; let mut s = self.clone(); let mut margin: Option = None; + let mut margin_keys = 0; for (k, v) in obj { match k.as_str() { "margins" => { let m = number(k, v)?; (s.margin_left, s.margin_right, s.margin_top, s.margin_bottom) = (m, m, m, m); } - "marginLeft" => s.margin_left = *margin.insert(number(k, v)?), - "marginRight" => s.margin_right = *margin.insert(number(k, v)?), - "marginTop" => s.margin_top = *margin.insert(number(k, v)?), - "marginBottom" => s.margin_bottom = *margin.insert(number(k, v)?), + "marginLeft" => { + s.margin_left = *margin.insert(number(k, v)?); + margin_keys += 1; + } + "marginRight" => { + s.margin_right = *margin.insert(number(k, v)?); + margin_keys += 1; + } + "marginTop" => { + s.margin_top = *margin.insert(number(k, v)?); + margin_keys += 1; + } + "marginBottom" => { + s.margin_bottom = *margin.insert(number(k, v)?); + margin_keys += 1; + } "linkMargins" => s.link_margins = boolean(k, v)?, "showGuides" => s.show_guides = boolean(k, v)?, "aspect" => { @@ -264,7 +277,9 @@ impl SlideSettings { other => return Err(format!("unknown setting `{other}` ({KEYS})")), } } + // all four given: an explicit full state (e.g. `to_json`), kept as is if s.link_margins + && margin_keys < 4 && let Some(m) = margin { (s.margin_left, s.margin_right, s.margin_top, s.margin_bottom) = (m, m, m, m); @@ -319,6 +334,13 @@ pub fn hex(c: [u8; 3]) -> String { mod tests { use super::*; + #[test] + fn merge_restores_unequal_linked_margins() { + let d = SlideSettings::default(); + let st = SlideSettings { link_margins: true, margin_left: 0.1, margin_right: 0.0, margin_top: 0.3, margin_bottom: 0.0, ..d.clone() }; + assert_eq!(d.merged(&st.to_json()).unwrap(), st); + } + #[test] fn merge_validates_links_margins_and_round_trips() { let d = SlideSettings::default(); From 7a7be84e41fced71d1b75c036cb4dbca8b11f2a3 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Mon, 2 Nov 2026 03:10:14 +0000 Subject: [PATCH 2/2] test: pin three linked margin keys boundary and wrap merged doc comment Co-Authored-By: Claude Sonnet 5.5 --- crates/slideshow/src/settings.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/slideshow/src/settings.rs b/crates/slideshow/src/settings.rs index c17c2bba6c..488819e77c 100644 --- a/crates/slideshow/src/settings.rs +++ b/crates/slideshow/src/settings.rs @@ -218,8 +218,8 @@ impl SlideSettings { /// These settings with the keys `p` names changed (the others kept), validated and clamped. /// A wrong type, an unknown key or a non-finite number is an error, and nothing changes. - /// With `linkMargins` on (already, or set in `p`), a margin given sets all four (unless all four are given); `margins` - /// sets all four in any case. + /// With `linkMargins` on (already, or set in `p`), a margin given sets all four (unless all four are given); + /// `margins` sets all four in any case. pub fn merged(&self, p: &Value) -> Result { let Some(obj) = p.as_object() else { return Err("parameters must be an object".into()) }; let mut s = self.clone(); @@ -341,6 +341,14 @@ mod tests { assert_eq!(d.merged(&st.to_json()).unwrap(), st); } + #[test] + fn merge_copies_last_of_three_linked_margins() { + let d = SlideSettings::default(); + // keys are visited in key order (bottom, left, top): the last one, `marginTop`, wins + let s = d.merged(&json!({"marginLeft": 0.1, "marginTop": 0.3, "marginBottom": 0.2})).unwrap(); + assert_eq!((s.margin_left, s.margin_right, s.margin_top, s.margin_bottom), (0.3, 0.3, 0.3, 0.3)); + } + #[test] fn merge_validates_links_margins_and_round_trips() { let d = SlideSettings::default();