Skip to content

Fix linux theme change - #167

Draft
piotrsac wants to merge 10 commits into
mainfrom
piotrsaczawa/voy-138-auto-theme-not-working
Draft

piotrsac wants to merge 10 commits into
mainfrom
piotrsaczawa/voy-138-auto-theme-not-working

Conversation

@piotrsac

Copy link
Copy Markdown
Member

No description provided.

@linear

linear Bot commented Aug 11, 2026

Copy link
Copy Markdown
VOY-138 Auto Theme not working

Voyager theme set: Auto
When changed form Dark to Default on Debian 13 x86_64 Voyager is still dark

Review in Linear

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts the app’s theme synchronization logic in the root layout to better handle OS theme changes on Linux (notably in Tauri), adding a more reliable re-probe flow and fallbacks.

Changes:

  • Introduces autoMode() and refines when OS-driven theme updates should apply vs. when a user-selected theme should be respected.
  • Updates the Tauri onThemeChanged handling to re-read the OS theme via the existing probe instead of trusting the event payload.
  • Adds fallbacks to re-sync theme on media-query changes, focus, and visibility changes (Tauri-only).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread lib/voyager_web/components/layouts/root.html.heex Outdated
@piotrsac
piotrsac marked this pull request as ready for review August 11, 2026 14:39
@piotrsac
piotrsac requested a review from hhubert6 August 11, 2026 14:40
@piotrsac
piotrsac removed the request for review from hhubert6 August 14, 2026 14:12
@piotrsac
piotrsac marked this pull request as draft August 14, 2026 14:16
@piotrsac

Copy link
Copy Markdown
Member Author

@claude review opus

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown

Claude finished @piotrsac's task in 4m 21s —— View job


🦀 Review

Severity: 🔴 blocking · 🟡 should-fix · 🟢 nit

  • 🔴 lib/voyager_web/components/layouts/root.html.heex:44nativeOs is inferred from sessionStorage/__VOYAGER_OS_THEME__, but both can hold a matchMedia-derived value (setOs persists every source, and seed_script falls back to matchMedia when the portal snapshot fails). After one reload in a browser, or on the first paint in Tauri with no working portal, nativeOs is true, the matchMedia change handler returns early, and auto theme stops following the OS. Flip nativeOs only on a value that really came from a native probe.
  • 🟡 rel/app/src-tauri/src/theme.rs:94BASE_200_DARK is rgb(32, 36, 41), but the oklch(23.26% 0.014 253.1) it documents is rgb(25, 30, 36); the native fill is lighter than the page background it's meant to match.

<verdict: 1 blocking, 1 should-fix, 0 nits>
· piotrsaczawa/voy-138-auto-theme-not-working

const hint = window.__VOYAGER_OS_THEME__;
const stored = storedOs();
let osTheme = isTheme(hint) ? hint : isTheme(stored) ? stored : media();
let nativeOs = isTheme(hint) || isTheme(stored);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 blocking: nativeOs is set from values that are not necessarily native. setOs writes every OS theme to sessionStorage — including ones derived from matchMedia — and seed_script always assigns __VOYAGER_OS_THEME__, falling back to matchMedia when the portal snapshot fails. So (a) in a plain browser, one OS theme change writes voyager:os-theme, and after the next reload nativeOs is true, the change listener on line 93 returns early, and auto theme stops following the OS for the rest of the session; (b) in Tauri on a desktop with no working settings portal, the seed hint is matchMedia-derived, nativeOs is true from the first paint and os_theme returns null, so the matchMedia fallback is dead and auto theme never updates — the exact VOY-138 symptom. Only flip nativeOs on a value that actually came from a native probe (e.g. a separate flag set by seed_script when the snapshot succeeded, plus setOsFromNative), and don't infer it from sessionStorage.


/// DaisyUI `--color-base-200` used by `html, body` (`assets/css/app.css`).
/// dark: oklch(23.26% 0.014 253.1); light: oklch(98% 0.003 247.858).
const BASE_200_DARK: tauri::window::Color = tauri::window::Color(32, 36, 41, 255);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 should-fix: BASE_200_DARK doesn't match the token the doc comment above cites. oklch(23.26% 0.014 253.1) converts to rgb(25, 30, 36) (#191E24), not rgb(32, 36, 41) — the light constant checks out, so the dark one is the outlier. The native window fill is then visibly lighter than the page's dark base-200, which is the seam background_color/set_surface exist to remove.

Suggested change
const BASE_200_DARK: tauri::window::Color = tauri::window::Color(32, 36, 41, 255);
const BASE_200_DARK: tauri::window::Color = tauri::window::Color(25, 30, 36, 255);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants