host: a pane's own theme wins over a theme preview

A preview (the Theme Builder's, developer mode's, or one an automation left on through theme_preview)
replaced every site tab's theme, pane themes included, also on reload; "Theme for this pane" then
showed its choice checked while the page kept the preview. Reproduced live: a preview of Windows 98
turned a Paper pane into Windows 98 until the preview ended. Now a pane with its own theme keeps it;
every other tab shows the preview, as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
CRTkafa 2026-10-01 16:51:42 +07:00
parent 4d806b647d
commit ef3a5f6f7a
2 changed files with 26 additions and 9 deletions

View file

@ -314,6 +314,17 @@ impl ThemeScopes {
pub fn for_tab(&self, site: &ThemeSite, global: &ThemeChoice, tab: &str, profile: Option<&str>) -> ThemeChoice {
global.for_theme(site, self.theme_id(site, global, tab, profile))
}
/// What site tab `tab` shows with the Theme Builder's (or developer mode's) `preview` in play: a
/// pane the owner gave a theme of its own keeps it, every other tab shows the preview. A preview
/// replaces the global theme, not a choice made for one pane (a preview left on must not make
/// "Theme for this pane" look broken).
pub fn for_tab_with_preview(&self, site: &ThemeSite, global: &ThemeChoice, preview: Option<&ThemeChoice>, tab: &str, profile: Option<&str>) -> ThemeChoice {
match preview {
Some(preview) if !self.panes.get(tab).is_some_and(|id| global.knows(site, id)) => preview.clone(),
_ => self.for_tab(site, global, tab, profile),
}
}
}
#[cfg(test)]
@ -331,6 +342,17 @@ mod tests {
theme.validate(&SITE).map(|()| theme)
}
#[test]
fn a_preview_replaces_the_global_theme_but_not_a_pane_theme() {
let global = ThemeChoice { preset: "paper".into(), ..ThemeChoice::default_for(&SITE) };
let preview = ThemeChoice { preset: "nord".into(), ..ThemeChoice::default_for(&SITE) };
let scopes = ThemeScopes { panes: [("pane1".to_string(), "night-ink".to_string())].into_iter().collect(), ..ThemeScopes::default() };
assert_eq!(scopes.for_tab_with_preview(&SITE, &global, Some(&preview), "pane1", None).preset, "night-ink");
assert_eq!(scopes.for_tab_with_preview(&SITE, &global, Some(&preview), "other", None).preset, "nord");
assert_eq!(scopes.for_tab_with_preview(&SITE, &global, None, "pane1", None).preset, "night-ink");
assert_eq!(scopes.for_tab_with_preview(&SITE, &global, None, "other", None).preset, "paper");
}
#[test]
fn page_color_follows_the_shown_theme() {
let preset = |id: &str| ThemeChoice { preset: id.into(), ..ThemeChoice::default_for(&SITE) };