shell: trigger re-render when surface disappears
This commit is contained in:
parent
56e72b4fef
commit
825430fdfd
4 changed files with 47 additions and 5 deletions
11
src/main.rs
11
src/main.rs
|
|
@ -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(())
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
25
src/utils.rs
25
src/utils.rs
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue