From c145b3c35a52439478f18a92ef47ff56caed3449 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 5 Jul 2023 23:48:10 +0200 Subject: [PATCH] tiling: Better synchronize configures --- src/main.rs | 13 ++++++---- src/shell/layout/tiling/blocker.rs | 38 +++++++++++++++++------------- src/shell/layout/tiling/mod.rs | 27 +++++++++++---------- src/shell/mod.rs | 9 ++++--- src/shell/workspace.rs | 6 ++--- 5 files changed, 54 insertions(+), 39 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7810ebab..c53275d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,8 @@ use anyhow::{Context, Result}; use std::{ffi::OsString, os::unix::prelude::AsRawFd, sync::Arc}; use tracing::{error, info, warn}; +use crate::wayland::handlers::compositor::client_compositor_state; + pub mod backend; pub mod config; #[cfg(feature = "debug")] @@ -66,10 +68,13 @@ fn main() -> Result<()> { } // trigger routines - data.state - .common - .shell - .update_animations(&data.state.common.event_loop_handle); + let clients = data.state.common.shell.update_animations(); + { + let dh = data.display.handle(); + for client in clients.values() { + client_compositor_state(&client).blocker_cleared(&mut data.state, &dh); + } + } data.state.common.shell.refresh(); state::Common::refresh_focus(&mut data.state); diff --git a/src/shell/layout/tiling/blocker.rs b/src/shell/layout/tiling/blocker.rs index 73768ced..0de4f9ce 100644 --- a/src/shell/layout/tiling/blocker.rs +++ b/src/shell/layout/tiling/blocker.rs @@ -1,8 +1,4 @@ -use crate::{ - shell::element::CosmicSurface, state::Data, - wayland::handlers::compositor::client_compositor_state, -}; -use calloop::LoopHandle; +use crate::shell::element::CosmicSurface; use smithay::{ reexports::wayland_server::{backend::ClientId, Client, Resource}, utils::Serial, @@ -13,18 +9,25 @@ 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 { - if self.is_ready() { + self.signaled.store(true, Ordering::SeqCst); + if self.ready.load(Ordering::SeqCst) { BlockerState::Released } else { BlockerState::Pending @@ -36,30 +39,31 @@ 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(), } } pub fn is_ready(&self) -> bool { - Instant::now().duration_since(self.start) >= Duration::from_millis(200) + Instant::now().duration_since(self.start) >= Duration::from_millis(300) || self .necessary_acks .iter() .all(|(surf, serial)| surf.serial_acked(serial)) } - pub fn signal_ready(&self, handle: &LoopHandle<'static, Data>) { - let clients = self - .necessary_acks + pub fn is_signaled(&self) -> bool { + self.signaled.load(Ordering::SeqCst) + } + + #[must_use] + pub fn signal_ready(&self) -> HashMap { + self.ready.swap(true, Ordering::SeqCst); + self.necessary_acks .iter() .flat_map(|(surface, _)| surface.wl_surface().and_then(|s| s.client())) .map(|client| (client.id(), client)) - .collect::>(); - handle.insert_idle(move |data| { - let dh = data.display.handle(); - for client in clients.values() { - client_compositor_state(&client).blocker_cleared(&mut data.state, &dh); - } - }); + .collect::>() } } diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 20dd2c8a..6b1d9d47 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -22,7 +22,6 @@ use crate::{ }, }; -use calloop::LoopHandle; use cosmic_time::{Cubic, Ease, Tween}; use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree}; use smithay::{ @@ -36,6 +35,7 @@ use smithay::{ desktop::{layer_map_for_output, space::SpaceElement, PopupKind}, input::{pointer::GrabStartData as PointerGrabStartData, Seat}, output::Output, + reexports::wayland_server::Client, utils::{IsAlive, Logical, Point, Rectangle, Scale}, wayland::{compositor::add_blocker, seat::WaylandFocus}, }; @@ -47,6 +47,7 @@ use std::{ time::{Duration, Instant}, }; use tracing::trace; +use wayland_backend::server::ClientId; mod blocker; mod grabs; @@ -1330,10 +1331,12 @@ impl TilingLayout { .any(|queue| queue.animation_start.is_some()) } - pub fn update_animation_state(&mut self, handle: &LoopHandle<'static, crate::state::Data>) { + pub fn update_animation_state(&mut self) -> HashMap { + let mut clients = HashMap::new(); for blocker in self.pending_blockers.drain(..) { - blocker.signal_ready(handle); + clients.extend(blocker.signal_ready()); } + for queue in self.queues.values_mut() { if let Some(start) = queue.animation_start { let duration_since_start = Instant::now().duration_since(start); @@ -1346,19 +1349,19 @@ impl TilingLayout { continue; } } - if let Some((_, blocker)) = queue.trees.get(1) { - if blocker - .as_ref() - .map(TilingBlocker::is_ready) - .unwrap_or(true) - { - queue.animation_start = Some(Instant::now()); - if let Some(blocker) = blocker.as_ref() { - blocker.signal_ready(handle) + if let Some((_, _, blocker)) = queue.trees.get(1) { + if let Some(blocker) = blocker { + if blocker.is_ready() && blocker.is_signaled() { + clients.extend(blocker.signal_ready()); + queue.animation_start = Some(Instant::now()); } + } else { + queue.animation_start = Some(Instant::now()); } } } + + clients } pub fn resize_request( diff --git a/src/shell/mod.rs b/src/shell/mod.rs index ba23e863..07c47aef 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -7,6 +7,7 @@ use std::{ time::Instant, }; use tracing::warn; +use wayland_backend::server::ClientId; use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState; use smithay::{ @@ -18,7 +19,7 @@ use smithay::{ Seat, }, output::Output, - reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle}, + reexports::wayland_server::{protocol::wl_surface::WlSurface, Client, DisplayHandle}, utils::{Logical, Point, Rectangle, Serial, SERIAL_COUNTER}, wayland::{ compositor::with_states, @@ -1134,10 +1135,12 @@ impl Shell { .any(|workspace| workspace.animations_going()) } - pub fn update_animations(&mut self, handle: &LoopHandle<'static, crate::state::Data>) { + pub fn update_animations(&mut self) -> HashMap { + let mut clients = HashMap::new(); for workspace in self.workspaces.spaces_mut() { - workspace.update_animations(handle) + clients.extend(workspace.update_animations()); } + clients } pub fn set_overview_mode(&mut self, enabled: Option) { diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 5e4601c8..723131db 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -38,7 +38,7 @@ use smithay::{ desktop::{layer_map_for_output, space::SpaceElement}, input::{pointer::GrabStartData as PointerGrabStartData, Seat}, output::Output, - reexports::wayland_server::protocol::wl_surface::WlSurface, + reexports::wayland_server::{protocol::wl_surface::WlSurface, Client}, utils::{Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Size}, wayland::seat::WaylandFocus, xwayland::X11Surface, @@ -103,8 +103,8 @@ impl Workspace { self.tiling_layer.animations_going() } - pub fn update_animations(&mut self, handle: &LoopHandle<'static, crate::state::Data>) { - self.tiling_layer.update_animation_state(handle) + pub fn update_animations(&mut self) -> HashMap { + self.tiling_layer.update_animation_state() } pub fn commit(&mut self, surface: &WlSurface) {