Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-renderer/src/windowing/winit/windows/window_attribute.rs
StratoSDK / crates / strato-ui-renderer / src / windowing / winit / windows / window_attribute.rs
1use std::{ffi::c_void, mem::size_of};
2use thiserror::Error;
3use wgpu::rwh;
4use windows::Win32::Foundation::HWND;
5use windows::Win32::Graphics::Dwm::{self, DWMWINDOWATTRIBUTE};
6use winit::raw_window_handle::HasWindowHandle;
7use winit::raw_window_handle::RawWindowHandle;
8use winit::window::Window as WinitWindow;
9 
10#[derive(Debug, Error)]
11pub enum WindowAttributeErr {
12 #[error(transparent)]
13 HandleError(#[from] rwh::HandleError),
14 #[error(transparent)]
15 Win32Error(#[from] windows::core::Error),
16}
17 
18/// Uses the `windows` crate to fetch a specific window attribute.
19/// First, we translate the Winit window object to a native Windows HWND handle.
20/// Then, we invoke the Device Window Manager (DWM)'s `DwmGetWindowAttribute`
21/// function for the attribute in question.
22pub fn get_window_attribute<T>(
23 window: &WinitWindow,
24 attribute_name: DWMWINDOWATTRIBUTE,
25) -> Result<T, WindowAttributeErr>
26where
27 T: Default,
28{
29 let hwnd_handle = to_hwnd(window)?;
30 let mut result_destination: T = T::default();
31 let window_attribute_result = unsafe {
32 let result_address = core::ptr::addr_of_mut!(result_destination);
33 Dwm::DwmGetWindowAttribute(
34 hwnd_handle,
35 attribute_name,
36 result_address as *mut c_void,
37 size_of::<T>().try_into().unwrap(),
38 )
39 };
40 Ok(window_attribute_result.map(|_| result_destination)?)
41}
42 
43/// Uses the `windows` crate to set a specific window attribute.
44/// First, we translate the Winit window object to a native Windows HWND handle.
45/// Then, we invoke the Device Window Manager (DWM)'s `DwmSetWindowAttribute`
46/// function for the attribute in question.
47pub fn set_window_attribute<T>(
48 window: &WinitWindow,
49 attribute_name: DWMWINDOWATTRIBUTE,
50 value: T,
51) -> Result<(), WindowAttributeErr> {
52 let hwnd_handle = to_hwnd(window)?;
53 let window_attribute_result = unsafe {
54 Dwm::DwmSetWindowAttribute(
55 hwnd_handle,
56 attribute_name,
57 core::ptr::addr_of!(value) as *const c_void,
58 size_of::<T>().try_into().unwrap(),
59 )
60 };
61 Ok(window_attribute_result?)
62}
63 
64fn to_hwnd(window: &WinitWindow) -> Result<HWND, rwh::HandleError> {
65 window
66 .window_handle()
67 .and_then(|handle| match handle.as_raw() {
68 RawWindowHandle::Win32(handle) => Ok(handle),
69 _ => Err(rwh::HandleError::NotSupported),
70 })
71 .map(|handle| HWND(handle.hwnd.get() as *mut c_void))
72}
73