diff --git a/src/shell/layout/tiling/blocker.rs b/src/shell/layout/tiling/blocker.rs index badbd075..decb933f 100644 --- a/src/shell/layout/tiling/blocker.rs +++ b/src/shell/layout/tiling/blocker.rs @@ -9,25 +9,18 @@ use smithay::{ }; use std::{ collections::HashMap, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, time::{Duration, Instant}, }; #[derive(Debug, Clone)] pub struct TilingBlocker { pub necessary_acks: Vec<(CosmicSurface, Serial)>, - ready: Arc, - signaled: Arc, start: Instant, } impl Blocker for TilingBlocker { fn state(&self) -> BlockerState { - self.signaled.store(true, Ordering::SeqCst); - if self.ready.load(Ordering::SeqCst) { + if self.is_ready() { BlockerState::Released } else { BlockerState::Pending @@ -39,8 +32,6 @@ impl TilingBlocker { pub fn new(configures: impl IntoIterator) -> Self { TilingBlocker { necessary_acks: configures.into_iter().collect(), - ready: Arc::new(AtomicBool::new(false)), - signaled: Arc::new(AtomicBool::new(false)), start: Instant::now(), } } @@ -53,14 +44,15 @@ impl TilingBlocker { .all(|(surf, serial)| !surf.alive() || surf.serial_acked(serial)) } - pub fn is_signaled(&self) -> bool { - self.signaled.load(Ordering::SeqCst) - || !self.necessary_acks.iter().any(|(surf, _)| surf.alive()) + pub fn is_processed(&self) -> bool { + Instant::now().duration_since(self.start) >= Duration::from_millis(500) + || self + .necessary_acks + .iter() + .all(|(surf, serial)| !surf.alive() || surf.serial_past(serial)) } - #[must_use] - pub fn signal_ready(&self) -> HashMap { - self.ready.swap(true, Ordering::SeqCst); + pub fn clients(&self) -> HashMap { self.necessary_acks .iter() .flat_map(|(surface, _)| surface.wl_surface().and_then(|s| s.client())) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index ec315195..e3b8fdb2 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -130,7 +130,6 @@ impl TreeQueue { pub struct TilingLayout { output: Output, queue: TreeQueue, - pending_blockers: Vec, placeholder_id: Id, swapping_stack_surface_id: Id, last_overview_hover: Option<(Option, TargetZone)>, @@ -353,7 +352,6 @@ impl TilingLayout { animation_start: None, }, output: output.clone(), - pending_blockers: Vec::new(), placeholder_id: Id::new(), swapping_stack_surface_id: Id::new(), last_overview_hover: None, @@ -2345,8 +2343,20 @@ impl TilingLayout { pub fn update_animation_state(&mut self) -> HashMap { let mut clients = HashMap::new(); - for blocker in self.pending_blockers.drain(..) { - clients.extend(blocker.signal_ready()); + let mut ready_trees = 0; + for (_, _, blocker) in self.queue.trees.iter().skip(1) { + if let Some(blocker) = blocker.as_ref() { + if blocker.is_processed() { + ready_trees += 1; + } + if blocker.is_ready() { + clients.extend(blocker.clients()); + continue; + } + break; + } else { + ready_trees += 1; + } } if let Some(start) = self.queue.animation_start { @@ -2361,6 +2371,7 @@ impl TilingLayout { { let _ = self.queue.animation_start.take(); let _ = self.queue.trees.pop_front(); + ready_trees -= 1; let front = self.queue.trees.front_mut().unwrap(); if let Some(root_id) = front.0.root_node_id() { for node in front @@ -2383,28 +2394,12 @@ impl TilingLayout { } } - let ready_trees = self - .queue - .trees - .iter() - .skip(1) - .take_while(|(_, _, blocker)| { - blocker - .as_ref() - .map(|blocker| blocker.is_ready() && blocker.is_signaled()) - .unwrap_or(true) - }) - .count(); - // merge let other_duration = if ready_trees > 1 { self.queue .trees .drain(1..ready_trees) - .fold(None, |res, (_, duration, blocker)| { - if let Some(blocker) = blocker { - clients.extend(blocker.signal_ready()); - } + .fold(None, |res, (_, duration, _)| { Some( res.map(|old_duration: Duration| old_duration.max(duration)) .unwrap_or(duration), @@ -2416,13 +2411,10 @@ impl TilingLayout { // start if ready_trees > 0 { - let (_, duration, blocker) = self.queue.trees.get_mut(1).unwrap(); + let (_, duration, _) = self.queue.trees.get_mut(1).unwrap(); *duration = other_duration .map(|other| other.max(*duration)) .unwrap_or(*duration); - if let Some(blocker) = blocker { - clients.extend(blocker.signal_ready()); - } self.queue.animation_start = Some(Instant::now()); }