27 G_DEFINE_TYPE(FlViewAccessible, fl_view_accessible, ATK_TYPE_PLUG)
30 FlutterSemanticsNode2* semantics) {
31 if (semantics->flags & kFlutterSemanticsFlagIsTextField) {
38 static FlAccessibleNode*
lookup_node(FlViewAccessible*
self, int32_t
id) {
39 return FL_ACCESSIBLE_NODE(
40 g_hash_table_lookup(self->semantics_nodes_by_id, GINT_TO_POINTER(
id)));
45 static FlAccessibleNode*
get_node(FlViewAccessible*
self,
46 FlutterSemanticsNode2* semantics) {
47 FlAccessibleNode* node =
lookup_node(
self, semantics->id);
48 if (node !=
nullptr) {
56 g_hash_table_insert(self->semantics_nodes_by_id,
57 GINT_TO_POINTER(semantics->id),
58 reinterpret_cast<gpointer
>(node));
62 g_signal_emit_by_name(
self,
"children-changed::add", 0, node,
nullptr);
63 self->root_node_created =
true;
71 FlViewAccessible*
self = FL_VIEW_ACCESSIBLE(accessible);
74 if (node ==
nullptr) {
83 FlViewAccessible*
self = FL_VIEW_ACCESSIBLE(accessible);
86 if (
i != 0 || node ==
nullptr) {
90 return ATK_OBJECT(g_object_ref(node));
95 return ATK_ROLE_PANEL;
100 FlViewAccessible*
self = FL_VIEW_ACCESSIBLE(accessible);
102 return node !=
nullptr ? atk_object_ref_state_set(ATK_OBJECT(node)) :
nullptr;
106 FlViewAccessible*
self = FL_VIEW_ACCESSIBLE(
object);
108 g_clear_pointer(&self->semantics_nodes_by_id, g_hash_table_unref);
110 if (self->engine !=
nullptr) {
111 g_object_remove_weak_pointer(
object,
112 reinterpret_cast<gpointer*
>(&self->engine));
113 self->engine =
nullptr;
116 G_OBJECT_CLASS(fl_view_accessible_parent_class)->dispose(
object);
129 self->semantics_nodes_by_id = g_hash_table_new_full(
130 g_direct_hash, g_direct_equal,
nullptr, g_object_unref);
134 FlViewAccessible*
self =
135 FL_VIEW_ACCESSIBLE(g_object_new(fl_view_accessible_get_type(),
nullptr));
136 self->engine = engine;
137 g_object_add_weak_pointer(G_OBJECT(
self),
138 reinterpret_cast<gpointer*
>(&self->engine));
143 FlViewAccessible*
self,
144 const FlutterSemanticsUpdate2* update) {
145 g_autoptr(GHashTable) pending_children =
146 g_hash_table_new_full(g_direct_hash, g_direct_equal,
nullptr,
148 for (
size_t i = 0;
i < update->node_count;
i++) {
149 FlutterSemanticsNode2* node = update->nodes[
i];
150 FlAccessibleNode* atk_node =
get_node(
self, node);
156 atk_node, node->rect.left + node->transform.transX,
157 node->rect.top + node->transform.transY,
158 node->rect.right - node->rect.left, node->rect.bottom - node->rect.top);
161 node->text_selection_extent);
165 node->children_in_traversal_order, node->child_count);
166 g_hash_table_insert(pending_children, atk_node, children);
169 g_hash_table_foreach_remove(
171 [](gpointer key, gpointer
value, gpointer
user_data) -> gboolean {
172 FlViewAccessible*
self = FL_VIEW_ACCESSIBLE(
user_data);
174 FlAccessibleNode* parent = FL_ACCESSIBLE_NODE(key);
177 const int32_t* children_in_traversal_order =
180 g_autoptr(GPtrArray) children = g_ptr_array_new();
181 for (
size_t i = 0;
i < child_count;
i++) {
182 FlAccessibleNode* child =
184 g_assert(child !=
nullptr);
186 g_ptr_array_add(children, child);