diff --git a/src/shell/handler.rs b/src/shell/handler.rs index 620257cd..8fd17a6d 100644 --- a/src/shell/handler.rs +++ b/src/shell/handler.rs @@ -17,8 +17,7 @@ use smithay::{ seat::{PointerGrabStartData, Seat}, shell::{ wlr_layer::{ - wlr_layer_shell_init, KeyboardInteractivity, Layer, LayerShellRequest, - LayerSurfaceAttributes, LayerSurfaceCachedState, + wlr_layer_shell_init, LayerShellRequest, LayerSurfaceAttributes, }, xdg::{ xdg_shell_init, Configure, XdgPopupSurfaceRoleAttributes, XdgRequest, @@ -26,7 +25,6 @@ use smithay::{ }, }, Serial, - SERIAL_COUNTER, }, }; use std::{cell::Cell, sync::Mutex}; @@ -236,26 +234,7 @@ pub fn init_shell(config: &Config, display: &mut Display) -> super::Shell { .as_ref() .and_then(Output::from_resource) .unwrap_or_else(|| active_output(&seat, &*state)); - - let focus = surface - .get_surface() - .map(|surface| { - with_states(surface, |states| { - let state = states.cached_state.current::(); - matches!(state.layer, Layer::Top | Layer::Overlay) - && state.keyboard_interactivity != KeyboardInteractivity::None - }) - .unwrap() - }) - .unwrap_or(false); - - let mut map = layer_map_for_output(&output); - map.map_layer(&LayerSurface::new(surface.clone(), namespace)) - .unwrap(); - - if focus { - state.set_focus(surface.get_surface(), &seat, Some(SERIAL_COUNTER.next_serial())); - } + state.shell.active_space_mut(&output).pending_layer(LayerSurface::new(surface, namespace), &output, &seat); } _ => {} }, diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 99766988..dbc507b5 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -6,14 +6,17 @@ use crate::{ state::Common, }; pub use smithay::{ - desktop::{PopupGrab, PopupManager, PopupUngrabStrategy, Space, Window}, + desktop::{PopupGrab, PopupManager, PopupUngrabStrategy, Space, Window, layer_map_for_output}, reexports::wayland_server::protocol::wl_surface::WlSurface, utils::{Logical, Point, Rectangle, Size}, wayland::{ compositor::with_states, output::{Mode as OutputMode, Output, Scale}, seat::Seat, - shell::xdg::XdgToplevelSurfaceRoleAttributes, + shell::{ + xdg::XdgToplevelSurfaceRoleAttributes, + wlr_layer::{Layer, KeyboardInteractivity, LayerSurfaceCachedState}, + }, Serial, SERIAL_COUNTER, }, }; @@ -465,9 +468,35 @@ impl Shell { } { new_focus = Some(seat); } - workspace.pending_windows.retain(|(w, _)| w != &window); + workspace.pending_windows.retain(|(w, _)| w != &window); } - workspace.space.commit(surface) + if let Some((layer, output, seat)) = workspace + .pending_layers + .iter() + .find(|(l, _, _)| l.get_surface() == Some(surface)) + .cloned() + { + let focus = layer + .get_surface() + .map(|surface| { + with_states(surface, |states| { + let state = states.cached_state.current::(); + matches!(state.layer, Layer::Top | Layer::Overlay) + && dbg!(state.keyboard_interactivity) != KeyboardInteractivity::None + }) + .unwrap() + }) + .unwrap_or(false); + + let mut map = layer_map_for_output(&output); + map.map_layer(&layer).unwrap(); + + if focus { + new_focus = Some(seat); + } + workspace.pending_layers.retain(|(l, _, _)| l != &layer); + } + workspace.space.commit(surface); } if let Some(seat) = new_focus { self.set_focus(Some(surface), &seat, seats, None) diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 720378b8..deb32817 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -1,7 +1,7 @@ use super::{layout, Layout}; use indexmap::IndexSet; use smithay::{ - desktop::{Space, Window}, + desktop::{LayerSurface, Space, Window}, reexports::wayland_protocols::xdg_shell::server::xdg_toplevel::ResizeEdge, wayland::{ output::Output, @@ -52,6 +52,7 @@ pub struct Workspace { pub space: Space, pub(super) layout: Box, pub(super) pending_windows: Vec<(Window, Seat)>, + pub(super) pending_layers: Vec<(LayerSurface, Output, Seat)>, } impl Workspace { @@ -61,6 +62,7 @@ impl Workspace { space: Space::new(None), layout: layout::new_default_layout(), pending_windows: Vec::new(), + pending_layers: Vec::new(), } } @@ -88,6 +90,10 @@ impl Workspace { pub fn pending_window(&mut self, window: Window, seat: &Seat) { self.pending_windows.push((window, seat.clone())); } + + pub fn pending_layer(&mut self, layer: LayerSurface, output: &Output, seat: &Seat) { + self.pending_layers.push((layer, output.clone(), seat.clone())); + } pub(super) fn map_window(&mut self, window: &Window, seat: &Seat) { seat.user_data()