From 6e7d8fb92261bc90dd998ef27103b38df24652b8 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Fri, 25 Apr 2025 17:53:55 -0700 Subject: [PATCH] fix(animation): avoid redundant async window pos calls As pointed out by @alex-ds13, animations run on a separate thread and so unresponsive apps will not block komorebi. --- komorebi/src/window.rs | 18 ++++++------------ komorebi/src/windows_api.rs | 4 ++-- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/komorebi/src/window.rs b/komorebi/src/window.rs index d64c9c27..58ebe4d1 100644 --- a/komorebi/src/window.rs +++ b/komorebi/src/window.rs @@ -27,7 +27,6 @@ use crate::window_manager_event::WindowManagerEvent; use crate::windows_api; use crate::windows_api::WindowsApi; use crate::AnimationStyle; -use crate::WindowHandlingBehaviour; use crate::FLOATING_APPLICATIONS; use crate::FLOATING_WINDOW_TOGGLE_ASPECT_RATIO; use crate::HIDDEN_HWNDS; @@ -40,7 +39,6 @@ use crate::PERMAIGNORE_CLASSES; use crate::REGEX_IDENTIFIERS; use crate::SLOW_APPLICATION_COMPENSATION_TIME; use crate::SLOW_APPLICATION_IDENTIFIERS; -use crate::WINDOW_HANDLING_BEHAVIOUR; use crate::WSL2_UI_PROCESSES; use color_eyre::eyre; use color_eyre::Result; @@ -205,22 +203,18 @@ impl RenderDispatcher for MovementRenderDispatcher { fn render(&self, progress: f64) -> Result<()> { let new_rect = self.start_rect.lerp(self.target_rect, progress, self.style); - match WINDOW_HANDLING_BEHAVIOUR.load() { - WindowHandlingBehaviour::Sync => { - WindowsApi::move_window(self.hwnd, &new_rect, false)?; - } - WindowHandlingBehaviour::Async => { - // MoveWindow runs faster than SetWindowPos, but it doesn't support async window pos - WindowsApi::position_window(self.hwnd, &new_rect, self.top, true)?; - } - } + // we don't check WINDOW_HANDLING_BEHAVIOUR here because animations + // are always run on a separate thread + WindowsApi::move_window(self.hwnd, &new_rect, false)?; WindowsApi::invalidate_rect(self.hwnd, None, false); Ok(()) } fn post_render(&self) -> Result<()> { - WindowsApi::position_window(self.hwnd, &self.target_rect, self.top, true)?; + // we don't add the async_window_pos flag here because animations + // are always run on a separate thread + WindowsApi::position_window(self.hwnd, &self.target_rect, self.top, false)?; if ANIMATION_MANAGER .lock() .count_in_progress(MovementRenderDispatcher::PREFIX) diff --git a/komorebi/src/windows_api.rs b/komorebi/src/windows_api.rs index 9d19fb8b..27de5285 100644 --- a/komorebi/src/windows_api.rs +++ b/komorebi/src/windows_api.rs @@ -481,7 +481,7 @@ impl WindowsApi { hwnd: isize, layout: &Rect, top: bool, - supports_async: bool, + with_async_window_pos: bool, ) -> Result<()> { let hwnd = HWND(as_ptr!(hwnd)); @@ -497,7 +497,7 @@ impl WindowsApi { // By default SetWindowPos waits for target window's WindowProc thread // to process the message, so we have to use ASYNC_WINDOW_POS to avoid // blocking our thread in case the target window is not responding. - if supports_async + if with_async_window_pos && matches!( WINDOW_HANDLING_BEHAVIOUR.load(), WindowHandlingBehaviour::Async