diff --git a/v2/src/renderer.rs b/v2/src/renderer.rs index 41b3294..1553885 100644 --- a/v2/src/renderer.rs +++ b/v2/src/renderer.rs @@ -180,6 +180,7 @@ pub trait Renderer { fn set_title(&self, title: &str); fn window_state(&self) -> Option; fn theme(&self) -> Theme; + fn set_theme(&self, theme: Theme) -> Result<()>; fn show(&self); fn set_background_color(&self, rbga: (u8, u8, u8, u8)) -> Result<()>; fn print(&self) -> Result<()>; @@ -209,5 +210,6 @@ pub trait Rendering: Sized { pub trait EventHandler { fn handle_user_event(&mut self, event: UserEvent) -> Result; fn handle_menu_event(&mut self, item: MenuItem) -> Result; + fn handle_theme_changed(&mut self, theme: Theme) -> Result; fn handle_exit(&self) -> Result<()>; } diff --git a/v2/src/shiba.rs b/v2/src/shiba.rs index 55a5f14..21e3a69 100644 --- a/v2/src/shiba.rs +++ b/v2/src/shiba.rs @@ -5,7 +5,7 @@ use crate::markdown::{DisplayText, MarkdownContent, MarkdownParser}; use crate::opener::Opener; use crate::renderer::{ EventHandler, MenuItem, MessageFromRenderer, MessageToRenderer, Renderer, Rendering, - RenderingFlow, UserEvent, + RenderingFlow, Theme, UserEvent, }; use crate::watcher::{PathFilter, Watcher}; use anyhow::{Context as _, Result}; @@ -494,6 +494,11 @@ where Ok(RenderingFlow::Continue) } + fn handle_theme_changed(&mut self, theme: Theme) -> Result { + self.renderer.set_theme(theme)?; + Ok(RenderingFlow::Continue) + } + fn handle_exit(&self) -> Result<()> { log::debug!("Handling application exit"); let data_dir = self.config.data_dir(); diff --git a/v2/src/wry/event_loop.rs b/v2/src/wry/event_loop.rs index 1cb5260..8fa3542 100644 --- a/v2/src/wry/event_loop.rs +++ b/v2/src/wry/event_loop.rs @@ -1,10 +1,13 @@ use crate::config::Config; -use crate::renderer::{EventHandler, Rendering, RenderingFlow, UserEvent, UserEventSender}; +use crate::renderer::{ + EventHandler, Rendering, RenderingFlow, Theme as RendererTheme, UserEvent, UserEventSender, +}; use crate::wry::menu::{Menu, MenuEvents}; use crate::wry::webview::{EventLoop, WebViewRenderer}; use anyhow::{Error, Result}; use wry::application::event::{Event, StartCause, WindowEvent}; use wry::application::event_loop::{ControlFlow, EventLoopBuilder, EventLoopProxy}; +use wry::application::window::Theme; pub struct Wry { event_loop: EventLoop, @@ -88,6 +91,22 @@ impl Rendering for Wry { log::debug!("Closing window was requested"); RenderingFlow::Exit } + Event::WindowEvent { + event: WindowEvent::ThemeChanged(theme @ (Theme::Light | Theme::Dark)), + .. + } => { + log::debug!("Window theme was changed: {:?}", theme); + let theme = match theme { + Theme::Light => RendererTheme::Light, + Theme::Dark => RendererTheme::Dark, + _ => unreachable!(), + }; + handler.handle_theme_changed(theme).unwrap_or_else(|err| { + log::error!("Could not handle theme change: {:?}", theme); + log_causes(err); + RenderingFlow::Continue + }) + } Event::UserEvent(event) => handler.handle_user_event(event).unwrap_or_else(|err| { log::error!("Could not handle user event"); log_causes(err); diff --git a/v2/src/wry/webview.rs b/v2/src/wry/webview.rs index f85d983..2f2ae93 100644 --- a/v2/src/wry/webview.rs +++ b/v2/src/wry/webview.rs @@ -286,6 +286,22 @@ impl Renderer for WebViewRenderer { window_theme(self.webview.window()) } + #[cfg(target_os = "windows")] + fn set_theme(&self, theme: RendererTheme) -> Result<()> { + use wry::webview::{Theme as WebViewTheme, WebviewExtWindows as _}; + let theme = match theme { + RendererTheme::Dark => WebViewTheme::Dark, + RendererTheme::Light => WebViewTheme::Light, + }; + self.webview.set_theme(theme); + Ok(()) + } + #[cfg(not(target_os = "windows"))] + fn set_theme(&self, _theme: RendererTheme) -> Result<()> { + // Note: winit has Window::set_theme but tao doesn't + Ok(()) + } + fn show(&self) { self.webview.window().set_visible(true); }