mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-12-24 19:25:12 +03:00
feat(core): add a new function to set theme dynamically (#10210)
closes #5279
This commit is contained in:
parent
8d22c0c814
commit
11db7be6c2
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -7153,9 +7153,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tao"
|
name = "tao"
|
||||||
version = "0.30.0"
|
version = "0.30.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a93f2c6b8fdaeb7f417bda89b5bc767999745c3052969664ae1fa65892deb7e"
|
checksum = "06e48d7c56b3f7425d061886e8ce3b6acfab1993682ed70bef50fd133d721ee6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"cocoa 0.26.0",
|
"cocoa 0.26.0",
|
||||||
|
@ -23,7 +23,7 @@ wry = { version = "0.44.0", default-features = false, features = [
|
|||||||
"os-webview",
|
"os-webview",
|
||||||
"linux-body",
|
"linux-body",
|
||||||
] }
|
] }
|
||||||
tao = { version = "0.30", default-features = false, features = ["rwh_06"] }
|
tao = { version = "0.30.2", default-features = false, features = ["rwh_06"] }
|
||||||
tauri-runtime = { version = "2.0.0-rc.12", path = "../tauri-runtime" }
|
tauri-runtime = { version = "2.0.0-rc.12", path = "../tauri-runtime" }
|
||||||
tauri-utils = { version = "2.0.0-rc.12", path = "../tauri-utils" }
|
tauri-utils = { version = "2.0.0-rc.12", path = "../tauri-utils" }
|
||||||
raw-window-handle = "0.6"
|
raw-window-handle = "0.6"
|
||||||
|
@ -1204,6 +1204,7 @@ pub enum WindowMessage {
|
|||||||
SetIgnoreCursorEvents(bool),
|
SetIgnoreCursorEvents(bool),
|
||||||
SetProgressBar(ProgressBarState),
|
SetProgressBar(ProgressBarState),
|
||||||
SetTitleBarStyle(tauri_utils::TitleBarStyle),
|
SetTitleBarStyle(tauri_utils::TitleBarStyle),
|
||||||
|
SetTheme(Option<Theme>),
|
||||||
DragWindow,
|
DragWindow,
|
||||||
ResizeDragWindow(tauri_runtime::ResizeDirection),
|
ResizeDragWindow(tauri_runtime::ResizeDirection),
|
||||||
RequestRedraw,
|
RequestRedraw,
|
||||||
@ -2026,6 +2027,13 @@ impl<T: UserEvent> WindowDispatch<T> for WryWindowDispatcher<T> {
|
|||||||
Message::Window(self.window_id, WindowMessage::SetTitleBarStyle(style)),
|
Message::Window(self.window_id, WindowMessage::SetTitleBarStyle(style)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_theme(&self, theme: Option<Theme>) -> Result<()> {
|
||||||
|
send_user_message(
|
||||||
|
&self.context,
|
||||||
|
Message::Window(self.window_id, WindowMessage::SetTheme(theme)),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -2286,6 +2294,18 @@ impl<T: UserEvent> RuntimeHandle<T> for WryHandle<T> {
|
|||||||
.map_err(|_| Error::FailedToGetCursorPosition)
|
.map_err(|_| Error::FailedToGetCursorPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_theme(&self, theme: Option<Theme>) {
|
||||||
|
self
|
||||||
|
.context
|
||||||
|
.main_thread
|
||||||
|
.window_target
|
||||||
|
.set_theme(match theme {
|
||||||
|
Some(Theme::Light) => Some(TaoTheme::Light),
|
||||||
|
Some(Theme::Dark) => Some(TaoTheme::Dark),
|
||||||
|
_ => None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
fn show(&self) -> tauri_runtime::Result<()> {
|
fn show(&self) -> tauri_runtime::Result<()> {
|
||||||
send_user_message(
|
send_user_message(
|
||||||
@ -2564,6 +2584,14 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
|||||||
.map_err(|_| Error::FailedToGetCursorPosition)
|
.map_err(|_| Error::FailedToGetCursorPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_theme(&self, theme: Option<Theme>) {
|
||||||
|
self.event_loop.set_theme(match theme {
|
||||||
|
Some(Theme::Light) => Some(TaoTheme::Light),
|
||||||
|
Some(Theme::Dark) => Some(TaoTheme::Dark),
|
||||||
|
_ => None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
fn set_activation_policy(&mut self, activation_policy: ActivationPolicy) {
|
fn set_activation_policy(&mut self, activation_policy: ActivationPolicy) {
|
||||||
self
|
self
|
||||||
@ -2996,6 +3024,13 @@ fn handle_user_message<T: UserEvent>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
WindowMessage::SetTheme(theme) => {
|
||||||
|
window.set_theme(match theme {
|
||||||
|
Some(Theme::Light) => Some(TaoTheme::Light),
|
||||||
|
Some(Theme::Dark) => Some(TaoTheme::Dark),
|
||||||
|
_ => None,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,6 +311,8 @@ pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'st
|
|||||||
|
|
||||||
fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
|
fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
|
||||||
|
|
||||||
|
fn set_theme(&self, theme: Option<Theme>);
|
||||||
|
|
||||||
/// Shows the application, but does not automatically focus it.
|
/// Shows the application, but does not automatically focus it.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
|
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
|
||||||
@ -402,6 +404,8 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
|
|||||||
|
|
||||||
fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
|
fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
|
||||||
|
|
||||||
|
fn set_theme(&self, theme: Option<Theme>);
|
||||||
|
|
||||||
/// Sets the activation policy for the application.
|
/// Sets the activation policy for the application.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
|
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
|
||||||
@ -802,4 +806,12 @@ pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 's
|
|||||||
///
|
///
|
||||||
/// - **Linux / Windows / iOS / Android:** Unsupported.
|
/// - **Linux / Windows / iOS / Android:** Unsupported.
|
||||||
fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
|
fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
|
||||||
|
|
||||||
|
/// Sets the theme for this window.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **Linux / macOS**: Theme is app-wide and not specific to this window.
|
||||||
|
/// - **iOS / Android:** Unsupported.
|
||||||
|
fn set_theme(&self, theme: Option<Theme>) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[
|
|||||||
("set_progress_bar", false),
|
("set_progress_bar", false),
|
||||||
("set_icon", false),
|
("set_icon", false),
|
||||||
("set_title_bar_style", false),
|
("set_title_bar_style", false),
|
||||||
|
("set_theme", false),
|
||||||
("toggle_maximize", false),
|
("toggle_maximize", false),
|
||||||
// internal
|
// internal
|
||||||
("internal_toggle_maximize", true),
|
("internal_toggle_maximize", true),
|
||||||
@ -141,6 +142,7 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[
|
|||||||
("app_show", false),
|
("app_show", false),
|
||||||
("app_hide", false),
|
("app_hide", false),
|
||||||
("default_window_icon", false),
|
("default_window_icon", false),
|
||||||
|
("set_app_theme", false),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -122,6 +122,32 @@ Denies the name command without any pre-configured scope.
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
|
`core:app:allow-set-app-theme`
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
Enables the set_app_theme command without any pre-configured scope.
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
`core:app:deny-set-app-theme`
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
Denies the set_app_theme command without any pre-configured scope.
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
`core:app:allow-tauri-version`
|
`core:app:allow-tauri-version`
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -1469,6 +1469,32 @@ Denies the set_skip_taskbar command without any pre-configured scope.
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
|
`core:window:allow-set-theme`
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
Enables the set_theme command without any pre-configured scope.
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
`core:window:deny-set-theme`
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
Denies the set_theme command without any pre-configured scope.
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
`core:window:allow-set-title`
|
`core:window:allow-set-title`
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
File diff suppressed because one or more lines are too long
@ -685,6 +685,31 @@ macro_rules! shared_app_impl {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the app theme.
|
||||||
|
pub fn set_theme(&self, theme: Option<Theme>) {
|
||||||
|
#[cfg(windows)]
|
||||||
|
for window in self.manager.windows().values() {
|
||||||
|
if let (Some(menu), Ok(hwnd)) = (window.menu(), window.hwnd()) {
|
||||||
|
let raw_hwnd = hwnd.0 as isize;
|
||||||
|
let _ = self.run_on_main_thread(move || {
|
||||||
|
let _ = unsafe {
|
||||||
|
menu.inner().set_theme_for_hwnd(
|
||||||
|
raw_hwnd,
|
||||||
|
theme
|
||||||
|
.map(crate::menu::map_to_menu_theme)
|
||||||
|
.unwrap_or(muda::MenuTheme::Auto),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
match self.runtime() {
|
||||||
|
RuntimeOrDispatch::Runtime(h) => h.set_theme(theme),
|
||||||
|
RuntimeOrDispatch::RuntimeHandle(h) => h.set_theme(theme),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the default window icon.
|
/// Returns the default window icon.
|
||||||
pub fn default_window_icon(&self) -> Option<&Image<'_>> {
|
pub fn default_window_icon(&self) -> Option<&Image<'_>> {
|
||||||
self.manager.window.default_icon.as_ref()
|
self.manager.window.default_icon.as_ref()
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use tauri_utils::Theme;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
command,
|
command,
|
||||||
plugin::{Builder, TauriPlugin},
|
plugin::{Builder, TauriPlugin},
|
||||||
@ -50,6 +52,11 @@ pub fn default_window_icon<R: Runtime>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[command(root = "crate")]
|
||||||
|
pub async fn set_app_theme<R: Runtime>(app: AppHandle<R>, theme: Option<Theme>) {
|
||||||
|
app.set_theme(theme);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||||
Builder::new("app")
|
Builder::new("app")
|
||||||
.invoke_handler(crate::generate_handler![
|
.invoke_handler(crate::generate_handler![
|
||||||
@ -59,6 +66,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
|||||||
app_show,
|
app_show,
|
||||||
app_hide,
|
app_hide,
|
||||||
default_window_icon,
|
default_window_icon,
|
||||||
|
set_app_theme,
|
||||||
])
|
])
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
@ -243,6 +243,10 @@ impl<T: UserEvent> RuntimeHandle<T> for MockRuntimeHandle {
|
|||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_theme(&self, theme: Option<Theme>) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Shows the application, but does not automatically focus it.
|
/// Shows the application, but does not automatically focus it.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
fn show(&self) -> Result<()> {
|
fn show(&self) -> Result<()> {
|
||||||
@ -955,6 +959,10 @@ impl<T: UserEvent> WindowDispatch<T> for MockWindowDispatcher {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_theme(&self, theme: Option<Theme>) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -1096,6 +1104,10 @@ impl<T: UserEvent> Runtime<T> for MockRuntime {
|
|||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_theme(&self, theme: Option<Theme>) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
|
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
|
||||||
fn set_activation_policy(&mut self, activation_policy: tauri_runtime::ActivationPolicy) {}
|
fn set_activation_policy(&mut self, activation_policy: tauri_runtime::ActivationPolicy) {}
|
||||||
|
@ -27,7 +27,10 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tauri_utils::config::{WebviewUrl, WindowConfig};
|
use tauri_utils::{
|
||||||
|
config::{WebviewUrl, WindowConfig},
|
||||||
|
Theme,
|
||||||
|
};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -1582,6 +1585,11 @@ impl<R: Runtime> WebviewWindow<R> {
|
|||||||
pub fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> crate::Result<()> {
|
pub fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> crate::Result<()> {
|
||||||
self.webview.window().set_title_bar_style(style)
|
self.webview.window().set_title_bar_style(style)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the window theme.
|
||||||
|
pub fn set_theme(&self, theme: Option<Theme>) -> crate::Result<()> {
|
||||||
|
self.webview.window().set_theme(theme)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Desktop webview setters and actions.
|
/// Desktop webview setters and actions.
|
||||||
|
@ -1981,6 +1981,7 @@ tauri::Builder::default()
|
|||||||
})
|
})
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the title bar style. **macOS only**.
|
/// Sets the title bar style. **macOS only**.
|
||||||
pub fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> crate::Result<()> {
|
pub fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> crate::Result<()> {
|
||||||
self
|
self
|
||||||
@ -1989,6 +1990,35 @@ tauri::Builder::default()
|
|||||||
.set_title_bar_style(style)
|
.set_title_bar_style(style)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the theme for this window.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **Linux / macOS**: Theme is app-wide and not specific to this window.
|
||||||
|
/// - **iOS / Android:** Unsupported.
|
||||||
|
pub fn set_theme(&self, theme: Option<Theme>) -> crate::Result<()> {
|
||||||
|
self
|
||||||
|
.window
|
||||||
|
.dispatcher
|
||||||
|
.set_theme(theme)
|
||||||
|
.map_err(Into::<crate::Error>::into)?;
|
||||||
|
#[cfg(windows)]
|
||||||
|
if let (Some(menu), Ok(hwnd)) = (self.menu(), self.hwnd()) {
|
||||||
|
let raw_hwnd = hwnd.0 as isize;
|
||||||
|
self.run_on_main_thread(move || {
|
||||||
|
let _ = unsafe {
|
||||||
|
menu.inner().set_theme_for_hwnd(
|
||||||
|
raw_hwnd,
|
||||||
|
theme
|
||||||
|
.map(crate::menu::map_to_menu_theme)
|
||||||
|
.unwrap_or(muda::MenuTheme::Auto),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
})?;
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Progress bar state.
|
/// Progress bar state.
|
||||||
|
@ -138,6 +138,7 @@ mod desktop_commands {
|
|||||||
setter!(set_visible_on_all_workspaces, bool);
|
setter!(set_visible_on_all_workspaces, bool);
|
||||||
setter!(set_title_bar_style, TitleBarStyle);
|
setter!(set_title_bar_style, TitleBarStyle);
|
||||||
setter!(set_size_constraints, WindowSizeConstraints);
|
setter!(set_size_constraints, WindowSizeConstraints);
|
||||||
|
setter!(set_theme, Option<Theme>);
|
||||||
|
|
||||||
#[command(root = "crate")]
|
#[command(root = "crate")]
|
||||||
pub async fn set_icon<R: Runtime>(
|
pub async fn set_icon<R: Runtime>(
|
||||||
@ -287,6 +288,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
|||||||
desktop_commands::set_icon,
|
desktop_commands::set_icon,
|
||||||
desktop_commands::set_visible_on_all_workspaces,
|
desktop_commands::set_visible_on_all_workspaces,
|
||||||
desktop_commands::set_title_bar_style,
|
desktop_commands::set_title_bar_style,
|
||||||
|
desktop_commands::set_theme,
|
||||||
desktop_commands::toggle_maximize,
|
desktop_commands::toggle_maximize,
|
||||||
desktop_commands::internal_toggle_maximize,
|
desktop_commands::internal_toggle_maximize,
|
||||||
]);
|
]);
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
"core:default",
|
"core:default",
|
||||||
"core:app:allow-app-hide",
|
"core:app:allow-app-hide",
|
||||||
"core:app:allow-app-show",
|
"core:app:allow-app-show",
|
||||||
|
"core:app:allow-set-app-theme",
|
||||||
|
"core:window:allow-set-theme",
|
||||||
"core:window:allow-center",
|
"core:window:allow-center",
|
||||||
"core:window:allow-request-user-attention",
|
"core:window:allow-request-user-attention",
|
||||||
"core:window:allow-set-resizable",
|
"core:window:allow-set-resizable",
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import { writable } from 'svelte/store'
|
import { writable } from 'svelte/store'
|
||||||
import { invoke } from '@tauri-apps/api/core'
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'
|
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'
|
||||||
|
import { setTheme } from '@tauri-apps/api/app'
|
||||||
|
|
||||||
import Welcome from './views/Welcome.svelte'
|
import Welcome from './views/Welcome.svelte'
|
||||||
import Communication from './views/Communication.svelte'
|
import Communication from './views/Communication.svelte'
|
||||||
@ -83,6 +84,7 @@
|
|||||||
function toggleDark() {
|
function toggleDark() {
|
||||||
isDark = !isDark
|
isDark = !isDark
|
||||||
applyTheme(isDark)
|
applyTheme(isDark)
|
||||||
|
setTheme(isDark ? 'dark' : 'light')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Console
|
// Console
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import { show, hide } from '@tauri-apps/api/app'
|
import { show, hide, setTheme } from '@tauri-apps/api/app'
|
||||||
|
|
||||||
export let onMessage
|
export let onMessage
|
||||||
|
/** @type {import('@tauri-apps/api/window').Theme | 'auto'} */
|
||||||
|
let theme = 'auto'
|
||||||
|
|
||||||
function showApp() {
|
function showApp() {
|
||||||
hideApp()
|
hideApp()
|
||||||
@ -20,6 +22,21 @@
|
|||||||
.then(() => onMessage('Hide app'))
|
.then(() => onMessage('Hide app'))
|
||||||
.catch(onMessage)
|
.catch(onMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function switchTheme() {
|
||||||
|
switch (theme) {
|
||||||
|
case 'dark':
|
||||||
|
theme = 'light'
|
||||||
|
break
|
||||||
|
case 'light':
|
||||||
|
theme = 'auto'
|
||||||
|
break
|
||||||
|
case 'auto':
|
||||||
|
theme = 'dark'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
setTheme(theme === 'auto' ? null : theme)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -30,4 +47,5 @@
|
|||||||
on:click={showApp}>Show</button
|
on:click={showApp}>Show</button
|
||||||
>
|
>
|
||||||
<button class="btn" id="hide" on:click={hideApp}>Hide</button>
|
<button class="btn" id="hide" on:click={hideApp}>Hide</button>
|
||||||
|
<button class="btn" id="hide" on:click={switchTheme}>Switch Theme ({theme})</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -123,6 +123,9 @@
|
|||||||
let cursorIgnoreEvents = false
|
let cursorIgnoreEvents = false
|
||||||
let windowTitle = 'Awesome Tauri Example!'
|
let windowTitle = 'Awesome Tauri Example!'
|
||||||
|
|
||||||
|
/** @type {import('@tauri-apps/api/window').Theme | 'auto'} */
|
||||||
|
let theme = 'auto'
|
||||||
|
|
||||||
let effects = []
|
let effects = []
|
||||||
let selectedEffect
|
let selectedEffect
|
||||||
let effectState
|
let effectState
|
||||||
@ -206,6 +209,21 @@
|
|||||||
await webviewMap[selectedWebview].requestUserAttention(null)
|
await webviewMap[selectedWebview].requestUserAttention(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function switchTheme() {
|
||||||
|
switch (theme) {
|
||||||
|
case 'dark':
|
||||||
|
theme = 'light'
|
||||||
|
break
|
||||||
|
case 'light':
|
||||||
|
theme = 'auto'
|
||||||
|
break
|
||||||
|
case 'auto':
|
||||||
|
theme = 'dark'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
await webviewMap[selectedWebview].setTheme(theme === 'auto' ? null : theme)
|
||||||
|
}
|
||||||
|
|
||||||
async function updateProgressBar() {
|
async function updateProgressBar() {
|
||||||
webviewMap[selectedWebview]?.setProgressBar({
|
webviewMap[selectedWebview]?.setProgressBar({
|
||||||
status: selectedProgressBarStatus,
|
status: selectedProgressBarStatus,
|
||||||
@ -379,6 +397,7 @@
|
|||||||
title="Minimizes the window, requests attention for 3s and then resets it"
|
title="Minimizes the window, requests attention for 3s and then resets it"
|
||||||
>Request attention</button
|
>Request attention</button
|
||||||
>
|
>
|
||||||
|
<button class="btn" on:click={switchTheme}>Switch Theme ({theme})</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid cols-[repeat(auto-fill,minmax(180px,1fr))]">
|
<div class="grid cols-[repeat(auto-fill,minmax(180px,1fr))]">
|
||||||
<label>
|
<label>
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
"build:api": "pnpm run --filter \"@tauri-apps/api\" build",
|
"build:api": "pnpm run --filter \"@tauri-apps/api\" build",
|
||||||
"build:cli": "pnpm run --filter \"@tauri-apps/cli\" build",
|
"build:cli": "pnpm run --filter \"@tauri-apps/cli\" build",
|
||||||
"build:cli:debug": "pnpm run --filter \"@tauri-apps/cli\" build:debug",
|
"build:cli:debug": "pnpm run --filter \"@tauri-apps/cli\" build:debug",
|
||||||
"test": "pnpm run -r build"
|
"test": "pnpm run -r test",
|
||||||
|
"example:api:dev": "pnpm run --filter \"api\" tauri dev"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^3.3.3"
|
"prettier": "^3.3.3"
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import { invoke } from './core'
|
import { invoke } from './core'
|
||||||
import { Image } from './image'
|
import { Image } from './image'
|
||||||
|
import { Theme } from './window'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Application metadata and related APIs.
|
* Application metadata and related APIs.
|
||||||
@ -101,4 +102,31 @@ async function defaultWindowIcon(): Promise<Image | null> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export { getName, getVersion, getTauriVersion, show, hide, defaultWindowIcon }
|
/**
|
||||||
|
* Set app's theme, pass in `null` or `undefined` to follow system theme
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { setTheme } from '@tauri-apps/api/app';
|
||||||
|
* await setTheme('dark');
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* #### Platform-specific
|
||||||
|
*
|
||||||
|
* - **iOS / Android:** Unsupported.
|
||||||
|
*
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
async function setTheme(theme?: Theme | null): Promise<void> {
|
||||||
|
return invoke('plugin:app|set_app_theme', { theme })
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
getName,
|
||||||
|
getVersion,
|
||||||
|
getTauriVersion,
|
||||||
|
show,
|
||||||
|
hide,
|
||||||
|
defaultWindowIcon,
|
||||||
|
setTheme
|
||||||
|
}
|
||||||
|
@ -1676,6 +1676,23 @@ class Window {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set window theme, pass in `null` or `undefined` to follow system theme
|
||||||
|
*
|
||||||
|
* #### Platform-specific
|
||||||
|
*
|
||||||
|
* - **Linux / macOS**: Theme is app-wide and not specific to this window.
|
||||||
|
* - **iOS / Android:** Unsupported.
|
||||||
|
*
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
async setTheme(theme?: Theme | null): Promise<void> {
|
||||||
|
return invoke('plugin:window|set_theme', {
|
||||||
|
label: this.label,
|
||||||
|
value: theme
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Listeners
|
// Listeners
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user