Skip to content

Commit a8715ab

Browse files
committed
fix: Redo config for window vibrancy
1 parent 33d2124 commit a8715ab

File tree

6 files changed

+160
-57
lines changed

6 files changed

+160
-57
lines changed

Cargo.lock

Lines changed: 0 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/desktop/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ tracing = "0.1"
3636
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
3737
netdev = "0.24"
3838
regex = "1"
39-
window-vibrancy = "0.5.2"
40-
csscolorparser = "0.7.0"
39+
window-vibrancy = "0.5"
4140

4241
[target.'cfg(target_os = "windows")'.dependencies]
4342
komorebi-client = { git = "https://github.com/LGUG2Z/komorebi", tag = "v0.1.28" }

packages/desktop/src/common/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
mod format_bytes;
22
mod fs_util;
33
mod length_value;
4+
mod parse_rgba;
45
mod path_ext;
56
mod window_ext;
67

78
pub use format_bytes::*;
89
pub use fs_util::*;
910
pub use length_value::*;
11+
pub use parse_rgba::*;
1012
pub use path_ext::*;
1113
pub use window_ext::*;
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#[derive(Debug)]
2+
pub enum ColorError {
3+
InvalidFormat,
4+
InvalidValue,
5+
}
6+
7+
pub fn parse_rgba(
8+
color_str: &str,
9+
) -> Result<(u8, u8, u8, u8), ColorError> {
10+
let content = color_str
11+
.trim_start_matches("rgba(")
12+
.trim_end_matches(")")
13+
.trim();
14+
15+
let parts: Vec<&str> = content.split(',').map(|s| s.trim()).collect();
16+
17+
if parts.len() != 4 {
18+
return Err(ColorError::InvalidFormat);
19+
}
20+
21+
let r = parts[0].parse().map_err(|_| ColorError::InvalidValue)?;
22+
let g = parts[1].parse().map_err(|_| ColorError::InvalidValue)?;
23+
let b = parts[2].parse().map_err(|_| ColorError::InvalidValue)?;
24+
25+
let a = if parts[3].ends_with('%') {
26+
let percent = parts[3]
27+
.trim_end_matches('%')
28+
.parse::<f32>()
29+
.map_err(|_| ColorError::InvalidValue)?;
30+
if percent < 0.0 || percent > 100.0 {
31+
return Err(ColorError::InvalidValue);
32+
}
33+
(percent / 100.0 * 255.0) as u8
34+
} else {
35+
let alpha = parts[3]
36+
.parse::<f32>()
37+
.map_err(|_| ColorError::InvalidValue)?;
38+
if alpha < 0.0 || alpha > 1.0 {
39+
return Err(ColorError::InvalidValue);
40+
}
41+
(alpha * 255.0) as u8
42+
};
43+
44+
Ok((r, g, b, a))
45+
}
46+
47+
#[cfg(test)]
48+
mod tests {
49+
use super::*;
50+
51+
#[test]
52+
fn test_parse_rgba() {
53+
// Test valid inputs
54+
assert_eq!(
55+
parse_rgba("rgba(255, 0, 0, 1.0)").unwrap(),
56+
(255, 0, 0, 255)
57+
);
58+
assert_eq!(
59+
parse_rgba("rgba(255, 0, 0, 0.5)").unwrap(),
60+
(255, 0, 0, 127)
61+
);
62+
assert_eq!(
63+
parse_rgba("rgba(255, 0, 0, 100%)").unwrap(),
64+
(255, 0, 0, 255)
65+
);
66+
assert_eq!(
67+
parse_rgba("rgba(255, 0, 0, 50%)").unwrap(),
68+
(255, 0, 0, 127)
69+
);
70+
71+
// Test invalid inputs
72+
assert!(parse_rgba("rgb(255, 0, 0)").is_err());
73+
assert!(parse_rgba("rgba(300, 0, 0, 1.0)").is_err());
74+
assert!(parse_rgba("rgba(255, 0, 0, 1.5)").is_err());
75+
assert!(parse_rgba("rgba(255, 0, 0, 101%)").is_err());
76+
assert!(parse_rgba("rgba(255, 0, 0)").is_err());
77+
assert!(parse_rgba("rgba(255, 0, 0, invalid)").is_err());
78+
}
79+
}

