Skip to content

Commit 8cbba5a

Browse files
committed
Add a test for the clipping filter behavior; add a comment explaining the logic and the rationale
1 parent a51d079 commit 8cbba5a

File tree

1 file changed

+136
-1
lines changed

1 file changed

+136
-1
lines changed

consumer/src/filters.rs

Lines changed: 136 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ pub fn common_filter(node: &Node) -> FilterResult {
5959

6060
if let Some(parent) = node.filtered_parent(&common_filter_without_parent_checks) {
6161
if parent.clips_children() {
62+
// If the parent clips its children, then exclude this subtree
63+
// if this child's bounding box isn't inside the parent's bounding
64+
// box, and if the previous or next filtered sibling isn't inside
65+
// the parent's bounding box either. The latter condition is meant
66+
// to allow off-screen items to be seen by consumers so they can be
67+
// scrolled into view.
6268
if let Some(bbox) = node.bounding_box() {
6369
if let Some(parent_bbox) = parent.bounding_box() {
6470
if bbox.intersect(parent_bbox).is_empty()
@@ -89,7 +95,7 @@ pub fn common_filter_with_root_exception(node: &Node) -> FilterResult {
8995

9096
#[cfg(test)]
9197
mod tests {
92-
use accesskit::{Node, NodeId, Role, Tree, TreeUpdate};
98+
use accesskit::{Node, NodeId, Rect, Role, Tree, TreeUpdate};
9399
use alloc::vec;
94100

95101
use super::{common_filter, common_filter_with_root_exception, FilterResult};
@@ -266,4 +272,133 @@ mod tests {
266272
common_filter(&tree.state().node_by_id(NodeId(1)).unwrap())
267273
);
268274
}
275+
276+
#[test]
277+
fn clipped_children() {
278+
let update = TreeUpdate {
279+
nodes: vec![
280+
(NodeId(0), {
281+
let mut node = Node::new(Role::ScrollView);
282+
node.set_clips_children();
283+
node.set_bounds(Rect::new(0.0, 0.0, 30.0, 30.0));
284+
node.set_children(vec![
285+
NodeId(1),
286+
NodeId(2),
287+
NodeId(3),
288+
NodeId(4),
289+
NodeId(5),
290+
NodeId(6),
291+
NodeId(7),
292+
NodeId(8),
293+
NodeId(9),
294+
NodeId(10),
295+
NodeId(11),
296+
]);
297+
node
298+
}),
299+
(NodeId(1), {
300+
let mut node = Node::new(Role::Unknown);
301+
node.set_bounds(Rect::new(0.0, -30.0, 30.0, -20.0));
302+
node
303+
}),
304+
(NodeId(2), {
305+
let mut node = Node::new(Role::Unknown);
306+
node.set_bounds(Rect::new(0.0, -20.0, 30.0, -10.0));
307+
node
308+
}),
309+
(NodeId(3), {
310+
let mut node = Node::new(Role::Unknown);
311+
node.set_bounds(Rect::new(0.0, -10.0, 30.0, 0.0));
312+
node
313+
}),
314+
(NodeId(4), {
315+
let mut node = Node::new(Role::Unknown);
316+
node.set_hidden();
317+
node
318+
}),
319+
(NodeId(5), {
320+
let mut node = Node::new(Role::Unknown);
321+
node.set_bounds(Rect::new(0.0, 0.0, 30.0, 10.0));
322+
node
323+
}),
324+
(NodeId(6), {
325+
let mut node = Node::new(Role::Unknown);
326+
node.set_bounds(Rect::new(0.0, 10.0, 30.0, 20.0));
327+
node
328+
}),
329+
(NodeId(7), {
330+
let mut node = Node::new(Role::Unknown);
331+
node.set_bounds(Rect::new(0.0, 20.0, 30.0, 30.0));
332+
node
333+
}),
334+
(NodeId(8), {
335+
let mut node = Node::new(Role::Unknown);
336+
node.set_hidden();
337+
node
338+
}),
339+
(NodeId(9), {
340+
let mut node = Node::new(Role::Unknown);
341+
node.set_bounds(Rect::new(0.0, 30.0, 30.0, 40.0));
342+
node
343+
}),
344+
(NodeId(10), {
345+
let mut node = Node::new(Role::Unknown);
346+
node.set_bounds(Rect::new(0.0, 40.0, 30.0, 50.0));
347+
node
348+
}),
349+
(NodeId(11), {
350+
let mut node = Node::new(Role::Unknown);
351+
node.set_bounds(Rect::new(0.0, 50.0, 30.0, 60.0));
352+
node
353+
}),
354+
],
355+
tree: Some(Tree::new(NodeId(0))),
356+
focus: NodeId(0),
357+
};
358+
let tree = crate::Tree::new(update, false);
359+
assert_eq!(
360+
FilterResult::ExcludeSubtree,
361+
common_filter(&tree.state().node_by_id(NodeId(1)).unwrap())
362+
);
363+
assert_eq!(
364+
FilterResult::ExcludeSubtree,
365+
common_filter(&tree.state().node_by_id(NodeId(2)).unwrap())
366+
);
367+
assert_eq!(
368+
FilterResult::Include,
369+
common_filter(&tree.state().node_by_id(NodeId(3)).unwrap())
370+
);
371+
assert_eq!(
372+
FilterResult::ExcludeSubtree,
373+
common_filter(&tree.state().node_by_id(NodeId(4)).unwrap())
374+
);
375+
assert_eq!(
376+
FilterResult::Include,
377+
common_filter(&tree.state().node_by_id(NodeId(5)).unwrap())
378+
);
379+
assert_eq!(
380+
FilterResult::Include,
381+
common_filter(&tree.state().node_by_id(NodeId(6)).unwrap())
382+
);
383+
assert_eq!(
384+
FilterResult::Include,
385+
common_filter(&tree.state().node_by_id(NodeId(7)).unwrap())
386+
);
387+
assert_eq!(
388+
FilterResult::ExcludeSubtree,
389+
common_filter(&tree.state().node_by_id(NodeId(8)).unwrap())
390+
);
391+
assert_eq!(
392+
FilterResult::Include,
393+
common_filter(&tree.state().node_by_id(NodeId(9)).unwrap())
394+
);
395+
assert_eq!(
396+
FilterResult::ExcludeSubtree,
397+
common_filter(&tree.state().node_by_id(NodeId(10)).unwrap())
398+
);
399+
assert_eq!(
400+
FilterResult::ExcludeSubtree,
401+
common_filter(&tree.state().node_by_id(NodeId(11)).unwrap())
402+
);
403+
}
269404
}

0 commit comments

Comments
 (0)