komorebi{,-core}: use window bounds without shadow

Switch to using the DWM API to get Window bounds so as to exclude the
outside of window decorations from the computation.

This is getting close to a precise window size, you can now set an
active border width of 1 and an offset of 1 and get a 1 pixel line
around most windows, except that there's some extra top padding I have
yet to find the cause of.

This implementation needs to be DPI aware, but I haven't yet tested if
the DPI scaling approach is entirely valid - we may instead need to get
the per-monitor DPI scale, identify the monitor the window is on, and
scale to that, rather than using the system wide scale.

Maybe fixes #574
Maybe updates #622
This commit is contained in:
James Tucker
2024-01-04 22:34:30 -08:00
committed by جاد
parent fd57d32bb5
commit 344e6ad2fd
2 changed files with 21 additions and 2 deletions

View File

@@ -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,
}
}
}

View File

@@ -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<Rect> {
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<()> {