shell: implement surface_geometry_offset_from_toplevel for WorkspaceSet
This commit is contained in:
parent
d829ec3815
commit
e75c9c0c48
1 changed files with 80 additions and 2 deletions
|
|
@ -50,10 +50,13 @@ use smithay::{
|
|||
},
|
||||
utils::{IsAlive, Logical, Point, Rectangle, Serial, Size},
|
||||
wayland::{
|
||||
compositor::{SurfaceAttributes, with_states},
|
||||
compositor::{SurfaceAttributes, get_parent, with_states},
|
||||
seat::WaylandFocus,
|
||||
session_lock::LockSurface,
|
||||
shell::wlr_layer::{KeyboardInteractivity, Layer, LayerSurfaceCachedState},
|
||||
shell::{
|
||||
wlr_layer::{KeyboardInteractivity, Layer, LayerSurfaceCachedState},
|
||||
xdg::{XDG_POPUP_ROLE, XdgPopupSurfaceData},
|
||||
},
|
||||
xdg_activation::XdgActivationState,
|
||||
xwayland_keyboard_grab::XWaylandKeyboardGrab,
|
||||
},
|
||||
|
|
@ -728,6 +731,81 @@ impl WorkspaceSet {
|
|||
self.post_remove_workspace(workspace_state, &previous_active_handle);
|
||||
prefers
|
||||
}
|
||||
|
||||
pub fn surface_geometry_offset_from_toplevel(
|
||||
&self,
|
||||
surface: &WlSurface,
|
||||
) -> Option<(Rectangle<i32, Local>, Point<i32, Logical>)> {
|
||||
let mut root = surface.clone();
|
||||
loop {
|
||||
while let Some(parent) = get_parent(&root) {
|
||||
root = parent;
|
||||
}
|
||||
if smithay::wayland::compositor::get_role(&root) == Some(XDG_POPUP_ROLE)
|
||||
&& let Some(parent) = with_states(&root, |states| {
|
||||
states
|
||||
.data_map
|
||||
.get::<XdgPopupSurfaceData>()
|
||||
.and_then(|m| m.lock().unwrap().parent.as_ref().cloned())
|
||||
})
|
||||
{
|
||||
root = parent;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
self.sticky_layer
|
||||
.mapped()
|
||||
.find(|w| {
|
||||
w.windows()
|
||||
.any(|(w, _)| w.wl_surface().as_deref() == Some(&root))
|
||||
})
|
||||
.and_then(|w| {
|
||||
w.surface_offset(surface).and_then(|offset| {
|
||||
self.sticky_layer
|
||||
.element_geometry(w)
|
||||
.map(|geom| (geom, offset))
|
||||
})
|
||||
})
|
||||
.or_else(|| {
|
||||
self.workspaces.iter().find_map(|workspace| {
|
||||
workspace
|
||||
.get_fullscreen()
|
||||
.and_then(|fullscreen| {
|
||||
(fullscreen.wl_surface().as_deref() == Some(&root))
|
||||
.then(|| {
|
||||
fullscreen.surface_offset(surface).and_then(|offset| {
|
||||
workspace.fullscreen_geometry().map(|geom| (geom, offset))
|
||||
})
|
||||
})
|
||||
.flatten()
|
||||
})
|
||||
.or_else(|| {
|
||||
workspace.mapped().find_map(|w| {
|
||||
w.windows()
|
||||
.any(|(w, _)| w.wl_surface().as_deref() == Some(&root))
|
||||
.then(|| {
|
||||
w.surface_offset(surface).and_then(|offset| {
|
||||
workspace.element_geometry(w).map(|geom| (geom, offset))
|
||||
})
|
||||
})
|
||||
.flatten()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.or_else(|| {
|
||||
layer_map_for_output(&self.output).layers().find_map(|l| {
|
||||
(l.wl_surface() == &root)
|
||||
.then(|| {
|
||||
CosmicSurface::surface_tree_offset(l.wl_surface(), surface)
|
||||
.map(|offset| (l.geometry().as_local(), offset))
|
||||
})
|
||||
.flatten()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue