diff --git a/komorebi-core/src/rect.rs b/komorebi-core/src/rect.rs index 01ea0960..5248ab86 100644 --- a/komorebi-core/src/rect.rs +++ b/komorebi-core/src/rect.rs @@ -43,4 +43,14 @@ impl Rect { && point.1 >= self.top && point.1 <= self.top + self.bottom } + + #[must_use] + pub const fn scale(&self, system_dpi: i32, rect_dpi: i32) -> Rect { + Rect { + left: (self.left * rect_dpi) / system_dpi, + top: (self.top * rect_dpi) / system_dpi, + right: (self.right * rect_dpi) / system_dpi, + bottom: (self.bottom * rect_dpi) / system_dpi, + } + } } diff --git a/komorebi/src/windows_api.rs b/komorebi/src/windows_api.rs index 114be56a..925fc72f 100644 --- a/komorebi/src/windows_api.rs +++ b/komorebi/src/windows_api.rs @@ -22,6 +22,7 @@ use windows::Win32::Foundation::WPARAM; use windows::Win32::Graphics::Dwm::DwmGetWindowAttribute; use windows::Win32::Graphics::Dwm::DwmSetWindowAttribute; use windows::Win32::Graphics::Dwm::DWMWA_CLOAKED; +use windows::Win32::Graphics::Dwm::DWMWA_EXTENDED_FRAME_BOUNDS; use windows::Win32::Graphics::Dwm::DWMWA_WINDOW_CORNER_PREFERENCE; use windows::Win32::Graphics::Dwm::DWMWCP_ROUND; use windows::Win32::Graphics::Dwm::DWMWINDOWATTRIBUTE; @@ -53,6 +54,8 @@ use windows::Win32::System::Threading::PROCESS_ACCESS_RIGHTS; use windows::Win32::System::Threading::PROCESS_NAME_WIN32; use windows::Win32::System::Threading::PROCESS_QUERY_INFORMATION; use windows::Win32::UI::HiDpi::GetDpiForMonitor; +use windows::Win32::UI::HiDpi::GetDpiForSystem; +use windows::Win32::UI::HiDpi::GetDpiForWindow; use windows::Win32::UI::HiDpi::SetProcessDpiAwarenessContext; use windows::Win32::UI::HiDpi::DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2; use windows::Win32::UI::HiDpi::MDT_EFFECTIVE_DPI; @@ -471,9 +474,15 @@ impl WindowsApi { pub fn window_rect(hwnd: HWND) -> Result { let mut rect = unsafe { std::mem::zeroed() }; - unsafe { GetWindowRect(hwnd, &mut rect) }.process()?; - Ok(Rect::from(rect)) + if Self::dwm_get_window_attribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &mut rect).is_ok() { + let window_scale = unsafe { GetDpiForWindow(hwnd) }; + let system_scale = unsafe { GetDpiForSystem() }; + Ok(Rect::from(rect).scale(system_scale.try_into()?, window_scale.try_into()?)) + } else { + unsafe { GetWindowRect(hwnd, &mut rect) }.process()?; + Ok(Rect::from(rect)) + } } fn set_cursor_pos(x: i32, y: i32) -> Result<()> {