From dc3ffb3bcbf36d7f748840119a46c3486a2ed662 Mon Sep 17 00:00:00 2001 From: James Tucker Date: Wed, 14 Feb 2024 01:10:27 -0800 Subject: [PATCH] fix(komorebi): restore borders, no more DWM border on border window This fixes a regression from an earlier commit that dropped the DWM style borders without fixing corner rounding on Windows 11. This is now fixed for Windows 11 again, while avoiding the extra system border decorations. --- komorebi/src/border.rs | 13 ++++++++----- komorebi/src/windows_api.rs | 7 +++---- komorebi/src/windows_callbacks.rs | 17 +++++++++++++++-- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/komorebi/src/border.rs b/komorebi/src/border.rs index 9b687772..36ee4eba 100644 --- a/komorebi/src/border.rs +++ b/komorebi/src/border.rs @@ -17,8 +17,8 @@ use crate::WindowsApi; use crate::BORDER_HWND; use crate::BORDER_OFFSET; use crate::BORDER_RECT; +use crate::BORDER_WIDTH; use crate::TRANSPARENCY_COLOUR; -use crate::WINDOWS_11; #[derive(Debug, Clone, Copy)] pub struct Border { @@ -75,10 +75,6 @@ impl Border { BORDER_HWND.store(hwnd.0, Ordering::SeqCst); - if *WINDOWS_11 { - WindowsApi::round_corners(hwnd.0)?; - } - Ok(()) } @@ -112,6 +108,13 @@ impl Border { rect.bottom += border_offset.bottom; } + let border_width = BORDER_WIDTH.load(Ordering::SeqCst); + + rect.left -= border_width; + rect.top -= border_width; + rect.right += border_width * 2; + rect.bottom += border_width * 2; + *BORDER_RECT.lock() = rect; WindowsApi::position_border_window(self.hwnd(), &rect, activate) diff --git a/komorebi/src/windows_api.rs b/komorebi/src/windows_api.rs index 925fc72f..d7770946 100644 --- a/komorebi/src/windows_api.rs +++ b/komorebi/src/windows_api.rs @@ -129,8 +129,7 @@ use windows::Win32::UI::WindowsAndMessaging::WS_DISABLED; use windows::Win32::UI::WindowsAndMessaging::WS_EX_LAYERED; use windows::Win32::UI::WindowsAndMessaging::WS_EX_NOACTIVATE; use windows::Win32::UI::WindowsAndMessaging::WS_EX_TOOLWINDOW; -use windows::Win32::UI::WindowsAndMessaging::WS_MAXIMIZEBOX; -use windows::Win32::UI::WindowsAndMessaging::WS_MINIMIZEBOX; +use windows::Win32::UI::WindowsAndMessaging::WS_EX_TOPMOST; use windows::Win32::UI::WindowsAndMessaging::WS_POPUP; use windows::Win32::UI::WindowsAndMessaging::WS_SYSMENU; @@ -858,10 +857,10 @@ impl WindowsApi { pub fn create_border_window(name: PCWSTR, instance: HMODULE) -> Result { unsafe { let hwnd = CreateWindowExW( - WS_EX_TOOLWINDOW | WS_EX_LAYERED, + WS_EX_TOOLWINDOW | WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_NOACTIVATE, name, name, - WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX, + WS_POPUP | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, diff --git a/komorebi/src/windows_callbacks.rs b/komorebi/src/windows_callbacks.rs index 3fc734be..242632f7 100644 --- a/komorebi/src/windows_callbacks.rs +++ b/komorebi/src/windows_callbacks.rs @@ -13,11 +13,13 @@ use windows::Win32::Graphics::Gdi::BeginPaint; use windows::Win32::Graphics::Gdi::CreatePen; use windows::Win32::Graphics::Gdi::EndPaint; use windows::Win32::Graphics::Gdi::Rectangle; +use windows::Win32::Graphics::Gdi::RoundRect; use windows::Win32::Graphics::Gdi::SelectObject; use windows::Win32::Graphics::Gdi::ValidateRect; use windows::Win32::Graphics::Gdi::HDC; use windows::Win32::Graphics::Gdi::HMONITOR; use windows::Win32::Graphics::Gdi::PAINTSTRUCT; +use windows::Win32::Graphics::Gdi::PS_INSIDEFRAME; use windows::Win32::Graphics::Gdi::PS_SOLID; use windows::Win32::UI::Accessibility::HWINEVENTHOOK; use windows::Win32::UI::WindowsAndMessaging::DefWindowProcW; @@ -44,6 +46,7 @@ use crate::BORDER_WIDTH; use crate::DISPLAY_INDEX_PREFERENCES; use crate::MONITOR_INDEX_PREFERENCES; use crate::TRANSPARENCY_COLOUR; +use crate::WINDOWS_11; pub extern "system" fn valid_display_monitors( hmonitor: HMONITOR, @@ -211,7 +214,7 @@ pub extern "system" fn border_window( let mut ps = PAINTSTRUCT::default(); let hdc = BeginPaint(window, &mut ps); let hpen = CreatePen( - PS_SOLID, + PS_SOLID | PS_INSIDEFRAME, BORDER_WIDTH.load(Ordering::SeqCst), COLORREF(BORDER_COLOUR_CURRENT.load(Ordering::SeqCst)), ); @@ -219,7 +222,17 @@ pub extern "system" fn border_window( SelectObject(hdc, hpen); SelectObject(hdc, hbrush); - Rectangle(hdc, 0, 0, border_rect.right, border_rect.bottom); + // TODO(raggi): this is approximately the correct curvature for + // the top left of a Windows 11 window (DWMWCP_DEFAULT), but + // often the bottom right has a different shape. Furthermore if + // the window was made with DWMWCP_ROUNDSMALL then this is the + // wrong size. In the future we should read the DWM properties + // of windows and attempt to match appropriately. + if *WINDOWS_11 { + RoundRect(hdc, 0, 0, border_rect.right, border_rect.bottom, 14, 14); + } else { + Rectangle(hdc, 0, 0, border_rect.right, border_rect.bottom); + } EndPaint(window, &ps); ValidateRect(window, None);