mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
fix: titlebar does not follow theme in dark mode (#903)
This commit is contained in:
@@ -954,3 +954,18 @@ fn run_windows_start_command(args: &[&str], terminal_name: &str) -> Result<(), S
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 设置窗口主题(Windows/macOS 标题栏颜色)
|
||||||
|
/// theme: "dark" | "light" | "system"
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn set_window_theme(window: tauri::Window, theme: String) -> Result<(), String> {
|
||||||
|
use tauri::Theme;
|
||||||
|
|
||||||
|
let tauri_theme = match theme.as_str() {
|
||||||
|
"dark" => Some(Theme::Dark),
|
||||||
|
"light" => Some(Theme::Light),
|
||||||
|
_ => None, // system default
|
||||||
|
};
|
||||||
|
|
||||||
|
window.set_theme(tauri_theme).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|||||||
@@ -956,6 +956,8 @@ pub fn run() {
|
|||||||
commands::test_proxy_url,
|
commands::test_proxy_url,
|
||||||
commands::get_upstream_proxy_status,
|
commands::get_upstream_proxy_status,
|
||||||
commands::scan_local_proxies,
|
commands::scan_local_proxies,
|
||||||
|
// Window theme control
|
||||||
|
commands::set_window_theme,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let app = builder
|
let app = builder
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import React, {
|
|||||||
useMemo,
|
useMemo,
|
||||||
useState,
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
|
||||||
type Theme = "light" | "dark" | "system";
|
type Theme = "light" | "dark" | "system";
|
||||||
|
|
||||||
@@ -94,6 +95,54 @@ export function ThemeProvider({
|
|||||||
return () => mediaQuery.removeEventListener("change", handleChange);
|
return () => mediaQuery.removeEventListener("change", handleChange);
|
||||||
}, [theme]);
|
}, [theme]);
|
||||||
|
|
||||||
|
// Sync native window theme (Windows/macOS title bar)
|
||||||
|
useEffect(() => {
|
||||||
|
if (typeof window === "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let isCancelled = false;
|
||||||
|
|
||||||
|
const updateNativeTheme = async (nativeTheme: string) => {
|
||||||
|
if (isCancelled) return;
|
||||||
|
try {
|
||||||
|
await invoke("set_window_theme", { theme: nativeTheme });
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore errors (e.g., when not running in Tauri)
|
||||||
|
console.debug("Failed to set native window theme:", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Determine current effective theme
|
||||||
|
if (theme === "system") {
|
||||||
|
const isDark =
|
||||||
|
window.matchMedia &&
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||||
|
updateNativeTheme(isDark ? "dark" : "light");
|
||||||
|
} else {
|
||||||
|
updateNativeTheme(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen to system theme changes for native window when in "system" mode
|
||||||
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
const handleChange = () => {
|
||||||
|
if (theme === "system" && !isCancelled) {
|
||||||
|
updateNativeTheme(mediaQuery.matches ? "dark" : "light");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (theme === "system") {
|
||||||
|
mediaQuery.addEventListener("change", handleChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
isCancelled = true;
|
||||||
|
if (theme === "system") {
|
||||||
|
mediaQuery.removeEventListener("change", handleChange);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [theme]);
|
||||||
|
|
||||||
const value = useMemo<ThemeContextValue>(
|
const value = useMemo<ThemeContextValue>(
|
||||||
() => ({
|
() => ({
|
||||||
theme,
|
theme,
|
||||||
|
|||||||
Reference in New Issue
Block a user