Skip to content

feat: add Windows title bar theme support#136

Open
chengcheng84 wants to merge 2 commits intoerictli:mainfrom
chengcheng84:fix/titlebar
Open

feat: add Windows title bar theme support#136
chengcheng84 wants to merge 2 commits intoerictli:mainfrom
chengcheng84:fix/titlebar

Conversation

@chengcheng84
Copy link
Copy Markdown

@chengcheng84 chengcheng84 commented Apr 6, 2026

Before

2026-04-06.093820.mp4

Now

2026-04-06.093437.mp4

Summary by CodeRabbit

  • New Features
    • Title bar now syncs with your light/dark theme in real time, updating when you switch modes for a more cohesive look.
    • Windows: system title-bar styling is updated to match the selected theme.
    • Non-Windows: no title-bar changes are applied, but theme switching continues to update the app UI.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 655e01c4-60b5-4e3d-888e-71820e94b60d

📥 Commits

Reviewing files that changed from the base of the PR and between 9ea3893 and a57ec54.

📒 Files selected for processing (1)
  • src-tauri/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src-tauri/src/lib.rs

📝 Walkthrough

Walkthrough

Adds a Windows-only title bar theming module and a new Tauri command set_title_bar_theme, and invokes that command from the React theme context to sync window title-bar appearance with the app theme.

Changes

Cohort / File(s) Summary
Backend: Tauri & Windows FFI
src-tauri/src/lib.rs
Added windows_title_bar module (gated on Windows) that uses DwmSetWindowAttribute to set immersive dark mode and caption/border colors. Registered a new Tauri command set_title_bar_theme(app: AppHandle, is_dark: bool) that iterates app.webview_windows() and applies the theme to windows labeled "main" or starting with "preview-".
Frontend: Theme Integration
src/context/ThemeContext.tsx
Imported Tauri invoke and added an effect call to invoke("set_title_bar_theme", { isDark: resolvedTheme === "dark" }) (errors swallowed) so title-bar theme is updated when resolvedTheme changes.

Sequence Diagram

sequenceDiagram
    participant React as React Theme Context
    participant Tauri as Tauri Command Handler
    participant WinAPI as Windows API (DwmSetWindowAttribute)
    participant Window as Window Title Bar

    React->>Tauri: invoke("set_title_bar_theme", {isDark: boolean})
    activate Tauri
    Tauri->>Tauri: enumerate webview windows (labels "main"/"preview-*")
    Tauri->>WinAPI: DwmSetWindowAttribute (set immersive dark + caption colors)
    activate WinAPI
    WinAPI->>Window: apply dark/light and caption/border colors
    deactivate WinAPI
    Tauri-->>React: Ok(())
    deactivate Tauri
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • erictli

Poem

🐰 I hopped from React to native calls,
Dark bars and captions answering my calls.
From theme to title, a gentle gleam,
Windows and Tauri—what a dream! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add Windows title bar theme support' directly and clearly summarizes the main change: adding Windows title bar theme functionality to the application.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src-tauri/src/lib.rs (2)

3892-3903: Preview windows won't receive title bar theme updates.

The command only applies the theme to the "main" window. Preview windows (labeled "preview-*") created via create_preview_window won't have their title bars themed, causing visual inconsistency when editing files outside the notes folder.

Consider iterating over all windows or accepting an optional window label:

🔧 Suggested fix to theme all windows
 #[tauri::command]
 fn set_title_bar_theme(app: AppHandle, is_dark: bool) -> Result<(), String> {
     #[cfg(target_os = "windows")]
     {
-        if let Some(window) = app.get_webview_window("main") {
-            windows_title_bar::apply_title_bar_theme(&window, is_dark);
+        for (_, window) in app.webview_windows() {
+            windows_title_bar::apply_title_bar_theme(&window, is_dark);
         }
     }
     let _ = app;
     let _ = is_dark;
     Ok(())
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/src/lib.rs` around lines 3892 - 3903, The set_title_bar_theme
command currently only themes the "main" window; update it to apply the theme to
all relevant windows (e.g., the "main" window and any preview windows created by
create_preview_window with labels starting with "preview-") by iterating over
app.windows() (or app.hooks/windows API) and calling
windows_title_bar::apply_title_bar_theme(&window, is_dark) for each matching
window label, or alternatively extend set_title_bar_theme to accept an optional
window_label parameter and apply the theme only to that label if provided;
adjust references to set_title_bar_theme and create_preview_window accordingly
so preview windows receive updates too.

3705-3708: Initial title bar theme doesn't respect system preference.

At startup, apply_title_bar_theme is called with is_dark: false, regardless of the actual system theme. This may cause a brief flash of light title bar before the frontend's ThemeContext invokes set_title_bar_theme with the correct resolved theme.

Consider reading the system theme preference here, or deferring this call until after the frontend initializes:

🔧 Suggested fix to respect system preference at startup
 #[cfg(target_os = "windows")]
 {
-    windows_title_bar::apply_title_bar_theme(&main_window, false);
+    // Let the frontend apply the theme after resolving user/system preference
+    // to avoid a brief flash of incorrect title bar color
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/src/lib.rs` around lines 3705 - 3708, The Windows title bar is
forced to light by calling
windows_title_bar::apply_title_bar_theme(&main_window, false) at startup; change
this to respect system preference by querying the system theme and passing the
actual dark/light boolean (or defer the call and let the frontend call
set_title_bar_theme after ThemeContext resolves). Update the #[cfg(target_os =
"windows")] block: replace the hardcoded false with the system theme check (or
remove the call and rely on set_title_bar_theme) so apply_title_bar_theme and
main_window use the correct initial is_dark value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src-tauri/src/lib.rs`:
- Around line 3892-3903: The set_title_bar_theme command currently only themes
the "main" window; update it to apply the theme to all relevant windows (e.g.,
the "main" window and any preview windows created by create_preview_window with
labels starting with "preview-") by iterating over app.windows() (or
app.hooks/windows API) and calling
windows_title_bar::apply_title_bar_theme(&window, is_dark) for each matching
window label, or alternatively extend set_title_bar_theme to accept an optional
window_label parameter and apply the theme only to that label if provided;
adjust references to set_title_bar_theme and create_preview_window accordingly
so preview windows receive updates too.
- Around line 3705-3708: The Windows title bar is forced to light by calling
windows_title_bar::apply_title_bar_theme(&main_window, false) at startup; change
this to respect system preference by querying the system theme and passing the
actual dark/light boolean (or defer the call and let the frontend call
set_title_bar_theme after ThemeContext resolves). Update the #[cfg(target_os =
"windows")] block: replace the hardcoded false with the system theme check (or
remove the call and rely on set_title_bar_theme) so apply_title_bar_theme and
main_window use the correct initial is_dark value.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d1fc1545-3c61-42a6-94ea-fc65d97dbff4

📥 Commits

Reviewing files that changed from the base of the PR and between 6d443e9 and 9ea3893.

📒 Files selected for processing (2)
  • src-tauri/src/lib.rs
  • src/context/ThemeContext.tsx

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.

1 participant