From fc793032be6e654cca0ef87ff91a81f1213fd9c7 Mon Sep 17 00:00:00 2001 From: Brad Veryard Date: Sun, 27 Oct 2024 17:29:34 +0800 Subject: [PATCH 1/8] feat: Add vibrancy --- Cargo.lock | 13 +++- packages/desktop/Cargo.toml | 2 + packages/desktop/src/config.rs | 20 ++++++ packages/desktop/src/widget_factory.rs | 90 +++++++++++++++++++++++++- 4 files changed, 122 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 29afaccf..7236143e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -939,6 +939,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "csscolorparser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f9a16a848a7fb95dd47ce387ac1ee9a6df879ba784b815537fcd388a1a8288" +dependencies = [ + "phf 0.11.2", +] + [[package]] name = "cssparser" version = "0.27.2" @@ -6791,6 +6800,7 @@ dependencies = [ "async-trait", "clap", "cocoa 0.25.0", + "csscolorparser", "komorebi-client", "netdev", "regex", @@ -6808,6 +6818,7 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", + "window-vibrancy", "windows 0.58.0", ] diff --git a/packages/desktop/Cargo.toml b/packages/desktop/Cargo.toml index 1b56d76b..a3819f75 100644 --- a/packages/desktop/Cargo.toml +++ b/packages/desktop/Cargo.toml @@ -36,6 +36,8 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } netdev = "0.24" regex = "1" +window-vibrancy = "0.5.2" +csscolorparser = "0.7.0" [target.'cfg(target_os = "windows")'.dependencies] komorebi-client = { git = "https://github.com/LGUG2Z/komorebi", tag = "v0.1.28" } diff --git a/packages/desktop/src/config.rs b/packages/desktop/src/config.rs index 50bfecca..288676b6 100644 --- a/packages/desktop/src/config.rs +++ b/packages/desktop/src/config.rs @@ -90,6 +90,15 @@ pub struct WidgetConfig { /// Whether the Tauri window frame should be transparent. pub transparent: bool, + /// Whether the window frame should have an effect + pub background_effect: Option, + + // Background effect color (Windows 10 v1903+, no effect on Windows 7 or Windows 11) + pub background_effect_color: Option, + + // Background Dark on Mica (Windows only) + pub background_effect_mica_dark: Option, + /// Where to place the widget. Add alias for `defaultPlacements` for /// compatibility with v2.3.0 and earlier. #[serde(alias = "defaultPlacements")] @@ -161,6 +170,17 @@ pub enum MonitorSelection { Name(String), } +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, ValueEnum)] +#[clap(rename_all = "snake_case")] +#[serde(rename_all = "snake_case")] +pub enum BackgroundEffect { + None, + Blur, // For Windows + Acrylic, // For Windows + Mica, // For Windows + Vibrancy // For macOS; the string represents the material +} + #[derive(Debug)] pub struct Config { /// Handle to the Tauri application. diff --git a/packages/desktop/src/widget_factory.rs b/packages/desktop/src/widget_factory.rs index 9d78e295..61e0056d 100644 --- a/packages/desktop/src/widget_factory.rs +++ b/packages/desktop/src/widget_factory.rs @@ -18,10 +18,13 @@ use tokio::{ task, }; use tracing::{error, info}; - +use csscolorparser::Color; use crate::{ common::{PathExt, WindowExt}, - config::{AnchorPoint, Config, WidgetConfig, WidgetPlacement, ZOrder}, + config::{ + AnchorPoint, BackgroundEffect, Config, WidgetConfig, WidgetPlacement, + ZOrder, + }, monitor_state::MonitorState, }; @@ -191,6 +194,8 @@ impl WidgetFactory { Self::to_asset_url(&html_path.to_unicode_string()).into(), ); + let window_effect = &widget_config.background_effect; + // Note that window label needs to be globally unique. let window = WebviewWindowBuilder::new( &self.app_handle, @@ -254,6 +259,87 @@ impl WidgetFactory { widget_states.insert(state.id.clone(), state.clone()); } + if let Some(window_effect) = &widget_config.background_effect { + if *window_effect != BackgroundEffect::None { + let color = if let Some(color_str) = &widget_config.background_effect_color { + let color = csscolorparser::parse(color_str)?.to_rgba8(); + Some((color[3], color[0], color[1], color[2])) + } else { + Some((18, 18, 18, 125)) + }; + #[cfg(target_os = "macos")] + { + use window_vibrancy::{ + apply_vibrancy, NSVisualEffectMaterial, + }; + if let BackgroundEffect::Vibrancy(material_str) = window_effect + { + let material = match material_str.as_str() { + "appearance-based" => { + NSVisualEffectMaterial::AppearanceBased + } + "light" => NSVisualEffectMaterial::Light, + "dark" => NSVisualEffectMaterial::Dark, + "titlebar" => NSVisualEffectMaterial::Titlebar, + "selection" => NSVisualEffectMaterial::Selection, + "menu" => NSVisualEffectMaterial::Menu, + "popover" => NSVisualEffectMaterial::Popover, + "sidebar" => NSVisualEffectMaterial::Sidebar, + "header-view" => NSVisualEffectMaterial::HeaderView, + "sheet" => NSVisualEffectMaterial::Sheet, + "window-background" => { + NSVisualEffectMaterial::WindowBackground + } + "hud-window" => NSVisualEffectMaterial::HudWindow, + "full-screen-ui" => NSVisualEffectMaterial::FullScreenUi, + "tool-tip" => NSVisualEffectMaterial::ToolTip, + "content-background" => { + NSVisualEffectMaterial::ContentBackground + } + "under-window-background" => { + NSVisualEffectMaterial::UnderWindowBackground + } + "under-page-background" => { + NSVisualEffectMaterial::UnderPageBackground + } + _ => { + error!("Unknown vibrancy material: {}", material_str); + NSVisualEffectMaterial::AppearanceBased + } + }; + + if let Err(e) = apply_vibrancy(&window, material, None, None) + { + error!("Failed to apply vibrancy: {:?}", e); + } + } + } + #[cfg(target_os = "windows")] + { + use window_vibrancy::{apply_acrylic, apply_blur, apply_mica}; + match window_effect { + BackgroundEffect::Blur => { + if let Err(e) = apply_blur(&window, color) { + error!("Failed to apply blur: {:?}", e); + } + } + BackgroundEffect::Acrylic => { + if let Err(e) = apply_acrylic(&window, color) { + error!("Failed to apply acrylic: {:?}", e); + } + } + BackgroundEffect::Mica => { + let mica_dark = widget_config.background_effect_mica_dark.unwrap_or(false); + if let Err(e) = apply_mica(&window, Some(mica_dark)) { + error!("Failed to apply mica: {:?}", e); + } + } + _ => {} + } + } + } + } + self.register_window_events(&window, widget_id); self.open_tx.send(state)?; } From c89ff80429b724683d621be64b405de2ddc9d371 Mon Sep 17 00:00:00 2001 From: Brad Veryard Date: Sun, 27 Oct 2024 17:37:23 +0800 Subject: [PATCH 2/8] fix: Remove mac for now --- packages/desktop/src/widget_factory.rs | 69 ++++++-------------------- 1 file changed, 14 insertions(+), 55 deletions(-) diff --git a/packages/desktop/src/widget_factory.rs b/packages/desktop/src/widget_factory.rs index 61e0056d..afbca01d 100644 --- a/packages/desktop/src/widget_factory.rs +++ b/packages/desktop/src/widget_factory.rs @@ -8,6 +8,7 @@ use std::{ }; use anyhow::Context; +use csscolorparser::Color; use serde::Serialize; use tauri::{ AppHandle, Manager, PhysicalPosition, PhysicalSize, WebviewUrl, @@ -18,7 +19,7 @@ use tokio::{ task, }; use tracing::{error, info}; -use csscolorparser::Color; + use crate::{ common::{PathExt, WindowExt}, config::{ @@ -259,63 +260,19 @@ impl WidgetFactory { widget_states.insert(state.id.clone(), state.clone()); } - if let Some(window_effect) = &widget_config.background_effect { - if *window_effect != BackgroundEffect::None { - let color = if let Some(color_str) = &widget_config.background_effect_color { + #[cfg(target_os = "windows")] + { + if let Some(window_effect) = &widget_config.background_effect { + if *window_effect != BackgroundEffect::None { + let color = if let Some(color_str) = + &widget_config.background_effect_color + { let color = csscolorparser::parse(color_str)?.to_rgba8(); Some((color[3], color[0], color[1], color[2])) - } else { - Some((18, 18, 18, 125)) - }; - #[cfg(target_os = "macos")] - { - use window_vibrancy::{ - apply_vibrancy, NSVisualEffectMaterial, + } else { + Some((18, 18, 18, 125)) }; - if let BackgroundEffect::Vibrancy(material_str) = window_effect - { - let material = match material_str.as_str() { - "appearance-based" => { - NSVisualEffectMaterial::AppearanceBased - } - "light" => NSVisualEffectMaterial::Light, - "dark" => NSVisualEffectMaterial::Dark, - "titlebar" => NSVisualEffectMaterial::Titlebar, - "selection" => NSVisualEffectMaterial::Selection, - "menu" => NSVisualEffectMaterial::Menu, - "popover" => NSVisualEffectMaterial::Popover, - "sidebar" => NSVisualEffectMaterial::Sidebar, - "header-view" => NSVisualEffectMaterial::HeaderView, - "sheet" => NSVisualEffectMaterial::Sheet, - "window-background" => { - NSVisualEffectMaterial::WindowBackground - } - "hud-window" => NSVisualEffectMaterial::HudWindow, - "full-screen-ui" => NSVisualEffectMaterial::FullScreenUi, - "tool-tip" => NSVisualEffectMaterial::ToolTip, - "content-background" => { - NSVisualEffectMaterial::ContentBackground - } - "under-window-background" => { - NSVisualEffectMaterial::UnderWindowBackground - } - "under-page-background" => { - NSVisualEffectMaterial::UnderPageBackground - } - _ => { - error!("Unknown vibrancy material: {}", material_str); - NSVisualEffectMaterial::AppearanceBased - } - }; - if let Err(e) = apply_vibrancy(&window, material, None, None) - { - error!("Failed to apply vibrancy: {:?}", e); - } - } - } - #[cfg(target_os = "windows")] - { use window_vibrancy::{apply_acrylic, apply_blur, apply_mica}; match window_effect { BackgroundEffect::Blur => { @@ -329,7 +286,9 @@ impl WidgetFactory { } } BackgroundEffect::Mica => { - let mica_dark = widget_config.background_effect_mica_dark.unwrap_or(false); + let mica_dark = widget_config + .background_effect_mica_dark + .unwrap_or(false); if let Err(e) = apply_mica(&window, Some(mica_dark)) { error!("Failed to apply mica: {:?}", e); } From 33d21247f578afcefd63fbf2deaa997b5649d52c Mon Sep 17 00:00:00 2001 From: Brad Veryard Date: Sun, 27 Oct 2024 18:01:38 +0800 Subject: [PATCH 3/8] fix: Color order --- packages/desktop/src/widget_factory.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/desktop/src/widget_factory.rs b/packages/desktop/src/widget_factory.rs index afbca01d..e627fe22 100644 --- a/packages/desktop/src/widget_factory.rs +++ b/packages/desktop/src/widget_factory.rs @@ -268,7 +268,7 @@ impl WidgetFactory { &widget_config.background_effect_color { let color = csscolorparser::parse(color_str)?.to_rgba8(); - Some((color[3], color[0], color[1], color[2])) + Some((color[1], color[2], color[3], color[4])) } else { Some((18, 18, 18, 125)) }; From 13007dc83a28ddeeff92e35d99ce97db05abf513 Mon Sep 17 00:00:00 2001 From: Brad Veryard Date: Tue, 5 Nov 2024 19:52:13 +0800 Subject: [PATCH 4/8] fix: Redo config for window vibrancy --- Cargo.lock | 10 --- packages/desktop/Cargo.toml | 3 +- packages/desktop/src/common/mod.rs | 2 + packages/desktop/src/common/parse_rgba.rs | 79 +++++++++++++++++++++++ packages/desktop/src/config.rs | 51 +++++++++++---- packages/desktop/src/widget_factory.rs | 74 +++++++++++---------- 6 files changed, 160 insertions(+), 59 deletions(-) create mode 100644 packages/desktop/src/common/parse_rgba.rs diff --git a/Cargo.lock b/Cargo.lock index 7236143e..89b82e3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -939,15 +939,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "csscolorparser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f9a16a848a7fb95dd47ce387ac1ee9a6df879ba784b815537fcd388a1a8288" -dependencies = [ - "phf 0.11.2", -] - [[package]] name = "cssparser" version = "0.27.2" @@ -6800,7 +6791,6 @@ dependencies = [ "async-trait", "clap", "cocoa 0.25.0", - "csscolorparser", "komorebi-client", "netdev", "regex", diff --git a/packages/desktop/Cargo.toml b/packages/desktop/Cargo.toml index a3819f75..21920b9a 100644 --- a/packages/desktop/Cargo.toml +++ b/packages/desktop/Cargo.toml @@ -36,8 +36,7 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } netdev = "0.24" regex = "1" -window-vibrancy = "0.5.2" -csscolorparser = "0.7.0" +window-vibrancy = "0.5" [target.'cfg(target_os = "windows")'.dependencies] komorebi-client = { git = "https://github.com/LGUG2Z/komorebi", tag = "v0.1.28" } diff --git a/packages/desktop/src/common/mod.rs b/packages/desktop/src/common/mod.rs index 328132b3..9730c135 100644 --- a/packages/desktop/src/common/mod.rs +++ b/packages/desktop/src/common/mod.rs @@ -1,11 +1,13 @@ mod format_bytes; mod fs_util; mod length_value; +mod parse_rgba; mod path_ext; mod window_ext; pub use format_bytes::*; pub use fs_util::*; pub use length_value::*; +pub use parse_rgba::*; pub use path_ext::*; pub use window_ext::*; diff --git a/packages/desktop/src/common/parse_rgba.rs b/packages/desktop/src/common/parse_rgba.rs new file mode 100644 index 00000000..a454030d --- /dev/null +++ b/packages/desktop/src/common/parse_rgba.rs @@ -0,0 +1,79 @@ +#[derive(Debug)] +pub enum ColorError { + InvalidFormat, + InvalidValue, +} + +pub fn parse_rgba( + color_str: &str, +) -> Result<(u8, u8, u8, u8), ColorError> { + let content = color_str + .trim_start_matches("rgba(") + .trim_end_matches(")") + .trim(); + + let parts: Vec<&str> = content.split(',').map(|s| s.trim()).collect(); + + if parts.len() != 4 { + return Err(ColorError::InvalidFormat); + } + + let r = parts[0].parse().map_err(|_| ColorError::InvalidValue)?; + let g = parts[1].parse().map_err(|_| ColorError::InvalidValue)?; + let b = parts[2].parse().map_err(|_| ColorError::InvalidValue)?; + + let a = if parts[3].ends_with('%') { + let percent = parts[3] + .trim_end_matches('%') + .parse::() + .map_err(|_| ColorError::InvalidValue)?; + if percent < 0.0 || percent > 100.0 { + return Err(ColorError::InvalidValue); + } + (percent / 100.0 * 255.0) as u8 + } else { + let alpha = parts[3] + .parse::() + .map_err(|_| ColorError::InvalidValue)?; + if alpha < 0.0 || alpha > 1.0 { + return Err(ColorError::InvalidValue); + } + (alpha * 255.0) as u8 + }; + + Ok((r, g, b, a)) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_rgba() { + // Test valid inputs + assert_eq!( + parse_rgba("rgba(255, 0, 0, 1.0)").unwrap(), + (255, 0, 0, 255) + ); + assert_eq!( + parse_rgba("rgba(255, 0, 0, 0.5)").unwrap(), + (255, 0, 0, 127) + ); + assert_eq!( + parse_rgba("rgba(255, 0, 0, 100%)").unwrap(), + (255, 0, 0, 255) + ); + assert_eq!( + parse_rgba("rgba(255, 0, 0, 50%)").unwrap(), + (255, 0, 0, 127) + ); + + // Test invalid inputs + assert!(parse_rgba("rgb(255, 0, 0)").is_err()); + assert!(parse_rgba("rgba(300, 0, 0, 1.0)").is_err()); + assert!(parse_rgba("rgba(255, 0, 0, 1.5)").is_err()); + assert!(parse_rgba("rgba(255, 0, 0, 101%)").is_err()); + assert!(parse_rgba("rgba(255, 0, 0)").is_err()); + assert!(parse_rgba("rgba(255, 0, 0, invalid)").is_err()); + } +} diff --git a/packages/desktop/src/config.rs b/packages/desktop/src/config.rs index 288676b6..281f6f55 100644 --- a/packages/desktop/src/config.rs +++ b/packages/desktop/src/config.rs @@ -93,12 +93,6 @@ pub struct WidgetConfig { /// Whether the window frame should have an effect pub background_effect: Option, - // Background effect color (Windows 10 v1903+, no effect on Windows 7 or Windows 11) - pub background_effect_color: Option, - - // Background Dark on Mica (Windows only) - pub background_effect_mica_dark: Option, - /// Where to place the widget. Add alias for `defaultPlacements` for /// compatibility with v2.3.0 and earlier. #[serde(alias = "defaultPlacements")] @@ -170,15 +164,44 @@ pub enum MonitorSelection { Name(String), } -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, ValueEnum)] -#[clap(rename_all = "snake_case")] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[serde(rename_all = "snake_case")] +pub struct BackgroundEffect { + pub windows: Option, + pub mac_os: Option, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] #[serde(rename_all = "snake_case")] -pub enum BackgroundEffect { - None, - Blur, // For Windows - Acrylic, // For Windows - Mica, // For Windows - Vibrancy // For macOS; the string represents the material +pub enum WindowsBackgroundEffect { + Blur { color: String }, + Acrylic { color: String }, + Mica { prefer_dark: bool }, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum MacOsBackgroundEffect { + Vibrancy { material: VibrancyMaterial }, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[repr(u64)] +pub enum VibrancyMaterial { + Titlebar = 3, + Selection = 4, + Menu = 5, + Popover = 6, + Sidebar = 7, + HeaderView = 10, + Sheet = 11, + WindowBackground = 12, + HudWindow = 13, + FullScreenUI = 15, + Tooltip = 17, + ContentBackground = 18, + UnderWindowBackground = 21, + UnderPageBackground = 22, } #[derive(Debug)] diff --git a/packages/desktop/src/widget_factory.rs b/packages/desktop/src/widget_factory.rs index e627fe22..0a243221 100644 --- a/packages/desktop/src/widget_factory.rs +++ b/packages/desktop/src/widget_factory.rs @@ -8,7 +8,6 @@ use std::{ }; use anyhow::Context; -use csscolorparser::Color; use serde::Serialize; use tauri::{ AppHandle, Manager, PhysicalPosition, PhysicalSize, WebviewUrl, @@ -19,12 +18,13 @@ use tokio::{ task, }; use tracing::{error, info}; +use window_vibrancy::apply_vibrancy; use crate::{ - common::{PathExt, WindowExt}, + common::{parse_rgba, PathExt, WindowExt}, config::{ - AnchorPoint, BackgroundEffect, Config, WidgetConfig, WidgetPlacement, - ZOrder, + AnchorPoint, Config, MacOsBackgroundEffect, WidgetConfig, + WidgetPlacement, WindowsBackgroundEffect, }, monitor_state::MonitorState, }; @@ -195,8 +195,6 @@ impl WidgetFactory { Self::to_asset_url(&html_path.to_unicode_string()).into(), ); - let window_effect = &widget_config.background_effect; - // Note that window label needs to be globally unique. let window = WebviewWindowBuilder::new( &self.app_handle, @@ -262,38 +260,48 @@ impl WidgetFactory { #[cfg(target_os = "windows")] { - if let Some(window_effect) = &widget_config.background_effect { - if *window_effect != BackgroundEffect::None { - let color = if let Some(color_str) = - &widget_config.background_effect_color - { - let color = csscolorparser::parse(color_str)?.to_rgba8(); - Some((color[1], color[2], color[3], color[4])) - } else { - Some((18, 18, 18, 125)) - }; + use window_vibrancy::{apply_acrylic, apply_blur, apply_mica}; - use window_vibrancy::{apply_acrylic, apply_blur, apply_mica}; - match window_effect { - BackgroundEffect::Blur => { - if let Err(e) = apply_blur(&window, color) { - error!("Failed to apply blur: {:?}", e); + if let Some(window_effect) = &widget_config.background_effect { + if let Some(effect) = &window_effect.windows { + let result = match effect { + WindowsBackgroundEffect::Blur { color } + | WindowsBackgroundEffect::Acrylic { color } => { + let color = + parse_rgba(color).unwrap_or((255, 255, 255, 200)); + match effect { + WindowsBackgroundEffect::Blur { .. } => { + apply_blur(&window, Some(color)) + } + _ => apply_acrylic(&window, Some(color)), } } - BackgroundEffect::Acrylic => { - if let Err(e) = apply_acrylic(&window, color) { - error!("Failed to apply acrylic: {:?}", e); - } + WindowsBackgroundEffect::Mica { prefer_dark } => { + apply_mica(&window, Some(*prefer_dark)) } - BackgroundEffect::Mica => { - let mica_dark = widget_config - .background_effect_mica_dark - .unwrap_or(false); - if let Err(e) = apply_mica(&window, Some(mica_dark)) { - error!("Failed to apply mica: {:?}", e); - } + }; + + if let Err(e) = result { + error!("Failed to apply effect: {:?}", e); + } + } + } + } + + #[cfg(target_os = "macos")] + { + use window_vibrancy::apply_vibrancy; + + if let Some(window_effect) = &widget_config.background_effect { + if let Some(effect) = &window_effect.mac_os { + let result = match effect { + MacOsBackgroundEffect::Vibrancy { material } => { + apply_vibrancy(&window, *material, None, None); } - _ => {} + }; + + if let Err(e) = result { + error!("Failed to apply macos effect: {:?}", e); } } } From dbb7aa47e7e7676d4f13931e40ee540f865578d2 Mon Sep 17 00:00:00 2001 From: Brad Veryard Date: Tue, 5 Nov 2024 20:02:57 +0800 Subject: [PATCH 5/8] fix: macos --- packages/desktop/src/widget_factory.rs | 53 +++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/packages/desktop/src/widget_factory.rs b/packages/desktop/src/widget_factory.rs index 0a243221..363a129d 100644 --- a/packages/desktop/src/widget_factory.rs +++ b/packages/desktop/src/widget_factory.rs @@ -23,8 +23,7 @@ use window_vibrancy::apply_vibrancy; use crate::{ common::{parse_rgba, PathExt, WindowExt}, config::{ - AnchorPoint, Config, MacOsBackgroundEffect, WidgetConfig, - WidgetPlacement, WindowsBackgroundEffect, + AnchorPoint, Config, MacOsBackgroundEffect, VibrancyMaterial, WidgetConfig, WidgetPlacement, WindowsBackgroundEffect, ZOrder }, monitor_state::MonitorState, }; @@ -273,10 +272,14 @@ impl WidgetFactory { WindowsBackgroundEffect::Blur { .. } => { apply_blur(&window, Some(color)) } - _ => apply_acrylic(&window, Some(color)), + _ => { + println!("Applied acrylic"); + apply_acrylic(&window, Some(color)) + } } } WindowsBackgroundEffect::Mica { prefer_dark } => { + println!("Applied mica"); apply_mica(&window, Some(*prefer_dark)) } }; @@ -290,13 +293,53 @@ impl WidgetFactory { #[cfg(target_os = "macos")] { - use window_vibrancy::apply_vibrancy; + use window_vibrancy::{apply_vibrancy, NSVisualEffectMaterial}; if let Some(window_effect) = &widget_config.background_effect { if let Some(effect) = &window_effect.mac_os { let result = match effect { MacOsBackgroundEffect::Vibrancy { material } => { - apply_vibrancy(&window, *material, None, None); + let ns_material = match material { + VibrancyMaterial::Titlebar => { + NSVisualEffectMaterial::Titlebar + } + VibrancyMaterial::Selection => { + NSVisualEffectMaterial::Selection + } + VibrancyMaterial::Menu => NSVisualEffectMaterial::Menu, + VibrancyMaterial::Popover => { + NSVisualEffectMaterial::Popover + } + VibrancyMaterial::Sidebar => { + NSVisualEffectMaterial::Sidebar + } + VibrancyMaterial::HeaderView => { + NSVisualEffectMaterial::HeaderView + } + VibrancyMaterial::Sheet => NSVisualEffectMaterial::Sheet, + VibrancyMaterial::WindowBackground => { + NSVisualEffectMaterial::WindowBackground + } + VibrancyMaterial::HudWindow => { + NSVisualEffectMaterial::HudWindow + } + VibrancyMaterial::FullScreenUI => { + NSVisualEffectMaterial::FullScreenUI + } + VibrancyMaterial::Tooltip => { + NSVisualEffectMaterial::Tooltip + } + VibrancyMaterial::ContentBackground => { + NSVisualEffectMaterial::ContentBackground + } + VibrancyMaterial::UnderWindowBackground => { + NSVisualEffectMaterial::UnderWindowBackground + } + VibrancyMaterial::UnderPageBackground => { + NSVisualEffectMaterial::UnderPageBackground + } + }; + apply_vibrancy(&window, ns_material, None, None) } }; From eafca9eb1762c1cf31c00cd18c496965cf145f0f Mon Sep 17 00:00:00 2001 From: Brad Veryard Date: Tue, 5 Nov 2024 20:28:39 +0800 Subject: [PATCH 6/8] cs: Fix code style --- packages/desktop/src/widget_factory.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/desktop/src/widget_factory.rs b/packages/desktop/src/widget_factory.rs index 363a129d..d3274566 100644 --- a/packages/desktop/src/widget_factory.rs +++ b/packages/desktop/src/widget_factory.rs @@ -23,7 +23,8 @@ use window_vibrancy::apply_vibrancy; use crate::{ common::{parse_rgba, PathExt, WindowExt}, config::{ - AnchorPoint, Config, MacOsBackgroundEffect, VibrancyMaterial, WidgetConfig, WidgetPlacement, WindowsBackgroundEffect, ZOrder + AnchorPoint, Config, MacOsBackgroundEffect, VibrancyMaterial, + WidgetConfig, WidgetPlacement, WindowsBackgroundEffect, ZOrder, }, monitor_state::MonitorState, }; From 0103a3f1ee56af3bf04978cfe7c75028fc252370 Mon Sep 17 00:00:00 2001 From: Brad Veryard Date: Tue, 5 Nov 2024 22:27:40 +0800 Subject: [PATCH 7/8] cs: Remove logs --- packages/desktop/src/widget_factory.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/desktop/src/widget_factory.rs b/packages/desktop/src/widget_factory.rs index d3274566..034f8563 100644 --- a/packages/desktop/src/widget_factory.rs +++ b/packages/desktop/src/widget_factory.rs @@ -273,14 +273,10 @@ impl WidgetFactory { WindowsBackgroundEffect::Blur { .. } => { apply_blur(&window, Some(color)) } - _ => { - println!("Applied acrylic"); - apply_acrylic(&window, Some(color)) - } + _ => apply_acrylic(&window, Some(color)), } } WindowsBackgroundEffect::Mica { prefer_dark } => { - println!("Applied mica"); apply_mica(&window, Some(*prefer_dark)) } }; From 6313c57dea124aa1b9853747fbc6879070fe3b92 Mon Sep 17 00:00:00 2001 From: Lars Berger Date: Wed, 6 Nov 2024 17:20:56 +0800 Subject: [PATCH 8/8] feat: run background effect change on main thread for macos --- packages/desktop/src/config.rs | 30 +++---- packages/desktop/src/widget_factory.rs | 106 ++++++++++++++----------- 2 files changed, 75 insertions(+), 61 deletions(-) diff --git a/packages/desktop/src/config.rs b/packages/desktop/src/config.rs index 281f6f55..0748c99e 100644 --- a/packages/desktop/src/config.rs +++ b/packages/desktop/src/config.rs @@ -186,22 +186,22 @@ pub enum MacOsBackgroundEffect { } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] -#[repr(u64)] +#[serde(rename_all = "snake_case")] pub enum VibrancyMaterial { - Titlebar = 3, - Selection = 4, - Menu = 5, - Popover = 6, - Sidebar = 7, - HeaderView = 10, - Sheet = 11, - WindowBackground = 12, - HudWindow = 13, - FullScreenUI = 15, - Tooltip = 17, - ContentBackground = 18, - UnderWindowBackground = 21, - UnderPageBackground = 22, + Titlebar, + Selection, + Menu, + Popover, + Sidebar, + HeaderView, + Sheet, + WindowBackground, + HudWindow, + FullScreenUI, + Tooltip, + ContentBackground, + UnderWindowBackground, + UnderPageBackground, } #[derive(Debug)] diff --git a/packages/desktop/src/widget_factory.rs b/packages/desktop/src/widget_factory.rs index 034f8563..826fb7c6 100644 --- a/packages/desktop/src/widget_factory.rs +++ b/packages/desktop/src/widget_factory.rs @@ -294,54 +294,68 @@ impl WidgetFactory { if let Some(window_effect) = &widget_config.background_effect { if let Some(effect) = &window_effect.mac_os { - let result = match effect { - MacOsBackgroundEffect::Vibrancy { material } => { - let ns_material = match material { - VibrancyMaterial::Titlebar => { - NSVisualEffectMaterial::Titlebar - } - VibrancyMaterial::Selection => { - NSVisualEffectMaterial::Selection - } - VibrancyMaterial::Menu => NSVisualEffectMaterial::Menu, - VibrancyMaterial::Popover => { - NSVisualEffectMaterial::Popover - } - VibrancyMaterial::Sidebar => { - NSVisualEffectMaterial::Sidebar - } - VibrancyMaterial::HeaderView => { - NSVisualEffectMaterial::HeaderView - } - VibrancyMaterial::Sheet => NSVisualEffectMaterial::Sheet, - VibrancyMaterial::WindowBackground => { - NSVisualEffectMaterial::WindowBackground - } - VibrancyMaterial::HudWindow => { - NSVisualEffectMaterial::HudWindow - } - VibrancyMaterial::FullScreenUI => { - NSVisualEffectMaterial::FullScreenUI + let window = window.clone(); + let effect = effect.clone(); + + let result = + self.app_handle.run_on_main_thread(move || match effect { + MacOsBackgroundEffect::Vibrancy { material } => { + let ns_material = match material { + VibrancyMaterial::Titlebar => { + NSVisualEffectMaterial::Titlebar + } + VibrancyMaterial::Selection => { + NSVisualEffectMaterial::Selection + } + VibrancyMaterial::Menu => NSVisualEffectMaterial::Menu, + VibrancyMaterial::Popover => { + NSVisualEffectMaterial::Popover + } + VibrancyMaterial::Sidebar => { + NSVisualEffectMaterial::Sidebar + } + VibrancyMaterial::HeaderView => { + NSVisualEffectMaterial::HeaderView + } + VibrancyMaterial::Sheet => { + NSVisualEffectMaterial::Sheet + } + VibrancyMaterial::WindowBackground => { + NSVisualEffectMaterial::WindowBackground + } + VibrancyMaterial::HudWindow => { + NSVisualEffectMaterial::HudWindow + } + VibrancyMaterial::FullScreenUI => { + NSVisualEffectMaterial::FullScreenUI + } + VibrancyMaterial::Tooltip => { + NSVisualEffectMaterial::Tooltip + } + VibrancyMaterial::ContentBackground => { + NSVisualEffectMaterial::ContentBackground + } + VibrancyMaterial::UnderWindowBackground => { + NSVisualEffectMaterial::UnderWindowBackground + } + VibrancyMaterial::UnderPageBackground => { + NSVisualEffectMaterial::UnderPageBackground + } + }; + + if let Err(err) = + apply_vibrancy(&window, ns_material, None, None) + { + error!("Failed to apply vibrancy effect: {:?}", err); } - VibrancyMaterial::Tooltip => { - NSVisualEffectMaterial::Tooltip - } - VibrancyMaterial::ContentBackground => { - NSVisualEffectMaterial::ContentBackground - } - VibrancyMaterial::UnderWindowBackground => { - NSVisualEffectMaterial::UnderWindowBackground - } - VibrancyMaterial::UnderPageBackground => { - NSVisualEffectMaterial::UnderPageBackground - } - }; - apply_vibrancy(&window, ns_material, None, None) - } - }; + } + }); - if let Err(e) = result { - error!("Failed to apply macos effect: {:?}", e); + if let Err(err) = result { + error!( + "Unable to change background effect on main thread: {:?}", + err + ); } } }