fix: constrain layer shell popups to output

This commit is contained in:
Samuel Onoja committed 2026-09-24 16:59:26 +01:00
1 parent d822920d59
commit 501521cf78
2 files changed
+28 -15

No files matched your search

+1
View File
@@ -47,6 +47,7 @@ impl WlrLayerShellHandler for Ferese {
} }
fn new_popup(&mut self, _parent: LayerSurface, popup: PopupSurface) { fn new_popup(&mut self, _parent: LayerSurface, popup: PopupSurface) {
self.unconstrain_popup(&popup);
if let Err(error) = self.popups.track_popup(PopupKind::Xdg(popup)) { if let Err(error) = self.popups.track_popup(PopupKind::Xdg(popup)) {
tracing::warn!(?error, "failed to track layer-shell popup"); tracing::warn!(?error, "failed to track layer-shell popup");
} }
+27 -15
View File
@@ -1,7 +1,7 @@
use smithay::{ use smithay::{
desktop::{ desktop::{
PopupKeyboardGrab, PopupKind, PopupManager, PopupPointerGrab, Space, Window, PopupKeyboardGrab, PopupKind, PopupManager, PopupPointerGrab, Space, Window,
find_popup_root_surface, get_popup_toplevel_coords, WindowSurfaceType, find_popup_root_surface, get_popup_toplevel_coords,
}, },
input::{ input::{
Seat, Seat,
@@ -310,30 +310,42 @@ pub fn handle_commit(popups: &mut PopupManager, space: &mut Space<Window>, surfa
} }
impl Ferese { impl Ferese {
fn unconstrain_popup(&self, popup: &PopupSurface) { pub(crate) fn unconstrain_popup(&self, popup: &PopupSurface) {
let Ok(root) = find_popup_root_surface(&PopupKind::Xdg(popup.clone())) else { let Ok(root) = find_popup_root_surface(&PopupKind::Xdg(popup.clone())) else {
return; return;
}; };
let Some(window) = self.space.elements().find(|window| { let window = self.space.elements().find(|window| {
window window
.toplevel() .toplevel()
.is_some_and(|toplevel| toplevel.wl_surface() == &root) .is_some_and(|toplevel| toplevel.wl_surface() == &root)
}) else { });
return; let geometry = (|| {
}; if let Some(window) = window {
let Some(output) = self.space.outputs().next() else { let output = self.space.outputs().next()?;
return; let output_geometry = self.space.output_geometry(output)?;
}; let window_geometry = self.space.element_geometry(window)?;
let Some(output_geometry) = self.space.output_geometry(output) else {
return; Some((output_geometry, window_geometry.loc))
}; } else {
let Some(window_geometry) = self.space.element_geometry(window) else { let layer = self
.space
.layer_for_surface(&root, WindowSurfaceType::TOPLEVEL)?;
self.space.outputs().find_map(|output| {
let output_geometry = self.space.output_geometry(output)?;
let layer_geometry =
smithay::desktop::layer_map_for_output(output).layer_geometry(&layer)?;
Some((output_geometry, output_geometry.loc + layer_geometry.loc))
})
}
})();
let Some((mut target, root_location)) = geometry else {
return; return;
}; };
let mut target = output_geometry;
target.loc -= get_popup_toplevel_coords(&PopupKind::Xdg(popup.clone())); target.loc -= get_popup_toplevel_coords(&PopupKind::Xdg(popup.clone()));
target.loc -= window_geometry.loc; target.loc -= root_location;
popup.with_pending_state(|state| { popup.with_pending_state(|state| {
state.geometry = state.positioner.get_unconstrained_geometry(target); state.geometry = state.positioner.get_unconstrained_geometry(target);
}); });