shell: Fix definition of surface_tree_offset()

Using `with_surface_tree_downward()` is wrong because it will traverse
other branches of the surface tree than the one containing `surface`,
and add their offsets.

It's simple enough to instead walk up the surface tree.
This commit is contained in:
Ian Douglas Scott 2026-06-08 15:15:58 -07:00 committed by Ian Douglas Scott
parent 7d0d374fd8
commit 84d2a9d297

View file

@ -46,7 +46,7 @@ use smithay::{
},
wayland::{
compositor::{
SubsurfaceCachedState, SurfaceData, TraversalAction, with_states,
SubsurfaceCachedState, SurfaceData, TraversalAction, get_parent, with_states,
with_surface_tree_downward,
},
seat::WaylandFocus,
@ -675,38 +675,24 @@ impl CosmicSurface {
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
let mut offset = Point::<i32, Logical>::default();
let mut parent = surface.clone();
loop {
if parent == *root {
return Some(offset);
} else if let Some(s) = get_parent(&parent) {
offset += with_states(&parent, |states| {
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);
.location
});
parent = s;
} else {
// `parent` is now root of subsurface tree; `surface` is not a subsurface child of `root`
break;
}
}
for (popup, popup_offset) in PopupManager::popups_for_surface(root) {