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

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // 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::{ use smithay::{
backend::renderer::utils::on_commit_buffer_handler, backend::renderer::utils::on_commit_buffer_handler,
desktop::{ desktop::{
@ -342,6 +342,11 @@ fn commit(surface: &WlSurface, state: &mut State) {
} }
let state = &mut state.common; 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| { if let Some(toplevel) = state.pending_toplevels.iter().find(|toplevel| {
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")] #[cfg(feature = "debug")]
use std::{collections::VecDeque, time::Duration}; use std::{collections::VecDeque, time::Duration};
@ -34,6 +39,7 @@ pub struct Common {
pub spaces: Workspaces, pub spaces: Workspaces,
pub shell: ShellStates, pub shell: ShellStates,
pub pending_toplevels: Vec<ToplevelSurface>, pub pending_toplevels: Vec<ToplevelSurface>,
pub dirty_flag: Arc<AtomicBool>,
pub seats: Vec<Seat>, pub seats: Vec<Seat>,
pub last_active_seat: Seat, pub last_active_seat: Seat,
@ -125,6 +131,7 @@ impl State {
spaces: Workspaces::new(), spaces: Workspaces::new(),
shell: shell_handles, shell: shell_handles,
pending_toplevels: Vec::new(), pending_toplevels: Vec::new(),
dirty_flag: Arc::new(AtomicBool::new(false)),
seats: vec![initial_seat.clone()], seats: vec![initial_seat.clone()],
last_active_seat: initial_seat, last_active_seat: initial_seat,

View file

@ -1,7 +1,13 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use smithay::reexports::wayland_server::{Global, Interface, Resource}; 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>>); 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);
}
}