mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
Add Window::set_theme
(#2553)
* Add `Window::set_theme` * typo * fix linux build * fix wayland * review changes * update docs * update changelog * pin `image` dep * suppport falling back to system default * fix linux * default to dark on macOS and x11 * fix `setAppearance` definition * add macOS notes * update docs * Update CHANGELOG.md Co-authored-by: Markus Siglreithmaier <m.siglreith@gmail.com> * update doc * Revert "pin `image` dep" This reverts commit 7517f7c5065b4089ca146ce8799dab445ec32068. * Update theme example with Window::set_theme * Fix Window::theme getter on macOS Co-authored-by: Markus Siglreithmaier <m.siglreith@gmail.com> Co-authored-by: Mads Marquart <mads@marquart.dk>
This commit is contained in:
parent
9ae7498a8a
commit
28e34c2e1b
|
@ -8,7 +8,9 @@ And please only add new entries to the top of this list, right below the `# Unre
|
||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
- On Windows, revert window background to an empty brush to avoid white flashes when changing scaling
|
- On Windows, macOS, X11 and Wayland, add `Window::set_theme`.
|
||||||
|
- **Breaking:** Remove `WindowExtWayland::wayland_set_csd_theme` and `WindowBuilderExtX11::with_gtk_theme_variant`.
|
||||||
|
- On Windows, revert window background to an empty brush to avoid white flashes when changing scaling.
|
||||||
- **Breaking:** Removed `Window::set_always_on_top` and related APIs in favor of `Window::set_window_level`.
|
- **Breaking:** Removed `Window::set_always_on_top` and related APIs in favor of `Window::set_window_level`.
|
||||||
- On Windows, MacOS and X11, add always on bottom APIs.
|
- On Windows, MacOS and X11, add always on bottom APIs.
|
||||||
- On Windows, fix the value in `MouseButton::Other`.
|
- On Windows, fix the value in `MouseButton::Other`.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use simple_logger::SimpleLogger;
|
use simple_logger::SimpleLogger;
|
||||||
use winit::{
|
use winit::{
|
||||||
event::{Event, WindowEvent},
|
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
window::{Theme, WindowBuilder},
|
window::{Theme, WindowBuilder},
|
||||||
};
|
};
|
||||||
|
@ -18,6 +18,10 @@ fn main() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
println!("Initial theme: {:?}", window.theme());
|
println!("Initial theme: {:?}", window.theme());
|
||||||
|
println!("debugging keys:");
|
||||||
|
println!(" (A) Automatic theme");
|
||||||
|
println!(" (L) Light theme");
|
||||||
|
println!(" (D) Dark theme");
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
*control_flow = ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
|
@ -34,6 +38,33 @@ fn main() {
|
||||||
} if window_id == window.id() => {
|
} if window_id == window.id() => {
|
||||||
println!("Theme is changed: {:?}", theme)
|
println!("Theme is changed: {:?}", theme)
|
||||||
}
|
}
|
||||||
|
Event::WindowEvent {
|
||||||
|
event:
|
||||||
|
WindowEvent::KeyboardInput {
|
||||||
|
input:
|
||||||
|
KeyboardInput {
|
||||||
|
virtual_keycode: Some(key),
|
||||||
|
state: ElementState::Pressed,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => match key {
|
||||||
|
VirtualKeyCode::A => {
|
||||||
|
println!("Theme was: {:?}", window.theme());
|
||||||
|
window.set_theme(None);
|
||||||
|
}
|
||||||
|
VirtualKeyCode::L => {
|
||||||
|
println!("Theme was: {:?}", window.theme());
|
||||||
|
window.set_theme(Some(Theme::Light));
|
||||||
|
}
|
||||||
|
VirtualKeyCode::D => {
|
||||||
|
println!("Theme was: {:?}", window.theme());
|
||||||
|
window.set_theme(Some(Theme::Dark));
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -88,14 +88,6 @@ pub trait WindowExtWayland {
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the [`Window`] is destroyed.
|
/// The pointer will become invalid when the [`Window`] is destroyed.
|
||||||
fn wayland_display(&self) -> Option<*mut raw::c_void>;
|
fn wayland_display(&self) -> Option<*mut raw::c_void>;
|
||||||
|
|
||||||
/// Updates [`Theme`] of window decorations.
|
|
||||||
///
|
|
||||||
/// You can also use `WINIT_WAYLAND_CSD_THEME` env variable to set the theme.
|
|
||||||
/// Possible values for env variable are: "dark" and light".
|
|
||||||
///
|
|
||||||
/// When unspecified a theme is automatically selected.
|
|
||||||
fn wayland_set_csd_theme(&self, config: Theme);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowExtWayland for Window {
|
impl WindowExtWayland for Window {
|
||||||
|
@ -116,16 +108,6 @@ impl WindowExtWayland for Window {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn wayland_set_csd_theme(&self, theme: Theme) {
|
|
||||||
#[allow(clippy::single_match)]
|
|
||||||
match self.window {
|
|
||||||
LinuxWindow::Wayland(ref w) => w.set_csd_theme(theme),
|
|
||||||
#[cfg(feature = "x11")]
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional methods on [`WindowBuilder`] that are specific to Wayland.
|
/// Additional methods on [`WindowBuilder`] that are specific to Wayland.
|
||||||
|
|
|
@ -190,9 +190,6 @@ pub trait WindowBuilderExtX11 {
|
||||||
/// Build window with `_NET_WM_WINDOW_TYPE` hints; defaults to `Normal`. Only relevant on X11.
|
/// Build window with `_NET_WM_WINDOW_TYPE` hints; defaults to `Normal`. Only relevant on X11.
|
||||||
fn with_x11_window_type(self, x11_window_type: Vec<XWindowType>) -> Self;
|
fn with_x11_window_type(self, x11_window_type: Vec<XWindowType>) -> Self;
|
||||||
|
|
||||||
/// Build window with `_GTK_THEME_VARIANT` hint set to the specified value. Currently only relevant on X11.
|
|
||||||
fn with_gtk_theme_variant(self, variant: String) -> Self;
|
|
||||||
|
|
||||||
/// Build window with base size hint. Only implemented on X11.
|
/// Build window with base size hint. Only implemented on X11.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -248,12 +245,6 @@ impl WindowBuilderExtX11 for WindowBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_gtk_theme_variant(mut self, variant: String) -> Self {
|
|
||||||
self.platform_specific.gtk_theme_variant = Some(variant);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_base_size<S: Into<Size>>(mut self, base_size: S) -> Self {
|
fn with_base_size<S: Into<Size>>(mut self, base_size: S) -> Self {
|
||||||
self.platform_specific.base_size = Some(base_size.into());
|
self.platform_specific.base_size = Some(base_size.into());
|
||||||
|
|
|
@ -1041,6 +1041,8 @@ impl Window {
|
||||||
self.app.content_rect()
|
self.app.content_rect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_theme(&self, _theme: Option<Theme>) {}
|
||||||
|
|
||||||
pub fn theme(&self) -> Option<Theme> {
|
pub fn theme(&self) -> Option<Theme> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,6 +348,11 @@ impl Inner {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_theme(&self, _theme: Option<Theme>) {
|
||||||
|
warn!("`Window::set_theme` is ignored on iOS");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn title(&self) -> String {
|
pub fn title(&self) -> String {
|
||||||
warn!("`Window::title` is ignored on iOS");
|
warn!("`Window::title` is ignored on iOS");
|
||||||
String::new()
|
String::new()
|
||||||
|
|
|
@ -100,8 +100,6 @@ pub struct PlatformSpecificWindowBuilderAttributes {
|
||||||
pub override_redirect: bool,
|
pub override_redirect: bool,
|
||||||
#[cfg(feature = "x11")]
|
#[cfg(feature = "x11")]
|
||||||
pub x11_window_types: Vec<XWindowType>,
|
pub x11_window_types: Vec<XWindowType>,
|
||||||
#[cfg(feature = "x11")]
|
|
||||||
pub gtk_theme_variant: Option<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PlatformSpecificWindowBuilderAttributes {
|
impl Default for PlatformSpecificWindowBuilderAttributes {
|
||||||
|
@ -120,8 +118,6 @@ impl Default for PlatformSpecificWindowBuilderAttributes {
|
||||||
override_redirect: false,
|
override_redirect: false,
|
||||||
#[cfg(feature = "x11")]
|
#[cfg(feature = "x11")]
|
||||||
x11_window_types: vec![XWindowType::Normal],
|
x11_window_types: vec![XWindowType::Normal],
|
||||||
#[cfg(feature = "x11")]
|
|
||||||
gtk_theme_variant: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -585,6 +581,11 @@ impl Window {
|
||||||
x11_or_wayland!(match self; Window(window) => window.raw_display_handle())
|
x11_or_wayland!(match self; Window(window) => window.raw_display_handle())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_theme(&self, theme: Option<Theme>) {
|
||||||
|
x11_or_wayland!(match self; Window(window) => window.set_theme(theme))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn theme(&self) -> Option<Theme> {
|
pub fn theme(&self) -> Option<Theme> {
|
||||||
x11_or_wayland!(match self; Window(window) => window.theme())
|
x11_or_wayland!(match self; Window(window) => window.theme())
|
||||||
|
|
|
@ -439,11 +439,6 @@ impl Window {
|
||||||
self.decorated.load(Ordering::Relaxed)
|
self.decorated.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set_csd_theme(&self, theme: Theme) {
|
|
||||||
self.send_request(WindowRequest::CsdThemeVariant(theme));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_minimized(&self, minimized: bool) {
|
pub fn set_minimized(&self, minimized: bool) {
|
||||||
// You can't unminimize the window on Wayland.
|
// You can't unminimize the window on Wayland.
|
||||||
|
@ -620,6 +615,11 @@ impl Window {
|
||||||
self.event_loop_awakener.ping();
|
self.event_loop_awakener.ping();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_theme(&self, theme: Option<Theme>) {
|
||||||
|
self.send_request(WindowRequest::Theme(theme));
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn theme(&self) -> Option<Theme> {
|
pub fn theme(&self) -> Option<Theme> {
|
||||||
None
|
None
|
||||||
|
|
|
@ -59,9 +59,6 @@ pub enum WindowRequest {
|
||||||
/// Request decorations change.
|
/// Request decorations change.
|
||||||
Decorate(bool),
|
Decorate(bool),
|
||||||
|
|
||||||
/// Request decorations change.
|
|
||||||
CsdThemeVariant(Theme),
|
|
||||||
|
|
||||||
/// Make the window resizeable.
|
/// Make the window resizeable.
|
||||||
Resizeable(bool),
|
Resizeable(bool),
|
||||||
|
|
||||||
|
@ -96,6 +93,9 @@ pub enum WindowRequest {
|
||||||
|
|
||||||
/// Window should be closed.
|
/// Window should be closed.
|
||||||
Close,
|
Close,
|
||||||
|
|
||||||
|
/// Change window theme.
|
||||||
|
Theme(Option<Theme>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// The window update comming from the compositor.
|
// The window update comming from the compositor.
|
||||||
|
@ -464,15 +464,6 @@ pub fn handle_window_requests(winit_state: &mut WinitState) {
|
||||||
let window_request = window_user_requests.get_mut(window_id).unwrap();
|
let window_request = window_user_requests.get_mut(window_id).unwrap();
|
||||||
window_request.refresh_frame = true;
|
window_request.refresh_frame = true;
|
||||||
}
|
}
|
||||||
#[cfg(feature = "sctk-adwaita")]
|
|
||||||
WindowRequest::CsdThemeVariant(theme) => {
|
|
||||||
window_handle.window.set_frame_config(theme.into());
|
|
||||||
|
|
||||||
let window_requst = window_user_requests.get_mut(window_id).unwrap();
|
|
||||||
window_requst.refresh_frame = true;
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "sctk-adwaita"))]
|
|
||||||
WindowRequest::CsdThemeVariant(_) => {}
|
|
||||||
WindowRequest::Resizeable(resizeable) => {
|
WindowRequest::Resizeable(resizeable) => {
|
||||||
window_handle.window.set_resizable(resizeable);
|
window_handle.window.set_resizable(resizeable);
|
||||||
|
|
||||||
|
@ -537,6 +528,18 @@ pub fn handle_window_requests(winit_state: &mut WinitState) {
|
||||||
let event_sink = &mut winit_state.event_sink;
|
let event_sink = &mut winit_state.event_sink;
|
||||||
event_sink.push_window_event(WindowEvent::Destroyed, *window_id);
|
event_sink.push_window_event(WindowEvent::Destroyed, *window_id);
|
||||||
}
|
}
|
||||||
|
WindowRequest::Theme(_theme) => {
|
||||||
|
#[cfg(feature = "sctk-adwaita")]
|
||||||
|
{
|
||||||
|
window_handle.window.set_frame_config(match _theme {
|
||||||
|
Some(theme) => theme.into(),
|
||||||
|
None => sctk_adwaita::FrameConfig::auto(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let window_requst = window_user_requests.get_mut(window_id).unwrap();
|
||||||
|
window_requst.refresh_frame = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,6 +301,10 @@ impl UnownedWindow {
|
||||||
.set_decorations_inner(window_attrs.decorations)
|
.set_decorations_inner(window_attrs.decorations)
|
||||||
.queue();
|
.queue();
|
||||||
|
|
||||||
|
if let Some(theme) = window_attrs.preferred_theme {
|
||||||
|
window.set_theme_inner(Some(theme)).queue();
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Enable drag and drop (TODO: extend API to make this toggleable)
|
// Enable drag and drop (TODO: extend API to make this toggleable)
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -359,10 +363,6 @@ impl UnownedWindow {
|
||||||
|
|
||||||
window.set_window_types(pl_attribs.x11_window_types).queue();
|
window.set_window_types(pl_attribs.x11_window_types).queue();
|
||||||
|
|
||||||
if let Some(variant) = pl_attribs.gtk_theme_variant {
|
|
||||||
window.set_gtk_theme_variant(variant).queue();
|
|
||||||
}
|
|
||||||
|
|
||||||
// set size hints
|
// set size hints
|
||||||
{
|
{
|
||||||
let mut min_inner_size = window_attrs
|
let mut min_inner_size = window_attrs
|
||||||
|
@ -565,9 +565,14 @@ impl UnownedWindow {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_gtk_theme_variant(&self, variant: String) -> util::Flusher<'_> {
|
pub fn set_theme_inner(&self, theme: Option<Theme>) -> util::Flusher<'_> {
|
||||||
let hint_atom = unsafe { self.xconn.get_atom_unchecked(b"_GTK_THEME_VARIANT\0") };
|
let hint_atom = unsafe { self.xconn.get_atom_unchecked(b"_GTK_THEME_VARIANT\0") };
|
||||||
let utf8_atom = unsafe { self.xconn.get_atom_unchecked(b"UTF8_STRING\0") };
|
let utf8_atom = unsafe { self.xconn.get_atom_unchecked(b"UTF8_STRING\0") };
|
||||||
|
let variant = match theme {
|
||||||
|
Some(Theme::Dark) => "dark",
|
||||||
|
Some(Theme::Light) => "light",
|
||||||
|
None => "dark",
|
||||||
|
};
|
||||||
let variant = CString::new(variant).expect("`_GTK_THEME_VARIANT` contained null byte");
|
let variant = CString::new(variant).expect("`_GTK_THEME_VARIANT` contained null byte");
|
||||||
self.xconn.change_property(
|
self.xconn.change_property(
|
||||||
self.xwindow,
|
self.xwindow,
|
||||||
|
@ -578,6 +583,13 @@ impl UnownedWindow {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_theme(&self, theme: Option<Theme>) {
|
||||||
|
self.set_theme_inner(theme)
|
||||||
|
.flush()
|
||||||
|
.expect("Failed to change window theme")
|
||||||
|
}
|
||||||
|
|
||||||
fn set_netwm(
|
fn set_netwm(
|
||||||
&self,
|
&self,
|
||||||
operation: util::StateOperation,
|
operation: util::StateOperation,
|
||||||
|
|
|
@ -87,7 +87,7 @@ extern_methods!(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[sel(setAppearance:)]
|
#[sel(setAppearance:)]
|
||||||
pub fn setAppearance(&self, appearance: &NSAppearance);
|
pub fn setAppearance(&self, appearance: Option<&NSAppearance>);
|
||||||
|
|
||||||
#[sel(run)]
|
#[sel(run)]
|
||||||
pub unsafe fn run(&self);
|
pub unsafe fn run(&self);
|
||||||
|
|
|
@ -399,7 +399,7 @@ impl WinitWindow {
|
||||||
|
|
||||||
match attrs.preferred_theme {
|
match attrs.preferred_theme {
|
||||||
Some(theme) => {
|
Some(theme) => {
|
||||||
set_ns_theme(theme);
|
set_ns_theme(Some(theme));
|
||||||
let mut state = this.shared_state.lock().unwrap();
|
let mut state = this.shared_state.lock().unwrap();
|
||||||
state.current_theme = Some(theme);
|
state.current_theme = Some(theme);
|
||||||
}
|
}
|
||||||
|
@ -1125,6 +1125,12 @@ impl WinitWindow {
|
||||||
state.current_theme
|
state.current_theme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_theme(&self, theme: Option<Theme>) {
|
||||||
|
set_ns_theme(theme);
|
||||||
|
self.lock_shared_state("set_theme").current_theme = theme.or_else(|| Some(get_ns_theme()));
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_content_protected(&self, protected: bool) {
|
pub fn set_content_protected(&self, protected: bool) {
|
||||||
self.setSharingType(if protected {
|
self.setSharingType(if protected {
|
||||||
|
@ -1254,15 +1260,17 @@ pub(super) fn get_ns_theme() -> Theme {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_ns_theme(theme: Theme) {
|
fn set_ns_theme(theme: Option<Theme>) {
|
||||||
let app = NSApp();
|
let app = NSApp();
|
||||||
let has_theme: bool = unsafe { msg_send![&app, respondsToSelector: sel!(effectiveAppearance)] };
|
let has_theme: bool = unsafe { msg_send![&app, respondsToSelector: sel!(effectiveAppearance)] };
|
||||||
if has_theme {
|
if has_theme {
|
||||||
let name = match theme {
|
let appearance = theme.map(|t| {
|
||||||
|
let name = match t {
|
||||||
Theme::Dark => NSString::from_str("NSAppearanceNameDarkAqua"),
|
Theme::Dark => NSString::from_str("NSAppearanceNameDarkAqua"),
|
||||||
Theme::Light => NSString::from_str("NSAppearanceNameAqua"),
|
Theme::Light => NSString::from_str("NSAppearanceNameAqua"),
|
||||||
};
|
};
|
||||||
let appearance = NSAppearance::appearanceNamed(&name);
|
NSAppearance::appearanceNamed(&name)
|
||||||
app.setAppearance(&appearance);
|
});
|
||||||
|
app.setAppearance(appearance.as_ref().map(|a| a.as_ref()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -375,6 +375,9 @@ impl Window {
|
||||||
RawDisplayHandle::Web(WebDisplayHandle::empty())
|
RawDisplayHandle::Web(WebDisplayHandle::empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_theme(&self, _theme: Option<Theme>) {}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn theme(&self) -> Option<Theme> {
|
pub fn theme(&self) -> Option<Theme> {
|
||||||
None
|
None
|
||||||
|
|
|
@ -701,6 +701,11 @@ impl Window {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_theme(&self, theme: Option<Theme>) {
|
||||||
|
try_theme(self.window.0, theme);
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn theme(&self) -> Option<Theme> {
|
pub fn theme(&self) -> Option<Theme> {
|
||||||
Some(self.window_state_lock().current_theme)
|
Some(self.window_state_lock().current_theme)
|
||||||
|
|
|
@ -349,8 +349,10 @@ impl WindowBuilder {
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
|
/// - **macOS:** This is an app-wide setting.
|
||||||
/// - **Wayland:** This control only CSD. You can also use `WINIT_WAYLAND_CSD_THEME` env variable to set the theme.
|
/// - **Wayland:** This control only CSD. You can also use `WINIT_WAYLAND_CSD_THEME` env variable to set the theme.
|
||||||
/// Possible values for env variable are: "dark" and light".
|
/// Possible values for env variable are: "dark" and light".
|
||||||
|
/// - **x11:** Build window with `_GTK_THEME_VARIANT` hint set to `dark` or `light`.
|
||||||
/// - **iOS / Android / Web / x11:** Ignored.
|
/// - **iOS / Android / Web / x11:** Ignored.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_theme(mut self, theme: Option<Theme>) -> Self {
|
pub fn with_theme(mut self, theme: Option<Theme>) -> Self {
|
||||||
|
@ -963,11 +965,26 @@ impl Window {
|
||||||
self.window.request_user_attention(request_type)
|
self.window.request_user_attention(request_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the current window theme. Use `None` to fallback to system default.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** This is an app-wide setting.
|
||||||
|
/// - **Wayland:** You can also use `WINIT_WAYLAND_CSD_THEME` env variable to set the theme.
|
||||||
|
/// Possible values for env variable are: "dark" and light". When unspecified, a theme is automatically selected.
|
||||||
|
/// -**x11:** Sets `_GTK_THEME_VARIANT` hint to `dark` or `light` and if `None` is used, it will default to [`Theme::Dark`].
|
||||||
|
/// - **iOS / Android / Web / x11:** Unsupported.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_theme(&self, theme: Option<Theme>) {
|
||||||
|
self.window.set_theme(theme)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the current window theme.
|
/// Returns the current window theme.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS / Android / Web / x11:** Unsupported.
|
/// - **macOS:** This is an app-wide setting.
|
||||||
|
/// - **iOS / Android / Web / Wayland / x11:** Unsupported.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn theme(&self) -> Option<Theme> {
|
pub fn theme(&self) -> Option<Theme> {
|
||||||
self.window.theme()
|
self.window.theme()
|
||||||
|
|
Loading…
Reference in a new issue