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

View File

@@ -174,7 +174,7 @@ pub struct EaseOutExpo;
impl Ease for EaseOutExpo {
fn evaluate(t: f64) -> f64 {
if t == 1.0 {
if (t - 1.0).abs() < f64::EPSILON {
return t;
}
@@ -186,7 +186,7 @@ pub struct EaseInOutExpo;
impl Ease for EaseInOutExpo {
fn evaluate(t: f64) -> f64 {
if t == 0.0 || t == 1.0 {
if t == 0.0 || (t - 1.0).abs() < f64::EPSILON {
return t;
}
@@ -275,7 +275,7 @@ pub struct EaseInElastic;
impl Ease for EaseInElastic {
fn evaluate(t: f64) -> f64 {
if t == 1.0 || t == 0.0 {
if (t - 1.0).abs() < f64::EPSILON || t == 0.0 {
return t;
}
@@ -289,7 +289,7 @@ pub struct EaseOutElastic;
impl Ease for EaseOutElastic {
fn evaluate(t: f64) -> f64 {
if t == 1.0 || t == 0.0 {
if (t - 1.0).abs() < f64::EPSILON || t == 0.0 {
return t;
}
@@ -305,7 +305,7 @@ pub struct EaseInOutElastic;
impl Ease for EaseInOutElastic {
fn evaluate(t: f64) -> f64 {
if t == 1.0 || t == 0.0 {
if (t - 1.0).abs() < f64::EPSILON || t == 0.0 {
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 {
// is_cancel: AtomicBool,
// pub in_progress: AtomicBool,
@@ -407,36 +407,37 @@ pub struct Animation {
pub in_progress: bool,
}
impl Default for Animation {
fn default() -> Self {
Animation {
// 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
// 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
// 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
// moving at one point and then fires new animation.
// But my approach does not work because of rust borrowing rules and wired pointers
// lifetime annotation that I dont know how to use.
is_cancel: false,
in_progress: false,
// is_cancel: AtomicBool::new(false),
// in_progress: AtomicBool::new(false),
}
}
}
// impl Default for Animation {
// fn default() -> Self {
// Animation {
// // 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
// // 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
// // 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
// // moving at one point and then fires new animation.
// // But my approach does not work because of rust borrowing rules and wired pointers
// // lifetime annotation that I dont know how to use.
// is_cancel: false,
// in_progress: false,
// // is_cancel: AtomicBool::new(false),
// // in_progress: AtomicBool::new(false),
// }
// }
// }
impl Animation {
pub fn cancel(&mut self) -> Result<()> {
pub fn cancel(&mut self) {
if !self.in_progress {
return Ok(());
return;
}
self.is_cancel = true;
let max_duration = Duration::from_secs(1);
let spent_duration = Instant::now();
// TODO: Come back to this clippy lint
while self.in_progress {
if spent_duration.elapsed() >= max_duration {
break;
@@ -444,10 +445,9 @@ impl Animation {
std::thread::sleep(Duration::from_millis(16));
}
Ok(())
}
#[allow(clippy::cast_possible_truncation)]
pub fn lerp(x: i32, new_x: i32, t: f64) -> i32 {
let time = apply_ease_func(t);
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(
&mut self,
duration: Duration,

View File

@@ -515,7 +515,8 @@ impl WindowManager {
WindowManagerEvent::DisplayChange(..)
| WindowManagerEvent::MouseCapture(..)
| WindowManagerEvent::Cloak(..)
| WindowManagerEvent::Uncloak(..) => {}
| WindowManagerEvent::Uncloak(..)
| WindowManagerEvent::SetFocusedBorderWindow(..) => {}
};
if *self.focused_workspace()?.tile() && BORDER_ENABLED.load(Ordering::SeqCst) {
@@ -529,7 +530,8 @@ impl WindowManager {
| WindowManagerEvent::Show(_, window)
| WindowManagerEvent::FocusChange(_, window)
| WindowManagerEvent::Hide(_, window)
| WindowManagerEvent::Minimize(_, window) => {
| WindowManagerEvent::Minimize(_, window)
| WindowManagerEvent::SetFocusedBorderWindow(window) => {
let border = Border::from(BORDER_HWND.load(Ordering::SeqCst));
let mut target_window = None;
let mut target_window_is_monocle = false;

View File

@@ -1,4 +1,5 @@
use crate::com::SetCloak;
use crate::winevent_listener::WINEVENT_CALLBACK_CHANNEL;
use crate::ANIMATE_DURATION;
use crate::ANIMATE_ENABLED;
use std::collections::HashMap;
@@ -110,7 +111,7 @@ impl Serialize for Window {
impl Window {
// for instantiation of animation struct
pub fn new(hwnd: isize) -> Self {
Window {
Self {
hwnd,
animation: Animation::default(),
}
@@ -149,19 +150,23 @@ impl Window {
let target_rect = *layout;
let duration = Duration::from_millis(ANIMATE_DURATION.load(Ordering::SeqCst));
let mut animation = self.animation;
let self_copied = *self;
std::thread::spawn(move || {
animation
.animate(duration, |progress: f64| {
let new_rect = Animation::lerp_rect(&curr_rect, &target_rect, progress);
if progress < 1.0 {
// using MoveWindow because it runs faster than SetWindowPos
// so animation have more fps and feel smoother
WindowsApi::move_window(hwnd, &new_rect, true)
} else {
WindowsApi::position_window(hwnd, &new_rect, top)
}
})
.unwrap();
animation.animate(duration, |progress: f64| {
let new_rect = Animation::lerp_rect(&curr_rect, &target_rect, progress);
if progress < 1.0 {
// using MoveWindow because it runs faster than SetWindowPos
// so animation have more fps and feel smoother
WindowsApi::move_window(hwnd, &new_rect, true)
} else {
WindowsApi::position_window(hwnd, &new_rect, top)?;
Ok(WINEVENT_CALLBACK_CHANNEL
.lock()
.0
.send(WindowManagerEvent::SetFocusedBorderWindow(self_copied))?)
}
})
});
Ok(())
@@ -202,8 +207,8 @@ impl Window {
if ANIMATE_ENABLED.load(Ordering::SeqCst) {
// check if animation is in progress
if self.animation.in_progress {
// wait for cancle animation
self.animation.cancel().unwrap();
// wait for cancel animation
self.animation.cancel();
}
self.animate_position(&rect, top)

View File

@@ -27,6 +27,7 @@ pub enum WindowManagerEvent {
Unmanage(Window),
Raise(Window),
DisplayChange(Window),
SetFocusedBorderWindow(Window),
}
impl Display for WindowManagerEvent {
@@ -77,6 +78,9 @@ impl Display for WindowManagerEvent {
Self::DisplayChange(window) => {
write!(f, "DisplayChange (Window: {window})")
}
Self::SetFocusedBorderWindow(window) => {
write!(f, "SetFocusedBorderWindow (Window: {window})")
}
}
}
}
@@ -97,7 +101,8 @@ impl WindowManagerEvent {
| Self::Raise(window)
| Self::Manage(window)
| Self::DisplayChange(window)
| Self::Unmanage(window) => window,
| Self::Unmanage(window)
| Self::SetFocusedBorderWindow(window) => window,
}
}

View File

@@ -19,11 +19,15 @@ use komorebi_core::Layout;
use komorebi_core::OperationDirection;
use komorebi_core::Rect;
use crate::border::Border;
use crate::container::Container;
use crate::ring::Ring;
use crate::static_config::WorkspaceConfig;
use crate::window::Window;
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_WORKSPACE_PADDING;
use crate::INITIAL_CONFIGURATION_LOADED;
@@ -276,6 +280,12 @@ impl Workspace {
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)?;
}
}