OS がダークモードか判定する

Recipe ID: sys-017

OS のカラーテーマ(ダークモード/ライトモード)を判定する方法を解説します。

解説

Tauri アプリは本質的に Web ブラウザであるため、CSS のメディアクエリ(prefers-color-scheme)を使用するのが最も標準的でレスポンシブな方法です。
また、Tauri の Window API を使用して明示的なテーマ設定を取得することも可能です。

方法 1: CSS / JavaScript (Web 標準)

OS の設定変更を即座に検知でき、再描画のコストも低いため、UI のスタイル切り替えにはこの方法を推奨します。

JavaScript での検知

// 現在の状態を確認
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
console.log(`Dark mode: ${isDark}`);

// 変更を監視 (リスナー)
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
  const newColorScheme = event.matches ? "dark" : "light";
  console.log(`Theme changed to: ${newColorScheme}`);
});

方法 2: Tauri Window API

ウィンドウごとのテーマを取得します。

Permissions (権限) の設定

src-tauri/capabilities/default.json に以下の権限を追加します。

{
  "permissions": [
    ...,
    "core:window:allow-theme"
  ]
}

コード例

import { getCurrentWindow } from '@tauri-apps/api/window';

async function checkWindowTheme() {
  const appWindow = getCurrentWindow();
  
  // 'light', 'dark', または null
  const theme = await appWindow.theme();
  console.log(`Window Theme: ${theme}`);
}

方法 3: バックエンドから判定する (Rust)

Rust 側の tauri::Window インスタンスからもテーマを取得できます。

Rust 実装

use tauri::{command, Theme, Window};

#[command]
fn get_theme_from_rust(window: Window) -> String {
    match window.theme() {
        Ok(Theme::Dark) => "dark".to_string(),
        Ok(Theme::Light) => "light".to_string(),
        _ => "unknown".to_string(),
    }
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![get_theme_from_rust])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

フロントエンドからの呼び出し

import { invoke } from '@tauri-apps/api/core';

invoke<string>('get_theme_from_rust')
  .then(theme => console.log(`Theme from Rust: ${theme}`))
  .catch(console.error);