shell: trigger re-render when surface disappears

This commit is contained in:
Victoria Brekenfeld 2022-02-04 20:57:56 +01:00
parent 56e72b4fef
commit 825430fdfd
4 changed files with 47 additions and 5 deletions

View file

@ -7,6 +7,7 @@ use smithay::reexports::{
use anyhow::{Context, Result};
use slog::Drain;
use std::sync::atomic::Ordering;
pub mod backend;
pub mod input;
@ -42,12 +43,18 @@ fn main() -> Result<()> {
return;
}
// trigger routines
state.common.spaces.refresh();
// do we need to trigger another render
if state.common.dirty_flag.swap(false, Ordering::SeqCst) {
for output in state.common.spaces.outputs() {
state.backend.schedule_render(output)
}
}
// send out events
let display = state.common.display.clone();
display.borrow_mut().flush_clients(state);
// trigger routines
state.common.spaces.refresh();
})?;
Ok(())

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::{input::active_output, state::State};
use crate::{input::active_output, state::State, utils::SurfaceDropNotifier};
use smithay::{
backend::renderer::utils::on_commit_buffer_handler,
desktop::{
@ -342,6 +342,11 @@ fn commit(surface: &WlSurface, state: &mut State) {
}
let state = &mut state.common;
let _ = with_states(surface, |states| {
states
.data_map
.insert_if_missing(|| SurfaceDropNotifier::from(&*state));
});
if let Some(toplevel) = state.pending_toplevels.iter().find(|toplevel| {
toplevel

View file

@ -18,7 +18,12 @@ use smithay::{
},
};
use std::{cell::RefCell, rc::Rc, time::Instant};
use std::{
cell::RefCell,
rc::Rc,
sync::{atomic::AtomicBool, Arc},
time::Instant,
};
#[cfg(feature = "debug")]
use std::{collections::VecDeque, time::Duration};
@ -34,6 +39,7 @@ pub struct Common {
pub spaces: Workspaces,
pub shell: ShellStates,
pub pending_toplevels: Vec<ToplevelSurface>,
pub dirty_flag: Arc<AtomicBool>,
pub seats: Vec<Seat>,
pub last_active_seat: Seat,
@ -125,6 +131,7 @@ impl State {
spaces: Workspaces::new(),
shell: shell_handles,
pending_toplevels: Vec::new(),
dirty_flag: Arc::new(AtomicBool::new(false)),
seats: vec![initial_seat.clone()],
last_active_seat: initial_seat,

View file

@ -1,7 +1,13 @@
// SPDX-License-Identifier: GPL-3.0-only
use smithay::reexports::wayland_server::{Global, Interface, Resource};
use std::convert::{AsRef, From};
use std::{
convert::{AsRef, From},
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
};
pub struct GlobalDrop<I: Interface + AsRef<Resource<I>> + From<Resource<I>>>(Option<Global<I>>);
@ -18,3 +24,20 @@ impl<I: Interface + AsRef<Resource<I>> + From<Resource<I>>> Drop for GlobalDrop<
}
}
}
// This hack will hopefully will be superseeded by a better solution, when smithay transitions to wayland-rs 0.30.
// But until then there is not really a better way to schedule a repaint on surface destruction
#[derive(Debug)]
pub struct SurfaceDropNotifier(Arc<AtomicBool>);
impl From<&crate::state::Common> for SurfaceDropNotifier {
fn from(state: &crate::state::Common) -> Self {
SurfaceDropNotifier(state.dirty_flag.clone())
}
}
impl Drop for SurfaceDropNotifier {
fn drop(&mut self) {
self.0.store(true, Ordering::SeqCst);
}
}