desktop.layer: Send output enter/leave events

This commit is contained in:
Victoria Brekenfeld 2022-01-19 19:36:26 +01:00
parent a099ccbb2e
commit 3b99a2c9dd
1 changed files with 47 additions and 2 deletions

View File

@ -3,7 +3,7 @@ use crate::{
desktop::{utils::*, PopupManager, Space},
utils::{user_data::UserDataMap, Logical, Point, Rectangle},
wayland::{
compositor::with_states,
compositor::{with_states, with_surface_tree_downward, TraversalAction},
output::{Inner as OutputInner, Output},
shell::wlr_layer::{
Anchor, ExclusiveZone, KeyboardInteractivity, Layer as WlrLayer, LayerSurface as WlrLayerSurface,
@ -29,6 +29,8 @@ pub struct LayerMap {
layers: IndexSet<LayerSurface>,
output: Weak<(Mutex<OutputInner>, wayland_server::UserDataMap)>,
zone: Rectangle<i32, Logical>,
// surfaces for tracking enter and leave events
surfaces: Vec<WlSurface>,
logger: ::slog::Logger,
}
@ -54,6 +56,7 @@ pub fn layer_map_for_output(o: &Output) -> RefMut<'_, LayerMap> {
.map(|mode| mode.size.to_logical(o.current_scale()))
.unwrap_or_else(|| (0, 0).into()),
),
surfaces: Vec::new(),
logger: (*o.inner.0.lock().unwrap())
.log
.new(slog::o!("smithay_module" => "layer_map")),
@ -94,6 +97,26 @@ impl LayerMap {
let _ = layer.user_data().get::<LayerUserdata>().take();
self.arrange();
}
if let (Some(output), Some(surface)) = (self.output(), layer.get_surface()) {
with_surface_tree_downward(
surface,
(),
|_, _, _| TraversalAction::DoChildren(()),
|wl_surface, _, _| {
if self.surfaces.contains(wl_surface) {
slog::trace!(
self.logger,
"surface ({:?}) leaving output {:?}",
wl_surface,
output.name()
);
output.leave(wl_surface);
self.surfaces.retain(|s| s != wl_surface);
}
},
|_, _, _| true,
);
}
}
/// Return the area of this output, that is not exclusive to any [`LayerSurface`]s.
@ -173,6 +196,27 @@ impl LayerMap {
continue;
};
let logger_ref = &self.logger;
let surfaces_ref = &mut self.surfaces;
with_surface_tree_downward(
surface,
(),
|_, _, _| TraversalAction::DoChildren(()),
|wl_surface, _, _| {
if !surfaces_ref.contains(wl_surface) {
slog::trace!(
logger_ref,
"surface ({:?}) entering output {:?}",
wl_surface,
output.name()
);
output.enter(wl_surface);
surfaces_ref.push(wl_surface.clone());
}
},
|_, _, _| true,
);
let data = with_states(surface, |states| {
*states.cached_state.current::<LayerSurfaceCachedState>()
})
@ -267,7 +311,8 @@ impl LayerMap {
/// This function needs to be called periodically (though not necessarily frequently)
/// to be able cleanup internally used resources.
pub fn cleanup(&mut self) {
self.layers.retain(|layer| layer.alive())
self.layers.retain(|layer| layer.alive());
self.surfaces.retain(|s| s.as_ref().is_alive());
}
}