packages/desktop/src/config.rs

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,6 @@ pub struct WidgetConfig {
9393
/// Whether the window frame should have an effect
9494
pub background_effect: Option<BackgroundEffect>,
9595

96-
// Background effect color (Windows 10 v1903+, no effect on Windows 7 or Windows 11)
97-
pub background_effect_color: Option<String>,
98-
99-
// Background Dark on Mica (Windows only)
100-
pub background_effect_mica_dark: Option<bool>,
101-
10296
/// Where to place the widget. Add alias for `defaultPlacements` for
10397
/// compatibility with v2.3.0 and earlier.
10498
#[serde(alias = "defaultPlacements")]
@@ -170,15 +164,44 @@ pub enum MonitorSelection {
170164
Name(String),
171165
}
172166

173-
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, ValueEnum)]
174-
#[clap(rename_all = "snake_case")]
167+
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
168+
#[serde(rename_all = "snake_case")]
169+
pub struct BackgroundEffect {
170+
pub windows: Option<WindowsBackgroundEffect>,
171+
pub mac_os: Option<MacOsBackgroundEffect>,
172+
}
173+
174+
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
175175
#[serde(rename_all = "snake_case")]
176-
pub enum BackgroundEffect {
177-
None,
178-
Blur, // For Windows
179-
Acrylic, // For Windows
180-
Mica, // For Windows
181-
Vibrancy // For macOS; the string represents the material
176+
pub enum WindowsBackgroundEffect {
177+
Blur { color: String },
178+
Acrylic { color: String },
179+
Mica { prefer_dark: bool },
180+
}
181+
182+
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
183+
#[serde(rename_all = "snake_case")]
184+
pub enum MacOsBackgroundEffect {
185+
Vibrancy { material: VibrancyMaterial },
186+
}
187+
188+
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
189+
#[repr(u64)]
190+
pub enum VibrancyMaterial {
191+
Titlebar = 3,
192+
Selection = 4,
193+
Menu = 5,
194+
Popover = 6,
195+
Sidebar = 7,
196+
HeaderView = 10,
197+
Sheet = 11,
198+
WindowBackground = 12,
199+
HudWindow = 13,
200+
FullScreenUI = 15,
201+
Tooltip = 17,
202+
ContentBackground = 18,
203+
UnderWindowBackground = 21,
204+
UnderPageBackground = 22,
182205
}
183206

184207
#[derive(Debug)]

packages/desktop/src/widget_factory.rs

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use std::{
88
};
99

1010
use anyhow::Context;
11-
use csscolorparser::Color;
1211
use serde::Serialize;
1312
use tauri::{
1413
AppHandle, Manager, PhysicalPosition, PhysicalSize, WebviewUrl,
@@ -19,12 +18,13 @@ use tokio::{
1918
task,
2019
};
2120
use tracing::{error, info};
21+
use window_vibrancy::apply_vibrancy;
2222

2323
use crate::{
24-
common::{PathExt, WindowExt},
24+
common::{parse_rgba, PathExt, WindowExt},
2525
config::{
26-
AnchorPoint, BackgroundEffect, Config, WidgetConfig, WidgetPlacement,
27-
ZOrder,
26+
AnchorPoint, Config, MacOsBackgroundEffect, WidgetConfig,
27+
WidgetPlacement, WindowsBackgroundEffect,
2828
},
2929
monitor_state::MonitorState,
3030
};
@@ -262,38 +262,48 @@ impl WidgetFactory {
262262

263263
#[cfg(target_os = "windows")]
264264
{
265-
if let Some(window_effect) = &widget_config.background_effect {
266-
if *window_effect != BackgroundEffect::None {
267-
let color = if let Some(color_str) =
268-
&widget_config.background_effect_color
269-
{
270-
let color = csscolorparser::parse(color_str)?.to_rgba8();
271-
Some((color[1], color[2], color[3], color[4]))
272-
} else {
273-
Some((18, 18, 18, 125))
274-
};
265+
use window_vibrancy::{apply_acrylic, apply_blur, apply_mica};
275266

276-
use window_vibrancy::{apply_acrylic, apply_blur, apply_mica};
277-
match window_effect {
278-
BackgroundEffect::Blur => {
279-
if let Err(e) = apply_blur(&window, color) {
280-
error!("Failed to apply blur: {:?}", e);
267+
if let Some(window_effect) = &widget_config.background_effect {
268+
if let Some(effect) = &window_effect.windows {
269+
let result = match effect {
270+
WindowsBackgroundEffect::Blur { color }
271+
| WindowsBackgroundEffect::Acrylic { color } => {
272+
let color =
273+
parse_rgba(color).unwrap_or((255, 255, 255, 200));
274+
match effect {
275+
WindowsBackgroundEffect::Blur { .. } => {
276+
apply_blur(&window, Some(color))
277+
}
278+
_ => apply_acrylic(&window, Some(color)),
281279
}
282280
}
283-
BackgroundEffect::Acrylic => {
284-
if let Err(e) = apply_acrylic(&window, color) {
285-
error!("Failed to apply acrylic: {:?}", e);
286-
}
281+
WindowsBackgroundEffect::Mica { prefer_dark } => {
282+
apply_mica(&window, Some(*prefer_dark))
287283
}
288-
BackgroundEffect::Mica => {
289-
let mica_dark = widget_config
290-
.background_effect_mica_dark
291-
.unwrap_or(false);
292-
if let Err(e) = apply_mica(&window, Some(mica_dark)) {
293-
error!("Failed to apply mica: {:?}", e);
294-
}
284+
};
285+
286+
if let Err(e) = result {
287+
error!("Failed to apply effect: {:?}", e);
288+
}
289+
}
290+
}
291+
}
292+
293+
#[cfg(target_os = "macos")]
294+
{
295+
use window_vibrancy::apply_vibrancy;
296+
297+
if let Some(window_effect) = &widget_config.background_effect {
298+
if let Some(effect) = &window_effect.mac_os {
299+
let result = match effect {
300+
MacOsBackgroundEffect::Vibrancy { material } => {
301+
apply_vibrancy(&window, *material, None, None);
295302
}
296-
_ => {}
303+
};
304+
305+
if let Err(e) = result {
306+
error!("Failed to apply macos effect: {:?}", e);
297307
}
298308
}
299309
}

0 commit comments

Comments
 (0)