desktop.layer: Send output enter/leave events
@@ -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());
}
}
