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