diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2025-01-03 16:24:02 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-01-03 16:24:23 +0300 |
| commit | 8e16be9e1150fed822fd671b3faf082a9b2641c0 (patch) | |
| tree | fe33daa07cbbae2a3b48f5a33034a793cb21607b | |
| parent | 300701f44e9d1fef38eda06fc33b34708a8c6e50 (diff) | |
| download | niri-8e16be9e1150fed822fd671b3faf082a9b2641c0.tar.gz niri-8e16be9e1150fed822fd671b3faf082a9b2641c0.tar.bz2 niri-8e16be9e1150fed822fd671b3faf082a9b2641c0.zip | |
Allow pop-up grabs for bottom and background layers
| -rw-r--r-- | src/handlers/xdg_shell.rs | 31 | ||||
| -rw-r--r-- | src/niri.rs | 2 |
2 files changed, 22 insertions, 11 deletions
diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs index 0d16e5f6..df8cb456 100644 --- a/src/handlers/xdg_shell.rs +++ b/src/handlers/xdg_shell.rs @@ -289,6 +289,7 @@ impl XdgShellHandler for State { let popup = PopupKind::Xdg(surface); let Ok(root) = find_popup_root_surface(&popup) else { + trace!("ignoring popup grab because no root surface"); return; }; @@ -297,30 +298,30 @@ impl XdgShellHandler for State { // keyboard focus being at the wrong place. if self.niri.is_locked() { if Some(&root) != self.niri.lock_surface_focus().as_ref() { + trace!("ignoring popup grab because the session is locked"); let _ = PopupManager::dismiss_popup(&root, &popup); return; } } else if self.niri.screenshot_ui.is_open() { + trace!("ignoring popup grab because the screenshot UI is open"); let _ = PopupManager::dismiss_popup(&root, &popup); return; } else if let Some(output) = self.niri.layout.active_output() { let layers = layer_map_for_output(output); - if let Some(layer_surface) = - layers.layer_for_surface(&root, WindowSurfaceType::TOPLEVEL) + if layers + .layer_for_surface(&root, WindowSurfaceType::TOPLEVEL) + .is_none() { - if !matches!(layer_surface.layer(), Layer::Overlay | Layer::Top) { - let _ = PopupManager::dismiss_popup(&root, &popup); - return; - } + // This is a grab for a regular window; check that there's no layer surface with a + // higher input priority. - // FIXME: popup grabs for on-demand bottom and background layers. - } else { if layers.layers_on(Layer::Overlay).any(|l| { l.cached_state().keyboard_interactivity == wlr_layer::KeyboardInteractivity::Exclusive || Some(l) == self.niri.layer_shell_on_demand_focus.as_ref() }) { + trace!("ignoring toplevel popup grab because the overlay layer has focus"); let _ = PopupManager::dismiss_popup(&root, &popup); return; } @@ -333,28 +334,35 @@ impl XdgShellHandler for State { || Some(l) == self.niri.layer_shell_on_demand_focus.as_ref() }) { + trace!("ignoring toplevel popup grab because the top layer has focus"); let _ = PopupManager::dismiss_popup(&root, &popup); return; } let layout_focus = self.niri.layout.focus(); if Some(&root) != layout_focus.map(|win| win.toplevel().wl_surface()) { + trace!("ignoring toplevel popup grab because another window has focus"); let _ = PopupManager::dismiss_popup(&root, &popup); return; } } } else { + trace!("ignoring popup grab because no output is active"); let _ = PopupManager::dismiss_popup(&root, &popup); return; } let seat = &self.niri.seat; - let Ok(mut grab) = self + let mut grab = match self .niri .popups .grab_popup(root.clone(), popup, seat, serial) - else { - return; + { + Ok(grab) => grab, + Err(err) => { + trace!("ignoring popup grab: {err:?}"); + return; + } }; let keyboard = seat.get_keyboard().unwrap(); @@ -380,6 +388,7 @@ impl XdgShellHandler for State { && !(pointer.has_grab(serial) || grab.previous_serial().map_or(true, |s| pointer.has_grab(s))); if (can_receive_keyboard_focus && keyboard_grab_mismatches) || pointer_grab_mismatches { + trace!("ignoring popup grab because of current grab mismatch"); grab.ungrab(PopupUngrabStrategy::All); return; } diff --git a/src/niri.rs b/src/niri.rs index 665238ac..c8180c73 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -920,6 +920,8 @@ impl State { // fullscreen layout window. This will need tracking in grab() to avoid handing it out // in the first place. Or a better way to structure this code. surface = surface.or_else(|| grab_on_layer(Layer::Top)); + surface = surface.or_else(|| grab_on_layer(Layer::Bottom)); + surface = surface.or_else(|| grab_on_layer(Layer::Background)); surface = surface.or_else(|| focus_on_layer(Layer::Overlay)); |
