shell: implement surface_offset and surface_tree_offset
This commit is contained in:
parent
22fe419747
commit
32b54cc31f
2 changed files with 74 additions and 1 deletions
|
|
@ -254,6 +254,14 @@ impl CosmicMapped {
|
||||||
.any(|(w, _)| w.has_surface(surface, surface_type))
|
.any(|(w, _)| w.has_surface(surface, surface_type))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn surface_offset(&self, surface: &WlSurface) -> Option<Point<i32, Logical>> {
|
||||||
|
self.windows().find_map(|(window, window_offset)| {
|
||||||
|
window
|
||||||
|
.surface_offset(surface)
|
||||||
|
.map(|offset| window_offset + offset)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Give the pointer target under a relative offset into this element.
|
/// Give the pointer target under a relative offset into this element.
|
||||||
///
|
///
|
||||||
/// Returns Target + Offset relative to the target
|
/// Returns Target + Offset relative to the target
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,10 @@ use smithay::{
|
||||||
IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, user_data::UserDataMap,
|
IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, user_data::UserDataMap,
|
||||||
},
|
},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::{SurfaceData, TraversalAction, with_states, with_surface_tree_downward},
|
compositor::{
|
||||||
|
SubsurfaceCachedState, SurfaceData, TraversalAction, with_states,
|
||||||
|
with_surface_tree_downward,
|
||||||
|
},
|
||||||
seat::WaylandFocus,
|
seat::WaylandFocus,
|
||||||
shell::xdg::{
|
shell::xdg::{
|
||||||
SurfaceCachedState, ToplevelCachedState, ToplevelSurface, XdgToplevelSurfaceData,
|
SurfaceCachedState, ToplevelCachedState, ToplevelSurface, XdgToplevelSurfaceData,
|
||||||
|
|
@ -652,6 +655,68 @@ impl CosmicSurface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn surface_offset(&self, surface: &WlSurface) -> Option<Point<i32, Logical>> {
|
||||||
|
match self.0.underlying_surface() {
|
||||||
|
WindowSurface::Wayland(toplevel) => {
|
||||||
|
Self::surface_tree_offset(toplevel.wl_surface(), surface)
|
||||||
|
}
|
||||||
|
WindowSurface::X11(surface_x11) => {
|
||||||
|
if surface_x11.wl_surface().as_ref() == Some(surface) {
|
||||||
|
Some(Point::default())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn surface_tree_offset(
|
||||||
|
root: &WlSurface,
|
||||||
|
surface: &WlSurface,
|
||||||
|
) -> Option<Point<i32, Logical>> {
|
||||||
|
if root == surface {
|
||||||
|
return Some(Point::default());
|
||||||
|
}
|
||||||
|
|
||||||
|
let found = AtomicBool::new(false);
|
||||||
|
let mut found_offset = Point::<i32, Logical>::default();
|
||||||
|
|
||||||
|
with_surface_tree_downward(
|
||||||
|
root,
|
||||||
|
Point::<i32, Logical>::default(),
|
||||||
|
|s, states, parent_offset| {
|
||||||
|
let mut offset = *parent_offset;
|
||||||
|
if s != root {
|
||||||
|
offset += states
|
||||||
|
.cached_state
|
||||||
|
.get::<SubsurfaceCachedState>()
|
||||||
|
.current()
|
||||||
|
.location;
|
||||||
|
}
|
||||||
|
TraversalAction::DoChildren(offset)
|
||||||
|
},
|
||||||
|
|s, _, offset| {
|
||||||
|
if s == surface {
|
||||||
|
found_offset = *offset;
|
||||||
|
found.store(true, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|_, _, _| !found.load(Ordering::SeqCst),
|
||||||
|
);
|
||||||
|
|
||||||
|
if found.load(Ordering::SeqCst) {
|
||||||
|
return Some(found_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (popup, popup_offset) in PopupManager::popups_for_surface(root) {
|
||||||
|
if let Some(offset) = Self::surface_tree_offset(popup.wl_surface(), surface) {
|
||||||
|
return Some(popup_offset + offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn focus_under(
|
pub fn focus_under(
|
||||||
&self,
|
&self,
|
||||||
relative_pos: Point<f64, Logical>,
|
relative_pos: Point<f64, Logical>,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue