perf(borders): selectively invalidate border rects

This commit ensures that we only invalidate a border rect to send a
WM_PAINT message either when the position of the focus state of the
border has changed.

re #862
This commit is contained in:
LGUG2Z
2024-06-12 08:16:32 -07:00
parent d2d6484e38
commit 3d518f73ca
3 changed files with 37 additions and 18 deletions

View File

@@ -232,7 +232,16 @@ pub enum BorderStyle {
}
#[derive(
Copy, Clone, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, JsonSchema,
Copy,
Clone,
Debug,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
PartialEq,
)]
pub enum WindowKind {
Single,

View File

@@ -119,7 +119,7 @@ impl Border {
WindowsApi::close_window(self.hwnd())
}
pub fn update(&self, rect: &Rect) -> color_eyre::Result<()> {
pub fn update(&self, rect: &Rect, mut should_invalidate: bool) -> color_eyre::Result<()> {
// Make adjustments to the border
let mut rect = *rect;
rect.add_margin(BORDER_WIDTH.load(Ordering::SeqCst));
@@ -128,10 +128,13 @@ impl Border {
// Update the position of the border if required
if !WindowsApi::window_rect(self.hwnd())?.eq(&rect) {
WindowsApi::set_border_pos(self.hwnd(), &rect, HWND((Z_ORDER.load()).into()))?;
should_invalidate = true;
}
// Invalidate the rect to trigger the callback to update colours etc.
self.invalidate();
if should_invalidate {
self.invalidate();
}
Ok(())
}

View File

@@ -236,7 +236,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
monocle.focused_window().copied().unwrap_or_default().hwnd(),
)?;
border.update(&rect)?;
border.update(&rect, true)?;
let border_hwnd = border.hwnd;
let mut to_remove = vec![];
@@ -325,7 +325,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
if rect != new_rect {
rect = new_rect;
border.update(&rect)?;
border.update(&rect, true)?;
}
}
@@ -348,28 +348,35 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
borders_monitors.insert(c.id().clone(), monitor_idx);
#[allow(unused_assignments)]
let mut last_focus_state = None;
let new_focus_state = if idx != ws.focused_container_idx()
|| monitor_idx != focused_monitor_idx
{
WindowKind::Unfocused
} else if c.windows().len() > 1 {
WindowKind::Stack
} else {
WindowKind::Single
};
// Update the focused state for all containers on this workspace
{
let mut focus_state = FOCUS_STATE.lock();
focus_state.insert(
border.hwnd,
if idx != ws.focused_container_idx()
|| monitor_idx != focused_monitor_idx
{
WindowKind::Unfocused
} else if c.windows().len() > 1 {
WindowKind::Stack
} else {
WindowKind::Single
},
);
last_focus_state = focus_state.insert(border.hwnd, new_focus_state);
}
let rect = WindowsApi::window_rect(
c.focused_window().copied().unwrap_or_default().hwnd(),
)?;
border.update(&rect)?;
let should_invalidate = match last_focus_state {
None => true,
Some(last_focus_state) => last_focus_state != new_focus_state,
};
border.update(&rect, should_invalidate)?;
}
}
}