mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-05-17 09:17:02 +02:00
fix(borders): always validate border client area
This commit pushes up the calls to BeginPaint and EndPaint in the border callback function to ensure that the client area of the border rect is always validated after calls to InvalidateRect from the update fn. The callback now also logs errors whenever it is not possible to get the border rect to operate on for any reason. There was a call at the end of this logic to ValidateRect which has been removed as the validation is already handled by the call to BeginPaint. re #862
This commit is contained in:
@@ -32,7 +32,6 @@ use windows::Win32::Graphics::Gdi::InvalidateRect;
|
|||||||
use windows::Win32::Graphics::Gdi::Rectangle;
|
use windows::Win32::Graphics::Gdi::Rectangle;
|
||||||
use windows::Win32::Graphics::Gdi::RoundRect;
|
use windows::Win32::Graphics::Gdi::RoundRect;
|
||||||
use windows::Win32::Graphics::Gdi::SelectObject;
|
use windows::Win32::Graphics::Gdi::SelectObject;
|
||||||
use windows::Win32::Graphics::Gdi::ValidateRect;
|
|
||||||
use windows::Win32::Graphics::Gdi::PAINTSTRUCT;
|
use windows::Win32::Graphics::Gdi::PAINTSTRUCT;
|
||||||
use windows::Win32::Graphics::Gdi::PS_INSIDEFRAME;
|
use windows::Win32::Graphics::Gdi::PS_INSIDEFRAME;
|
||||||
use windows::Win32::Graphics::Gdi::PS_SOLID;
|
use windows::Win32::Graphics::Gdi::PS_SOLID;
|
||||||
@@ -150,63 +149,68 @@ impl Border {
|
|||||||
unsafe {
|
unsafe {
|
||||||
match message {
|
match message {
|
||||||
WM_PAINT => {
|
WM_PAINT => {
|
||||||
|
let mut ps = PAINTSTRUCT::default();
|
||||||
|
let hdc = BeginPaint(window, &mut ps);
|
||||||
|
|
||||||
// With the rect that we set in Self::update
|
// With the rect that we set in Self::update
|
||||||
if let Ok(rect) = WindowsApi::window_rect(window) {
|
match WindowsApi::window_rect(window) {
|
||||||
// Grab the focus kind for this border
|
Ok(rect) => {
|
||||||
let focus_kind = {
|
// Grab the focus kind for this border
|
||||||
FOCUS_STATE
|
let focus_kind = {
|
||||||
.lock()
|
FOCUS_STATE
|
||||||
.get(&window.0)
|
.lock()
|
||||||
.copied()
|
.get(&window.0)
|
||||||
.unwrap_or(WindowKind::Unfocused)
|
.copied()
|
||||||
};
|
.unwrap_or(WindowKind::Unfocused)
|
||||||
|
};
|
||||||
|
|
||||||
// Set up the brush to draw the border
|
// Set up the brush to draw the border
|
||||||
let mut ps = PAINTSTRUCT::default();
|
let hpen = CreatePen(
|
||||||
let hdc = BeginPaint(window, &mut ps);
|
PS_SOLID | PS_INSIDEFRAME,
|
||||||
let hpen = CreatePen(
|
BORDER_WIDTH.load(Ordering::SeqCst),
|
||||||
PS_SOLID | PS_INSIDEFRAME,
|
COLORREF(match focus_kind {
|
||||||
BORDER_WIDTH.load(Ordering::SeqCst),
|
WindowKind::Unfocused => UNFOCUSED.load(Ordering::SeqCst),
|
||||||
COLORREF(match focus_kind {
|
WindowKind::Single => FOCUSED.load(Ordering::SeqCst),
|
||||||
WindowKind::Unfocused => UNFOCUSED.load(Ordering::SeqCst),
|
WindowKind::Stack => STACK.load(Ordering::SeqCst),
|
||||||
WindowKind::Single => FOCUSED.load(Ordering::SeqCst),
|
WindowKind::Monocle => MONOCLE.load(Ordering::SeqCst),
|
||||||
WindowKind::Stack => STACK.load(Ordering::SeqCst),
|
}),
|
||||||
WindowKind::Monocle => MONOCLE.load(Ordering::SeqCst),
|
);
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
let hbrush = WindowsApi::create_solid_brush(0);
|
let hbrush = WindowsApi::create_solid_brush(0);
|
||||||
|
|
||||||
// Draw the border
|
// Draw the border
|
||||||
SelectObject(hdc, hpen);
|
SelectObject(hdc, hpen);
|
||||||
SelectObject(hdc, hbrush);
|
SelectObject(hdc, hbrush);
|
||||||
// TODO(raggi): this is approximately the correct curvature for
|
// TODO(raggi): this is approximately the correct curvature for
|
||||||
// the top left of a Windows 11 window (DWMWCP_DEFAULT), but
|
// the top left of a Windows 11 window (DWMWCP_DEFAULT), but
|
||||||
// often the bottom right has a different shape. Furthermore if
|
// often the bottom right has a different shape. Furthermore if
|
||||||
// the window was made with DWMWCP_ROUNDSMALL then this is the
|
// the window was made with DWMWCP_ROUNDSMALL then this is the
|
||||||
// wrong size. In the future we should read the DWM properties
|
// wrong size. In the future we should read the DWM properties
|
||||||
// of windows and attempt to match appropriately.
|
// of windows and attempt to match appropriately.
|
||||||
match STYLE.load() {
|
match STYLE.load() {
|
||||||
BorderStyle::System => {
|
BorderStyle::System => {
|
||||||
if *WINDOWS_11 {
|
if *WINDOWS_11 {
|
||||||
|
RoundRect(hdc, 0, 0, rect.right, rect.bottom, 20, 20);
|
||||||
|
} else {
|
||||||
|
Rectangle(hdc, 0, 0, rect.right, rect.bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BorderStyle::Rounded => {
|
||||||
RoundRect(hdc, 0, 0, rect.right, rect.bottom, 20, 20);
|
RoundRect(hdc, 0, 0, rect.right, rect.bottom, 20, 20);
|
||||||
} else {
|
}
|
||||||
|
BorderStyle::Square => {
|
||||||
Rectangle(hdc, 0, 0, rect.right, rect.bottom);
|
Rectangle(hdc, 0, 0, rect.right, rect.bottom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BorderStyle::Rounded => {
|
DeleteObject(hpen);
|
||||||
RoundRect(hdc, 0, 0, rect.right, rect.bottom, 20, 20);
|
DeleteObject(hbrush);
|
||||||
}
|
}
|
||||||
BorderStyle::Square => {
|
Err(error) => {
|
||||||
Rectangle(hdc, 0, 0, rect.right, rect.bottom);
|
tracing::error!("could not get border rect: {}", error.to_string())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EndPaint(window, &ps);
|
|
||||||
DeleteObject(hpen);
|
|
||||||
DeleteObject(hbrush);
|
|
||||||
ValidateRect(window, None);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EndPaint(window, &ps);
|
||||||
LRESULT(0)
|
LRESULT(0)
|
||||||
}
|
}
|
||||||
WM_DESTROY => {
|
WM_DESTROY => {
|
||||||
|
|||||||
@@ -155,10 +155,8 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle the retile edge case
|
// handle the retile edge case
|
||||||
if !should_process_notification {
|
if !should_process_notification && BORDER_STATE.lock().is_empty() {
|
||||||
if BORDER_STATE.lock().is_empty() {
|
should_process_notification = true;
|
||||||
should_process_notification = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !should_process_notification {
|
if !should_process_notification {
|
||||||
|
|||||||
Reference in New Issue
Block a user