fix(animations): fix border updates + apply lints

This commit fixes an issue where the active window border would not
properly update when animations were enabled. Various clippy lints have
also been addressed, but I still need to look into the infinite loop
lint that has been marked with a todo comment.
This commit is contained in:
LGUG2Z
2023-11-24 18:04:04 -08:00
parent 95df970860
commit 50b12431fa
5 changed files with 70 additions and 47 deletions
+30 -29
View File
@@ -174,7 +174,7 @@ pub struct EaseOutExpo;
impl Ease for EaseOutExpo { impl Ease for EaseOutExpo {
fn evaluate(t: f64) -> f64 { fn evaluate(t: f64) -> f64 {
if t == 1.0 { if (t - 1.0).abs() < f64::EPSILON {
return t; return t;
} }
@@ -186,7 +186,7 @@ pub struct EaseInOutExpo;
impl Ease for EaseInOutExpo { impl Ease for EaseInOutExpo {
fn evaluate(t: f64) -> f64 { fn evaluate(t: f64) -> f64 {
if t == 0.0 || t == 1.0 { if t == 0.0 || (t - 1.0).abs() < f64::EPSILON {
return t; return t;
} }
@@ -275,7 +275,7 @@ pub struct EaseInElastic;
impl Ease for EaseInElastic { impl Ease for EaseInElastic {
fn evaluate(t: f64) -> f64 { fn evaluate(t: f64) -> f64 {
if t == 1.0 || t == 0.0 { if (t - 1.0).abs() < f64::EPSILON || t == 0.0 {
return t; return t;
} }
@@ -289,7 +289,7 @@ pub struct EaseOutElastic;
impl Ease for EaseOutElastic { impl Ease for EaseOutElastic {
fn evaluate(t: f64) -> f64 { fn evaluate(t: f64) -> f64 {
if t == 1.0 || t == 0.0 { if (t - 1.0).abs() < f64::EPSILON || t == 0.0 {
return t; return t;
} }
@@ -305,7 +305,7 @@ pub struct EaseInOutElastic;
impl Ease for EaseInOutElastic { impl Ease for EaseInOutElastic {
fn evaluate(t: f64) -> f64 { fn evaluate(t: f64) -> f64 {
if t == 1.0 || t == 0.0 { if (t - 1.0).abs() < f64::EPSILON || t == 0.0 {
return t; return t;
} }
@@ -399,7 +399,7 @@ fn apply_ease_func(t: f64) -> f64 {
} }
} }
#[derive(Debug, Clone, Copy, JsonSchema)] #[derive(Debug, Default, Clone, Copy, JsonSchema)]
pub struct Animation { pub struct Animation {
// is_cancel: AtomicBool, // is_cancel: AtomicBool,
// pub in_progress: AtomicBool, // pub in_progress: AtomicBool,
@@ -407,36 +407,37 @@ pub struct Animation {
pub in_progress: bool, pub in_progress: bool,
} }
impl Default for Animation { // impl Default for Animation {
fn default() -> Self { // fn default() -> Self {
Animation { // Animation {
// I'm not sure if this is the right way to do it // // I'm not sure if this is the right way to do it
// I've tried to use Arc<Mutex<bool>> but it dooes not implement Copy trait // // I've tried to use Arc<Mutex<bool>> but it dooes not implement Copy trait
// and I dont want to rewrite everything cause I'm not experienced with rust // // and I dont want to rewrite everything cause I'm not experienced with rust
// Down here you can see the idea I've tried to achive like in any other OOP language // // Down here you can see the idea I've tried to achive like in any other OOP language
// My thought is that in order to prevent Google Chrome breaking render window // // My thought is that in order to prevent Google Chrome breaking render window
// I need to cancel animation if user starting new window movement. So window stops // // I need to cancel animation if user starting new window movement. So window stops
// moving at one point and then fires new animation. // // moving at one point and then fires new animation.
// But my approach does not work because of rust borrowing rules and wired pointers // // But my approach does not work because of rust borrowing rules and wired pointers
// lifetime annotation that I dont know how to use. // // lifetime annotation that I dont know how to use.
is_cancel: false, // is_cancel: false,
in_progress: false, // in_progress: false,
// is_cancel: AtomicBool::new(false), // // is_cancel: AtomicBool::new(false),
// in_progress: AtomicBool::new(false), // // in_progress: AtomicBool::new(false),
} // }
} // }
} // }
impl Animation { impl Animation {
pub fn cancel(&mut self) -> Result<()> { pub fn cancel(&mut self) {
if !self.in_progress { if !self.in_progress {
return Ok(()); return;
} }
self.is_cancel = true; self.is_cancel = true;
let max_duration = Duration::from_secs(1); let max_duration = Duration::from_secs(1);
let spent_duration = Instant::now(); let spent_duration = Instant::now();
// TODO: Come back to this clippy lint
while self.in_progress { while self.in_progress {
if spent_duration.elapsed() >= max_duration { if spent_duration.elapsed() >= max_duration {
break; break;
@@ -444,10 +445,9 @@ impl Animation {
std::thread::sleep(Duration::from_millis(16)); std::thread::sleep(Duration::from_millis(16));
} }
Ok(())
} }
#[allow(clippy::cast_possible_truncation)]
pub fn lerp(x: i32, new_x: i32, t: f64) -> i32 { pub fn lerp(x: i32, new_x: i32, t: f64) -> i32 {
let time = apply_ease_func(t); let time = apply_ease_func(t);
f64::from(new_x - x).mul_add(time, f64::from(x)) as i32 f64::from(new_x - x).mul_add(time, f64::from(x)) as i32
@@ -462,6 +462,7 @@ impl Animation {
} }
} }
#[allow(clippy::cast_precision_loss)]
pub fn animate( pub fn animate(
&mut self, &mut self,
duration: Duration, duration: Duration,
+4 -2
View File
@@ -515,7 +515,8 @@ impl WindowManager {
WindowManagerEvent::DisplayChange(..) WindowManagerEvent::DisplayChange(..)
| WindowManagerEvent::MouseCapture(..) | WindowManagerEvent::MouseCapture(..)
| WindowManagerEvent::Cloak(..) | WindowManagerEvent::Cloak(..)
| WindowManagerEvent::Uncloak(..) => {} | WindowManagerEvent::Uncloak(..)
| WindowManagerEvent::SetFocusedBorderWindow(..) => {}
}; };
if *self.focused_workspace()?.tile() && BORDER_ENABLED.load(Ordering::SeqCst) { if *self.focused_workspace()?.tile() && BORDER_ENABLED.load(Ordering::SeqCst) {
@@ -529,7 +530,8 @@ impl WindowManager {
| WindowManagerEvent::Show(_, window) | WindowManagerEvent::Show(_, window)
| WindowManagerEvent::FocusChange(_, window) | WindowManagerEvent::FocusChange(_, window)
| WindowManagerEvent::Hide(_, window) | WindowManagerEvent::Hide(_, window)
| WindowManagerEvent::Minimize(_, window) => { | WindowManagerEvent::Minimize(_, window)
| WindowManagerEvent::SetFocusedBorderWindow(window) => {
let border = Border::from(BORDER_HWND.load(Ordering::SeqCst)); let border = Border::from(BORDER_HWND.load(Ordering::SeqCst));
let mut target_window = None; let mut target_window = None;
let mut target_window_is_monocle = false; let mut target_window_is_monocle = false;
+20 -15
View File
@@ -1,4 +1,5 @@
use crate::com::SetCloak; use crate::com::SetCloak;
use crate::winevent_listener::WINEVENT_CALLBACK_CHANNEL;
use crate::ANIMATE_DURATION; use crate::ANIMATE_DURATION;
use crate::ANIMATE_ENABLED; use crate::ANIMATE_ENABLED;
use std::collections::HashMap; use std::collections::HashMap;
@@ -110,7 +111,7 @@ impl Serialize for Window {
impl Window { impl Window {
// for instantiation of animation struct // for instantiation of animation struct
pub fn new(hwnd: isize) -> Self { pub fn new(hwnd: isize) -> Self {
Window { Self {
hwnd, hwnd,
animation: Animation::default(), animation: Animation::default(),
} }
@@ -149,19 +150,23 @@ impl Window {
let target_rect = *layout; let target_rect = *layout;
let duration = Duration::from_millis(ANIMATE_DURATION.load(Ordering::SeqCst)); let duration = Duration::from_millis(ANIMATE_DURATION.load(Ordering::SeqCst));
let mut animation = self.animation; let mut animation = self.animation;
let self_copied = *self;
std::thread::spawn(move || { std::thread::spawn(move || {
animation animation.animate(duration, |progress: f64| {
.animate(duration, |progress: f64| { let new_rect = Animation::lerp_rect(&curr_rect, &target_rect, progress);
let new_rect = Animation::lerp_rect(&curr_rect, &target_rect, progress); if progress < 1.0 {
if progress < 1.0 { // using MoveWindow because it runs faster than SetWindowPos
// using MoveWindow because it runs faster than SetWindowPos // so animation have more fps and feel smoother
// so animation have more fps and feel smoother WindowsApi::move_window(hwnd, &new_rect, true)
WindowsApi::move_window(hwnd, &new_rect, true) } else {
} else { WindowsApi::position_window(hwnd, &new_rect, top)?;
WindowsApi::position_window(hwnd, &new_rect, top) Ok(WINEVENT_CALLBACK_CHANNEL
} .lock()
}) .0
.unwrap(); .send(WindowManagerEvent::SetFocusedBorderWindow(self_copied))?)
}
})
}); });
Ok(()) Ok(())
@@ -202,8 +207,8 @@ impl Window {
if ANIMATE_ENABLED.load(Ordering::SeqCst) { if ANIMATE_ENABLED.load(Ordering::SeqCst) {
// check if animation is in progress // check if animation is in progress
if self.animation.in_progress { if self.animation.in_progress {
// wait for cancle animation // wait for cancel animation
self.animation.cancel().unwrap(); self.animation.cancel();
} }
self.animate_position(&rect, top) self.animate_position(&rect, top)
+6 -1
View File
@@ -27,6 +27,7 @@ pub enum WindowManagerEvent {
Unmanage(Window), Unmanage(Window),
Raise(Window), Raise(Window),
DisplayChange(Window), DisplayChange(Window),
SetFocusedBorderWindow(Window),
} }
impl Display for WindowManagerEvent { impl Display for WindowManagerEvent {
@@ -77,6 +78,9 @@ impl Display for WindowManagerEvent {
Self::DisplayChange(window) => { Self::DisplayChange(window) => {
write!(f, "DisplayChange (Window: {window})") write!(f, "DisplayChange (Window: {window})")
} }
Self::SetFocusedBorderWindow(window) => {
write!(f, "SetFocusedBorderWindow (Window: {window})")
}
} }
} }
} }
@@ -97,7 +101,8 @@ impl WindowManagerEvent {
| Self::Raise(window) | Self::Raise(window)
| Self::Manage(window) | Self::Manage(window)
| Self::DisplayChange(window) | Self::DisplayChange(window)
| Self::Unmanage(window) => window, | Self::Unmanage(window)
| Self::SetFocusedBorderWindow(window) => window,
} }
} }
+10
View File
@@ -19,11 +19,15 @@ use komorebi_core::Layout;
use komorebi_core::OperationDirection; use komorebi_core::OperationDirection;
use komorebi_core::Rect; use komorebi_core::Rect;
use crate::border::Border;
use crate::container::Container; use crate::container::Container;
use crate::ring::Ring; use crate::ring::Ring;
use crate::static_config::WorkspaceConfig; use crate::static_config::WorkspaceConfig;
use crate::window::Window; use crate::window::Window;
use crate::windows_api::WindowsApi; use crate::windows_api::WindowsApi;
use crate::ANIMATE_ENABLED;
use crate::BORDER_HIDDEN;
use crate::BORDER_HWND;
use crate::DEFAULT_CONTAINER_PADDING; use crate::DEFAULT_CONTAINER_PADDING;
use crate::DEFAULT_WORKSPACE_PADDING; use crate::DEFAULT_WORKSPACE_PADDING;
use crate::INITIAL_CONFIGURATION_LOADED; use crate::INITIAL_CONFIGURATION_LOADED;
@@ -276,6 +280,12 @@ impl Workspace {
window.add_title_bar()?; window.add_title_bar()?;
} }
if ANIMATE_ENABLED.load(Ordering::SeqCst) {
let border = Border::from(BORDER_HWND.load(Ordering::SeqCst));
border.hide()?;
BORDER_HIDDEN.store(true, Ordering::SeqCst);
}
window.set_position(layout, invisible_borders, false)?; window.set_position(layout, invisible_borders, false)?;
} }
} }