mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-03-25 19:01:19 +01:00
fix(animation): extend cancelling system to support multiple cancel call
This commit fixes cross-monitor drag move by extending cancelling system. Now each cancel call have its own idx. And only latest cancel will continue animation. Others will be dropped.
This commit is contained in:
@@ -416,12 +416,15 @@ impl Animation {
|
||||
pub fn new(hwnd: isize) -> Self {
|
||||
Self { hwnd }
|
||||
}
|
||||
pub fn cancel(&mut self) {
|
||||
|
||||
/// Returns true if the animation needs to continue
|
||||
pub fn cancel(&mut self) -> bool {
|
||||
if !ANIMATION_MANAGER.lock().in_progress(self.hwnd) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
ANIMATION_MANAGER.lock().cancel(self.hwnd);
|
||||
// should be more than 0
|
||||
let cancel_idx = ANIMATION_MANAGER.lock().init_cancel(self.hwnd);
|
||||
let max_duration = Duration::from_secs(1);
|
||||
let spent_duration = Instant::now();
|
||||
|
||||
@@ -434,6 +437,10 @@ impl Animation {
|
||||
ANIMATION_DURATION.load(Ordering::SeqCst) / 2,
|
||||
));
|
||||
}
|
||||
|
||||
let latest_cancel_idx = ANIMATION_MANAGER.lock().end_cancel(self.hwnd);
|
||||
|
||||
return latest_cancel_idx == cancel_idx;
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
@@ -460,7 +467,11 @@ impl Animation {
|
||||
mut render_callback: impl FnMut(f64) -> Result<()>,
|
||||
) -> Result<()> {
|
||||
if ANIMATION_MANAGER.lock().in_progress(self.hwnd) {
|
||||
self.cancel();
|
||||
let should_animate = self.cancel();
|
||||
|
||||
if !should_animate {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
ANIMATION_MANAGER.lock().start(self.hwnd);
|
||||
@@ -474,8 +485,7 @@ impl Animation {
|
||||
// check if animation is cancelled
|
||||
if ANIMATION_MANAGER.lock().is_cancelled(self.hwnd) {
|
||||
// cancel animation
|
||||
// set all flags
|
||||
ANIMATION_MANAGER.lock().end(self.hwnd);
|
||||
ANIMATION_MANAGER.lock().cancel(self.hwnd);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -485,8 +495,10 @@ impl Animation {
|
||||
render_callback(progress).ok();
|
||||
|
||||
// sleep until next frame
|
||||
if frame_start.elapsed() < target_frame_time {
|
||||
std::thread::sleep(target_frame_time - frame_start.elapsed());
|
||||
let frame_time_elapsed = frame_start.elapsed();
|
||||
|
||||
if frame_time_elapsed < target_frame_time {
|
||||
std::thread::sleep(target_frame_time - frame_time_elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ pub static ANIMATIONS_IN_PROGRESS: AtomicUsize = AtomicUsize::new(0);
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct AnimationState {
|
||||
pub in_progress: bool,
|
||||
pub is_cancelled: bool,
|
||||
pub cancelled_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -31,7 +31,7 @@ impl AnimationManager {
|
||||
|
||||
pub fn is_cancelled(&self, hwnd: isize) -> bool {
|
||||
if let Some(animation_state) = self.animations.get(&hwnd) {
|
||||
animation_state.is_cancelled
|
||||
animation_state.cancelled_count > 0
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -45,9 +45,29 @@ impl AnimationManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_cancel(&mut self, hwnd: isize) -> usize {
|
||||
if let Some(animation_state) = self.animations.get_mut(&hwnd) {
|
||||
animation_state.cancelled_count += 1;
|
||||
animation_state.cancelled_count
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn end_cancel(&mut self, hwnd: isize) -> usize {
|
||||
if let Some(animation_state) = self.animations.get_mut(&hwnd) {
|
||||
let cancelled_count = animation_state.cancelled_count;
|
||||
animation_state.cancelled_count -= 1;
|
||||
|
||||
return cancelled_count;
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cancel(&mut self, hwnd: isize) {
|
||||
if let Some(animation_state) = self.animations.get_mut(&hwnd) {
|
||||
animation_state.is_cancelled = true;
|
||||
animation_state.in_progress = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +75,7 @@ impl AnimationManager {
|
||||
if let Entry::Vacant(e) = self.animations.entry(hwnd) {
|
||||
e.insert(AnimationState {
|
||||
in_progress: true,
|
||||
is_cancelled: false,
|
||||
cancelled_count: 0,
|
||||
});
|
||||
|
||||
ANIMATIONS_IN_PROGRESS.store(self.animations.len(), Ordering::Release);
|
||||
@@ -70,10 +90,11 @@ impl AnimationManager {
|
||||
pub fn end(&mut self, hwnd: isize) {
|
||||
if let Some(animation_state) = self.animations.get_mut(&hwnd) {
|
||||
animation_state.in_progress = false;
|
||||
animation_state.is_cancelled = false;
|
||||
|
||||
self.animations.remove(&hwnd);
|
||||
ANIMATIONS_IN_PROGRESS.store(self.animations.len(), Ordering::Release);
|
||||
if animation_state.cancelled_count == 0 {
|
||||
self.animations.remove(&hwnd);
|
||||
ANIMATIONS_IN_PROGRESS.store(self.animations.len(), Ordering::Release);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user