compositor: allow the choice or iteration direction in subsurface trees
This commit is contained in:
parent
3dd559cdf1
commit
648da00c6a
|
@ -298,7 +298,7 @@ where
|
|||
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||
ID: 'static,
|
||||
{
|
||||
/// Access the data of a surface tree
|
||||
/// Access the data of a surface tree from bottom to top
|
||||
///
|
||||
/// The provided closure is called successively on the surface and all its child subsurfaces,
|
||||
/// in a depth-first order. This matches the order in which the surfaces are supposed to be
|
||||
|
@ -314,7 +314,8 @@ where
|
|||
///
|
||||
/// If the surface not managed by the CompositorGlobal that provided this token, this
|
||||
/// will panic (having more than one compositor is not supported).
|
||||
pub fn with_surface_tree<F, T>(&self, surface: &wl_surface::WlSurface, initial: T, f: F) -> Result<(), ()>
|
||||
pub fn with_surface_tree_upward<F, T>(&self, surface: &wl_surface::WlSurface, initial: T, f: F)
|
||||
-> Result<(), ()>
|
||||
where
|
||||
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
|
||||
-> TraversalAction<T>,
|
||||
|
@ -327,7 +328,33 @@ where
|
|||
"Accessing the data of foreign surfaces is not supported."
|
||||
);
|
||||
unsafe {
|
||||
SurfaceData::<U, R>::map_tree(surface, initial, f);
|
||||
SurfaceData::<U, R>::map_tree(surface, initial, f, false);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Access the data of a surface tree from top to bottom
|
||||
///
|
||||
/// The provided closure is called successively on the surface and all its child subsurfaces,
|
||||
/// in a depth-first order. This matches the reverse of the order in which the surfaces are
|
||||
/// supposed to be drawn: top-most first.
|
||||
///
|
||||
/// Behavior is the same as `with_surface_tree_upward`.
|
||||
pub fn with_surface_tree_downward<F, T>(&self, surface: &wl_surface::WlSurface, initial: T, f: F)
|
||||
-> Result<(), ()>
|
||||
where
|
||||
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
|
||||
-> TraversalAction<T>,
|
||||
{
|
||||
assert!(
|
||||
resource_is_registered(
|
||||
surface,
|
||||
&self::handlers::surface_implementation::<U, R, ID>()
|
||||
),
|
||||
"Accessing the data of foreign surfaces is not supported."
|
||||
);
|
||||
unsafe {
|
||||
SurfaceData::<U, R>::map_tree(surface, initial, f, true);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -307,21 +307,22 @@ impl<U: 'static, R: 'static> SurfaceData<U, R> {
|
|||
}
|
||||
|
||||
/// Access sequentially the attributes associated with a surface tree,
|
||||
/// in a depth-first order
|
||||
/// in a depth-first order.
|
||||
///
|
||||
/// Note that an internal lock is taken during access of this data,
|
||||
/// so the tree cannot be manipulated at the same time.
|
||||
///
|
||||
/// The callback returns wether the traversal should continue or not. Returning
|
||||
/// false will cause an early-stopping.
|
||||
pub unsafe fn map_tree<F, T>(root: &wl_surface::WlSurface, initial: T, mut f: F)
|
||||
pub unsafe fn map_tree<F, T>(root: &wl_surface::WlSurface, initial: T, mut f: F, reverse: bool)
|
||||
where
|
||||
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
|
||||
-> TraversalAction<T>,
|
||||
{
|
||||
// helper function for recursion
|
||||
unsafe fn map<U: 'static, R: 'static, F, T>(surface: &wl_surface::WlSurface,
|
||||
root: &wl_surface::WlSurface, initial: &T, f: &mut F)
|
||||
root: &wl_surface::WlSurface, initial: &T, f: &mut F,
|
||||
reverse: bool)
|
||||
-> bool
|
||||
where
|
||||
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
|
||||
|
@ -344,11 +345,19 @@ impl<U: 'static, R: 'static> SurfaceData<U, R> {
|
|||
) {
|
||||
TraversalAction::DoChildren(t) => {
|
||||
// loop over children
|
||||
for c in &data_guard.children {
|
||||
if !map::<U, R, _, _>(c, root, &t, f) {
|
||||
if reverse {
|
||||
for c in data_guard.children.iter().rev() {
|
||||
if !map::<U, R, _, _>(c, root, &t, f, true) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for c in &data_guard.children {
|
||||
if !map::<U, R, _, _>(c, root, &t, f, false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
TraversalAction::SkipChildren => true,
|
||||
|
@ -368,11 +377,19 @@ impl<U: 'static, R: 'static> SurfaceData<U, R> {
|
|||
) {
|
||||
TraversalAction::DoChildren(t) => {
|
||||
// loop over children
|
||||
for c in &data_guard.children {
|
||||
if !map::<U, R, _, _>(c, root, &t, &mut f) {
|
||||
if reverse {
|
||||
for c in data_guard.children.iter().rev() {
|
||||
if !map::<U, R, _, _>(c, root, &t, &mut f, true) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for c in &data_guard.children {
|
||||
if !map::<U, R, _, _>(c, root, &t, &mut f, false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue