1#![allow(clippy::deprecated_semver)]
25
26#[cfg(target_os = "windows")]
27use windows_sys::core::HRESULT;
28
29mod macos;
30mod windows;
31
32pub use macos::{NSGlassEffectViewStyle, NSVisualEffectMaterial, NSVisualEffectState};
33
34#[cfg(target_os = "macos")]
35pub use macos::{LiquidGlassOptions, NSGlassEffectViewTagged, NSVisualEffectViewTagged};
36
37pub type Color = (u8, u8, u8, u8);
39
40pub fn apply_blur(
54 window: impl raw_window_handle::HasWindowHandle,
55 #[allow(unused)] color: Option<Color>,
56) -> Result<(), Error> {
57 match window.window_handle()?.as_raw() {
58 #[cfg(target_os = "windows")]
59 raw_window_handle::RawWindowHandle::Win32(handle) => {
60 windows::apply_blur(handle.hwnd.get() as _, color)
61 }
62 _ => Err(Error::UnsupportedPlatform(
63 "\"apply_blur()\" is only supported on Windows.",
64 )),
65 }
66}
67
68pub fn clear_blur(window: impl raw_window_handle::HasWindowHandle) -> Result<(), Error> {
74 match window.window_handle()?.as_raw() {
75 #[cfg(target_os = "windows")]
76 raw_window_handle::RawWindowHandle::Win32(handle) => {
77 windows::clear_blur(handle.hwnd.get() as _)
78 }
79 _ => Err(Error::UnsupportedPlatform(
80 "\"clear_blur()\" is only supported on Windows.",
81 )),
82 }
83}
84
85pub fn apply_acrylic(
99 window: impl raw_window_handle::HasWindowHandle,
100 #[allow(unused)] color: Option<Color>,
101) -> Result<(), Error> {
102 match window.window_handle()?.as_raw() {
103 #[cfg(target_os = "windows")]
104 raw_window_handle::RawWindowHandle::Win32(handle) => {
105 windows::apply_acrylic(handle.hwnd.get() as _, color)
106 }
107 _ => Err(Error::UnsupportedPlatform(
108 "\"apply_acrylic()\" is only supported on Windows.",
109 )),
110 }
111}
112
113pub fn clear_acrylic(window: impl raw_window_handle::HasWindowHandle) -> Result<(), Error> {
119 match window.window_handle()?.as_raw() {
120 #[cfg(target_os = "windows")]
121 raw_window_handle::RawWindowHandle::Win32(handle) => {
122 windows::clear_acrylic(handle.hwnd.get() as _)
123 }
124 _ => Err(Error::UnsupportedPlatform(
125 "\"clear_acrylic()\" is only supported on Windows.",
126 )),
127 }
128}
129
130pub fn apply_mica(
140 window: impl raw_window_handle::HasWindowHandle,
141 dark: Option<bool>,
142) -> Result<(), Error> {
143 #[cfg(not(target_os = "windows"))]
144 let _ = dark;
145 match window.window_handle()?.as_raw() {
146 #[cfg(target_os = "windows")]
147 raw_window_handle::RawWindowHandle::Win32(handle) => {
148 windows::apply_mica(handle.hwnd.get() as _, dark)
149 }
150 _ => Err(Error::UnsupportedPlatform(
151 "\"apply_mica()\" is only supported on Windows.",
152 )),
153 }
154}
155
156pub fn clear_mica(window: impl raw_window_handle::HasWindowHandle) -> Result<(), Error> {
162 match window.window_handle()?.as_raw() {
163 #[cfg(target_os = "windows")]
164 raw_window_handle::RawWindowHandle::Win32(handle) => {
165 windows::clear_mica(handle.hwnd.get() as _)
166 }
167 _ => Err(Error::UnsupportedPlatform(
168 "\"clear_mica()\" is only supported on Windows.",
169 )),
170 }
171}
172
173pub fn apply_tabbed(
183 window: impl raw_window_handle::HasWindowHandle,
184 dark: Option<bool>,
185) -> Result<(), Error> {
186 #[cfg(not(target_os = "windows"))]
187 let _ = dark;
188 match window.window_handle()?.as_raw() {
189 #[cfg(target_os = "windows")]
190 raw_window_handle::RawWindowHandle::Win32(handle) => {
191 windows::apply_tabbed(handle.hwnd.get() as _, dark)
192 }
193 _ => Err(Error::UnsupportedPlatform(
194 "\"apply_tabbed()\" is only supported on Windows.",
195 )),
196 }
197}
198
199pub fn clear_tabbed(window: impl raw_window_handle::HasWindowHandle) -> Result<(), Error> {
205 match window.window_handle()?.as_raw() {
206 #[cfg(target_os = "windows")]
207 raw_window_handle::RawWindowHandle::Win32(handle) => {
208 windows::clear_tabbed(handle.hwnd.get() as _)
209 }
210 _ => Err(Error::UnsupportedPlatform(
211 "\"clear_tabbed()\" is only supported on Windows.",
212 )),
213 }
214}
215
216pub fn apply_vibrancy(
222 window: impl raw_window_handle::HasWindowHandle,
223 #[allow(unused)] effect: NSVisualEffectMaterial,
224 #[allow(unused)] state: Option<NSVisualEffectState>,
225 #[allow(unused)] radius: Option<f64>,
226) -> Result<(), Error> {
227 match window.window_handle()?.as_raw() {
228 #[cfg(target_os = "macos")]
229 raw_window_handle::RawWindowHandle::AppKit(handle) => unsafe {
230 macos::apply_vibrancy(handle.ns_view, effect, state, radius)
231 },
232 _ => Err(Error::UnsupportedPlatform(
233 "\"apply_vibrancy()\" is only supported on macOS.",
234 )),
235 }
236}
237
238pub fn clear_vibrancy(window: impl raw_window_handle::HasWindowHandle) -> Result<bool, Error> {
249 match window.window_handle()?.as_raw() {
250 #[cfg(target_os = "macos")]
251 raw_window_handle::RawWindowHandle::AppKit(handle) => unsafe {
252 macos::clear_vibrancy(handle.ns_view)
253 },
254 _ => Err(Error::UnsupportedPlatform(
255 "\"clear_vibrancy()\" is only supported on macOS.",
256 )),
257 }
258}
259
260#[cfg(target_os = "macos")]
266pub fn apply_liquid_glass(
267 window: impl raw_window_handle::HasWindowHandle,
268 #[allow(unused)] options: LiquidGlassOptions<'_>,
269) -> Result<(), Error> {
270 match window.window_handle()?.as_raw() {
271 #[cfg(target_os = "macos")]
272 raw_window_handle::RawWindowHandle::AppKit(handle) => {
273 use objc2_app_kit::NSView;
274 let view = unsafe { handle.ns_view.cast::<NSView>().as_ref() };
275 macos::apply_liquid_glass(view, options)
276 }
277 _ => Err(Error::UnsupportedPlatform(
278 "\"apply_liquid_glass()\" is only supported on macOS.",
279 )),
280 }
281}
282
283#[cfg(target_os = "macos")]
294pub fn clear_liquid_glass(window: impl raw_window_handle::HasWindowHandle) -> Result<bool, Error> {
295 match window.window_handle()?.as_raw() {
296 #[cfg(target_os = "macos")]
297 raw_window_handle::RawWindowHandle::AppKit(handle) => {
298 use objc2_app_kit::NSView;
299 let view = unsafe { handle.ns_view.cast::<NSView>().as_ref() };
300 macos::clear_liquid_glass(view)
301 }
302 _ => Err(Error::UnsupportedPlatform(
303 "\"clear_liquid_glass()\" is only supported on macOS.",
304 )),
305 }
306}
307
308#[derive(Debug)]
309pub enum Error {
310 UnsupportedPlatform(&'static str),
311 UnsupportedPlatformVersion(&'static str),
312 NotMainThread(&'static str),
313 NoWindowHandle(raw_window_handle::HandleError),
314 #[cfg(target_os = "windows")]
315 Win32Error {
316 api: &'static str,
317 result: HRESULT,
318 },
319}
320
321impl std::fmt::Display for Error {
322 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
323 match self {
324 Error::UnsupportedPlatform(e)
325 | Error::UnsupportedPlatformVersion(e)
326 | Error::NotMainThread(e) => {
327 write!(f, "{}", e)
328 }
329 Error::NoWindowHandle(e) => {
330 write!(f, "{}", e)
331 }
332 #[cfg(target_os = "windows")]
333 Error::Win32Error { api, result } => {
334 write!(
335 f,
336 "Win32 API {api}() returned the error result 0x{:x}.",
337 result,
338 )
339 }
340 }
341 }
342}
343
344impl std::error::Error for Error {}
345
346impl From<raw_window_handle::HandleError> for Error {
347 fn from(err: raw_window_handle::HandleError) -> Self {
348 Error::NoWindowHandle(err)
349 }
350}