(&mut self, tree: &Tree)
| 110 | } |
| 111 | |
| 112 | fn enqueue_selection_changes(&mut self, tree: &Tree) { |
| 113 | let tree_state = tree.state(); |
| 114 | for (id, changes) in self.selection_changed.iter() { |
| 115 | let Some(node) = tree_state.node_by_id(*id) else { |
| 116 | continue; |
| 117 | }; |
| 118 | // Determine if `node` is a selection container with one selected child in |
| 119 | // order to optimize what platform events are sent. |
| 120 | let mut container = None; |
| 121 | let mut only_selected_child = None; |
| 122 | if node.is_container_with_selectable_children() { |
| 123 | container = Some(node); |
| 124 | for child in node.filtered_children(filter) { |
| 125 | if let Some(true) = child.is_selected() { |
| 126 | if only_selected_child.is_none() { |
| 127 | only_selected_child = Some(child); |
| 128 | } else { |
| 129 | only_selected_child = None; |
| 130 | break; |
| 131 | } |
| 132 | } |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | if let Some(only_selected_child) = only_selected_child { |
| 137 | self.queue.push(QueuedEvent::Simple { |
| 138 | element: PlatformNode::new(self.context, only_selected_child.id()).into(), |
| 139 | event_id: UIA_SelectionItem_ElementSelectedEventId, |
| 140 | }); |
| 141 | self.queue.push(QueuedEvent::PropertyChanged { |
| 142 | element: PlatformNode::new(self.context, only_selected_child.id()).into(), |
| 143 | property_id: UIA_SelectionItemIsSelectedPropertyId, |
| 144 | old_value: false.into(), |
| 145 | new_value: true.into(), |
| 146 | }); |
| 147 | for child_id in changes.removed_items.iter() { |
| 148 | let platform_node = PlatformNode::new(self.context, *child_id); |
| 149 | self.queue.push(QueuedEvent::PropertyChanged { |
| 150 | element: platform_node.into(), |
| 151 | property_id: UIA_SelectionItemIsSelectedPropertyId, |
| 152 | old_value: true.into(), |
| 153 | new_value: false.into(), |
| 154 | }); |
| 155 | } |
| 156 | } else { |
| 157 | // Per UIA documentation, beyond the "invalidate limit" we're supposed to |
| 158 | // fire a 'SelectionInvalidated' event. The exact value isn't specified, |
| 159 | // but System.Windows.Automation.Provider uses a value of 20. |
| 160 | const INVALIDATE_LIMIT: usize = 20; |
| 161 | if let Some(container) = container.filter(|_| { |
| 162 | changes.added_items.len() + changes.removed_items.len() > INVALIDATE_LIMIT |
| 163 | }) { |
| 164 | let platform_node = PlatformNode::new(self.context, container.id()); |
| 165 | self.queue.push(QueuedEvent::Simple { |
| 166 | element: platform_node.into(), |
| 167 | event_id: UIA_Selection_InvalidatedEventId, |
| 168 | }); |
| 169 | } else { |
no test coverage detected