tiling: Better synchronize configures

This commit is contained in:
Victoria Brekenfeld 2023-07-05 23:48:10 +02:00
parent 5fc315c950
commit c145b3c35a
5 changed files with 54 additions and 39 deletions

View file

@ -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<AtomicBool>,
signaled: Arc<AtomicBool>,
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<Item = (CosmicSurface, Serial)>) -> 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<ClientId, Client> {
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::<HashMap<ClientId, Client>>();
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::<HashMap<ClientId, Client>>()
}
}

View file

@ -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<ClientId, Client> {
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(

View file

@ -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<ClientId, Client> {
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<KeyModifiers>) {

View file

@ -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<ClientId, Client> {
self.tiling_layer.update_animation_state()
}
pub fn commit(&mut self, surface: &WlSurface) {