use smithay::{ desktop::{ LayerSurface as DesktopLayerSurface, PopupKind, WindowSurfaceType, layer_map_for_output, }, output::Output, reexports::wayland_server::protocol::{wl_output::WlOutput, wl_surface::WlSurface}, wayland::shell::{ wlr_layer::{Layer, LayerSurface, WlrLayerShellHandler, WlrLayerShellState}, xdg::PopupSurface, }, }; use crate::Ferese; impl WlrLayerShellHandler for Ferese { fn shell_state(&mut self) -> &mut WlrLayerShellState { &mut self.layer_shell_state } fn new_layer_surface( &mut self, surface: LayerSurface, output: Option, _layer: Layer, namespace: String, ) { let output = output .as_ref() .and_then(Output::from_resource) .or_else(|| self.space.outputs().next().cloned()); let Some(output) = output else { tracing::warn!(%namespace, "layer surface has no available output"); return; }; let layer = DesktopLayerSurface::new(surface, namespace.clone()); if let Err(error) = layer_map_for_output(&output).map_layer(&layer) { tracing::warn!(%namespace, %error, "failed to map layer surface"); return; } tracing::debug!(%namespace, output = %output.name(), "mapped layer surface"); self.relayout(); crate::backends::direct::render_all(self); } fn new_popup(&mut self, _parent: LayerSurface, popup: PopupSurface) { if let Err(error) = self.popups.track_popup(PopupKind::Xdg(popup)) { tracing::warn!(?error, "failed to track layer-shell popup"); } } fn layer_destroyed(&mut self, surface: LayerSurface) { let Some(layer) = self .space .layer_for_surface(surface.wl_surface(), WindowSurfaceType::TOPLEVEL) else { return; }; let outputs = self.space.outputs().cloned().collect::>(); for output in outputs { layer_map_for_output(&output).unmap_layer(&layer); } self.relayout(); crate::backends::direct::render_all(self); } } pub fn handle_commit(state: &mut Ferese, surface: &WlSurface) { let Some(layer) = state .space .layer_for_surface(surface, WindowSurfaceType::TOPLEVEL) else { return; }; let outputs = state.space.outputs().cloned().collect::>(); for output in outputs { let mut map = layer_map_for_output(&output); if map.layer_geometry(&layer).is_some() { map.arrange(); layer.layer_surface().send_pending_configure(); break; } } state.relayout(); }