Skip to content

Commit

Permalink
perf(borders): selectively invalidate border rects
Browse files Browse the repository at this point in the history
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
  • Loading branch information
LGUG2Z committed Jun 12, 2024
1 parent d2d6484 commit 3d518f7
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 18 deletions.
11 changes: 10 additions & 1 deletion komorebi-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 5 additions & 2 deletions komorebi/src/border_manager/border.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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(())
}
Expand Down
37 changes: 22 additions & 15 deletions komorebi/src/border_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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![];
Expand Down Expand Up @@ -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)?;
}
}

Expand All @@ -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)?;
}
}
}
Expand Down

0 comments on commit 3d518f7

Please sign in to comment.