window_shadows/
lib.rs

1// Copyright 2020-2022 Tauri Programme within The Commons Conservancy
2// SPDX-License-Identifier: Apache-2.0
3// SPDX-License-Identifier: MIT
4
5//! Add native shadows to your windows.
6//!
7//! ## Platform-specific
8//!
9//! - **Windows**: On Windows 11, the window will also have rounded corners.
10//! - **macOS**: Shadows are always disabled for transparent windows.
11//! - **Linux**: Unsupported, Shadows are controlled by the compositor installed on the end-user system.
12//!
13//! # Example
14//!
15//! ```no_run
16//! use window_shadows::set_shadow;
17//!
18//! # let window: &dyn raw_window_handle::HasRawWindowHandle = unsafe { std::mem::zeroed() };
19//! #[cfg(any(windows, target_os = "macos"))]
20//! set_shadow(&window, true).unwrap();
21//! ```
22
23/// Enables or disables the shadows for a window.
24///
25/// ## Platform-specific
26///
27/// - **Windows**: On Windows 11, the window will also have rounded corners.
28/// - **macOS**: Shadows are always disabled for transparent windows.
29/// - **Linux**: Unsupported, Shadows are controlled by the compositor installed on the end-user system.
30pub fn set_shadow(
31    window: impl raw_window_handle::HasRawWindowHandle,
32    enable: bool,
33) -> Result<(), Error> {
34    match window.raw_window_handle() {
35        #[cfg(target_os = "macos")]
36        raw_window_handle::RawWindowHandle::AppKit(handle) => {
37            use cocoa::{appkit::NSWindow, base::id};
38            use objc::runtime::{NO, YES};
39
40            unsafe {
41                (handle.ns_window as id).setHasShadow_(if enable { YES } else { NO });
42            }
43
44            Ok(())
45        }
46        #[cfg(target_os = "windows")]
47        raw_window_handle::RawWindowHandle::Win32(handle) => {
48            use windows_sys::Win32::{
49                Graphics::Dwm::DwmExtendFrameIntoClientArea, UI::Controls::MARGINS,
50            };
51
52            let m = if enable { 1 } else { 0 };
53            let margins = MARGINS {
54                cxLeftWidth: m,
55                cxRightWidth: m,
56                cyTopHeight: m,
57                cyBottomHeight: m,
58            };
59            unsafe {
60                DwmExtendFrameIntoClientArea(handle.hwnd as _, &margins);
61            };
62            Ok(())
63        }
64        _ => Err(Error::UnsupportedPlatform),
65    }
66}
67
68#[derive(Debug)]
69pub enum Error {
70    UnsupportedPlatform,
71}
72
73impl std::fmt::Display for Error {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        write!(f, "\"set_shadow()\" is only supported on Windows and macOS")
76    }
77}