Skip to content

Commit 4cebcf6

Browse files
authored
feat: expose theme APIs, closes #3903 (#3937)
1 parent 0299e50 commit 4cebcf6

File tree

22 files changed

+258
-13
lines changed

22 files changed

+258
-13
lines changed

.changes/api-theme-getter.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"api": patch
3+
---
4+
5+
Added `theme` getter to `WebviewWindow`.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"api": patch
3+
---
4+
5+
Added `theme` field to `WindowOptions`.

.changes/tauri-event-api.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"api": patch
3+
---
4+
5+
Added the `tauri://theme-changed` event.

.changes/theme-event.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri": patch
3+
"tauri-runtime": patch
4+
"tauri-runtime-wry": patch
5+
---
6+
7+
Added `WindowEvent::ThemeChanged(theme)`.

.changes/theme-getter.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri": patch
3+
"tauri-runtime": patch
4+
"tauri-runtime-wry": patch
5+
---
6+
7+
Added `theme` getter on `Window`.

.changes/window-builder-theme.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri": patch
3+
"tauri-runtime": patch
4+
"tauri-runtime-wry": patch
5+
---
6+
7+
Added `theme` setter to the WindowBuilder.

core/tauri-runtime-wry/src/lib.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use wry::application::platform::windows::{WindowBuilderExtWindows, WindowExtWind
4040
#[cfg(feature = "system-tray")]
4141
use wry::application::system_tray::{SystemTray as WrySystemTray, SystemTrayBuilder};
4242

43-
use tauri_utils::config::WindowConfig;
43+
use tauri_utils::{config::WindowConfig, Theme};
4444
use uuid::Uuid;
4545
use wry::{
4646
application::{
@@ -62,7 +62,10 @@ use wry::{
6262
MenuType,
6363
},
6464
monitor::MonitorHandle,
65-
window::{Fullscreen, Icon as WryWindowIcon, UserAttentionType as WryUserAttentionType},
65+
window::{
66+
Fullscreen, Icon as WryWindowIcon, Theme as WryTheme,
67+
UserAttentionType as WryUserAttentionType,
68+
},
6669
},
6770
http::{
6871
Request as WryHttpRequest, RequestParts as WryRequestParts, Response as WryHttpResponse,
@@ -607,6 +610,14 @@ impl WindowEventWrapper {
607610
}
608611
}
609612

613+
fn map_theme(theme: &WryTheme) -> Theme {
614+
match theme {
615+
WryTheme::Light => Theme::Light,
616+
WryTheme::Dark => Theme::Dark,
617+
_ => Theme::Light,
618+
}
619+
}
620+
610621
impl<'a> From<&WryWindowEvent<'a>> for WindowEventWrapper {
611622
fn from(event: &WryWindowEvent<'a>) -> Self {
612623
let event = match event {
@@ -624,6 +635,7 @@ impl<'a> From<&WryWindowEvent<'a>> for WindowEventWrapper {
624635
},
625636
#[cfg(any(target_os = "linux", target_os = "macos"))]
626637
WryWindowEvent::Focused(focused) => WindowEvent::Focused(*focused),
638+
WryWindowEvent::ThemeChanged(theme) => WindowEvent::ThemeChanged(map_theme(theme)),
627639
_ => return Self(None),
628640
};
629641
Self(Some(event))
@@ -776,7 +788,8 @@ impl WindowBuilder for WindowBuilderWrapper {
776788
.decorations(config.decorations)
777789
.maximized(config.maximized)
778790
.always_on_top(config.always_on_top)
779-
.skip_taskbar(config.skip_taskbar);
791+
.skip_taskbar(config.skip_taskbar)
792+
.theme(config.theme);
780793

781794
#[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
782795
{
@@ -936,6 +949,22 @@ impl WindowBuilder for WindowBuilderWrapper {
936949
self
937950
}
938951

952+
#[allow(unused_variables, unused_mut)]
953+
fn theme(mut self, theme: Option<Theme>) -> Self {
954+
#[cfg(windows)]
955+
{
956+
self.inner = self.inner.with_theme(if let Some(t) = theme {
957+
match t {
958+
Theme::Dark => Some(WryTheme::Dark),
959+
_ => Some(WryTheme::Light),
960+
}
961+
} else {
962+
None
963+
});
964+
}
965+
self
966+
}
967+
939968
fn has_icon(&self) -> bool {
940969
self.inner.window.window_icon.is_some()
941970
}
@@ -1025,6 +1054,7 @@ pub enum WindowMessage {
10251054
target_os = "openbsd"
10261055
))]
10271056
GtkWindow(Sender<GtkWindow>),
1057+
Theme(Sender<Theme>),
10281058
// Setters
10291059
Center(Sender<Result<()>>),
10301060
RequestUserAttention(Option<UserAttentionTypeWrapper>),
@@ -1275,6 +1305,10 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
12751305
window_getter!(self, WindowMessage::Hwnd).map(|w| w.0)
12761306
}
12771307

1308+
fn theme(&self) -> Result<Theme> {
1309+
window_getter!(self, WindowMessage::Theme)
1310+
}
1311+
12781312
/// Returns the `ApplicatonWindow` from gtk crate that is used by this window.
12791313
#[cfg(any(
12801314
target_os = "linux",
@@ -2090,6 +2124,12 @@ fn handle_user_message<T: UserEvent>(
20902124
target_os = "openbsd"
20912125
))]
20922126
WindowMessage::GtkWindow(tx) => tx.send(GtkWindow(window.gtk_window().clone())).unwrap(),
2127+
WindowMessage::Theme(tx) => {
2128+
#[cfg(windows)]
2129+
tx.send(map_theme(&window.theme())).unwrap();
2130+
#[cfg(not(windows))]
2131+
tx.send(Theme::Light).unwrap();
2132+
}
20932133
// Setters
20942134
WindowMessage::Center(tx) => {
20952135
tx.send(center_window(window, window_handle.inner_size()))

core/tauri-runtime/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use serde::Deserialize;
1010
use std::{fmt::Debug, path::PathBuf, sync::mpsc::Sender};
11+
use tauri_utils::Theme;
1112
use uuid::Uuid;
1213

1314
#[cfg(windows)]
@@ -465,6 +466,9 @@ pub trait Dispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static
465466
#[cfg(windows)]
466467
fn hwnd(&self) -> Result<HWND>;
467468

469+
/// Returns the current window theme.
470+
fn theme(&self) -> Result<Theme>;
471+
468472
/// Returns the native handle that is used by this window.
469473
#[cfg(target_os = "macos")]
470474
fn ns_window(&self) -> Result<*mut std::ffi::c_void>;

core/tauri-runtime/src/webview.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
77
use crate::{menu::Menu, window::DetachedWindow, WindowIcon};
88

9-
use tauri_utils::config::{WindowConfig, WindowUrl};
9+
use tauri_utils::{
10+
config::{WindowConfig, WindowUrl},
11+
Theme,
12+
};
1013

1114
#[cfg(windows)]
1215
use windows::Win32::Foundation::HWND;
@@ -186,6 +189,9 @@ pub trait WindowBuilder: WindowBuilderBase {
186189
#[must_use]
187190
fn owner_window(self, owner: HWND) -> Self;
188191

192+
/// Forces a theme or uses the system settings if None was provided.
193+
fn theme(self, theme: Option<Theme>) -> Self;
194+
189195
/// Whether the icon was set or not.
190196
fn has_icon(&self) -> bool;
191197

core/tauri-runtime/src/window.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
Dispatch, Runtime, UserEvent, WindowBuilder,
1212
};
1313
use serde::Serialize;
14-
use tauri_utils::config::WindowConfig;
14+
use tauri_utils::{config::WindowConfig, Theme};
1515

1616
use std::{
1717
collections::{HashMap, HashSet},
@@ -59,6 +59,12 @@ pub enum WindowEvent {
5959
},
6060
/// An event associated with the file drop action.
6161
FileDrop(FileDropEvent),
62+
/// The system window theme has changed.
63+
///
64+
/// Applications might wish to react to this to change the theme of the content of the window when the system changes the window theme.
65+
///
66+
/// At the moment this is only supported on Windows.
67+
ThemeChanged(Theme),
6268
}
6369

6470
/// The file drop event payload.

0 commit comments

Comments
 (0)