27 G_DEFINE_TYPE(FlViewAccessible, fl_view_accessible, ATK_TYPE_PLUG)
30 FlutterSemanticsNode2* semantics) {
31 g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
32 if (engine ==
nullptr) {
36 if (semantics->flags2->is_text_field) {
43 static FlAccessibleNode*
lookup_node(FlViewAccessible*
self, int32_t
id) {
44 return FL_ACCESSIBLE_NODE(
45 g_hash_table_lookup(self->semantics_nodes_by_id, GINT_TO_POINTER(
id)));
50 static FlAccessibleNode*
get_node(FlViewAccessible*
self,
51 FlutterSemanticsNode2* semantics) {
52 FlAccessibleNode* node =
lookup_node(
self, semantics->id);
53 if (node !=
nullptr) {
61 g_hash_table_insert(self->semantics_nodes_by_id,
62 GINT_TO_POINTER(semantics->id),
63 reinterpret_cast<gpointer
>(node));
67 g_signal_emit_by_name(
self,
"children-changed::add", 0, node,
nullptr);
68 self->root_node_created =
true;
76 FlViewAccessible*
self = FL_VIEW_ACCESSIBLE(accessible);
79 if (node ==
nullptr) {
88 FlViewAccessible*
self = FL_VIEW_ACCESSIBLE(accessible);
91 if (
i != 0 || node ==
nullptr) {
95 return ATK_OBJECT(g_object_ref(node));
100 return ATK_ROLE_PANEL;
105 FlViewAccessible*
self = FL_VIEW_ACCESSIBLE(accessible);
107 return node !=
nullptr ? atk_object_ref_state_set(ATK_OBJECT(node)) :
nullptr;
111 FlViewAccessible*
self = FL_VIEW_ACCESSIBLE(
object);
113 g_clear_pointer(&self->semantics_nodes_by_id, g_hash_table_unref);
115 g_weak_ref_clear(&self->engine);
117 G_OBJECT_CLASS(fl_view_accessible_parent_class)->dispose(
object);
130 self->semantics_nodes_by_id = g_hash_table_new_full(
131 g_direct_hash, g_direct_equal,
nullptr, g_object_unref);
136 FlViewAccessible*
self =
137 FL_VIEW_ACCESSIBLE(g_object_new(fl_view_accessible_get_type(),
nullptr));
138 g_weak_ref_init(&self->engine, engine);
144 FlViewAccessible*
self,
145 const FlutterSemanticsUpdate2* update) {
146 g_return_if_fail(FL_IS_VIEW_ACCESSIBLE(
self));
148 g_autoptr(GHashTable) pending_children =
149 g_hash_table_new_full(g_direct_hash, g_direct_equal,
nullptr,
151 for (
size_t i = 0;
i < update->node_count;
i++) {
152 FlutterSemanticsNode2* node = update->nodes[
i];
153 FlAccessibleNode* atk_node =
get_node(
self, node);
159 atk_node, node->rect.left + node->transform.transX,
160 node->rect.top + node->transform.transY,
161 node->rect.right - node->rect.left, node->rect.bottom - node->rect.top);
164 node->text_selection_extent);
168 node->children_in_traversal_order, node->child_count);
169 g_hash_table_insert(pending_children, atk_node, children);
172 g_hash_table_foreach_remove(
174 [](gpointer key, gpointer
value, gpointer
user_data) -> gboolean {
175 FlViewAccessible*
self = FL_VIEW_ACCESSIBLE(
user_data);
177 FlAccessibleNode* parent = FL_ACCESSIBLE_NODE(key);
180 const int32_t* children_in_traversal_order =
183 g_autoptr(GPtrArray) children = g_ptr_array_new();
184 for (
size_t i = 0;
i < child_count;
i++) {
185 FlAccessibleNode* child =
187 g_assert(child !=
nullptr);
189 g_ptr_array_add(children, child);
void fl_accessible_node_set_name(FlAccessibleNode *self, const gchar *name)
void fl_accessible_node_set_text_direction(FlAccessibleNode *self, FlutterTextDirection direction)
void fl_accessible_node_set_text_selection(FlAccessibleNode *self, gint base, gint extent)
void fl_accessible_node_set_actions(FlAccessibleNode *self, FlutterSemanticsAction actions)
void fl_accessible_node_set_children(FlAccessibleNode *self, GPtrArray *children)
void fl_accessible_node_set_extents(FlAccessibleNode *self, gint x, gint y, gint width, gint height)
void fl_accessible_node_set_value(FlAccessibleNode *self, const gchar *value)
void fl_accessible_node_set_parent(FlAccessibleNode *self, AtkObject *parent, gint index)
void fl_accessible_node_set_flags(FlAccessibleNode *self, FlutterSemanticsFlags *flags)
FlAccessibleNode * fl_accessible_node_new(FlEngine *engine, FlutterViewId view_id, int32_t node_id)
FlAccessibleNode * fl_accessible_text_field_new(FlEngine *engine, FlutterViewId view_id, int32_t id)
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle, fl_basic_message_channel_response_handle, G_TYPE_OBJECT) static void fl_basic_message_channel_response_handle_dispose(GObject *object)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue gpointer user_data
G_MODULE_EXPORT FlValue * fl_value_new_int32_list(const int32_t *data, size_t data_length)
G_MODULE_EXPORT void fl_value_unref(FlValue *self)
G_MODULE_EXPORT const int32_t * fl_value_get_int32_list(FlValue *self)
G_MODULE_EXPORT size_t fl_value_get_length(FlValue *self)
typedefG_BEGIN_DECLS struct _FlValue FlValue
static void fl_view_accessible_dispose(GObject *object)
static FlAccessibleNode * create_node(FlViewAccessible *self, FlutterSemanticsNode2 *semantics)
static AtkObject * fl_view_accessible_ref_child(AtkObject *accessible, gint i)
FlViewAccessible * fl_view_accessible_new(FlEngine *engine, FlutterViewId view_id)
static void fl_view_accessible_init(FlViewAccessible *self)
static AtkRole fl_view_accessible_get_role(AtkObject *accessible)
static FlAccessibleNode * lookup_node(FlViewAccessible *self, int32_t id)
static FlAccessibleNode * get_node(FlViewAccessible *self, FlutterSemanticsNode2 *semantics)
static gint fl_view_accessible_get_n_children(AtkObject *accessible)
static void fl_view_accessible_class_init(FlViewAccessibleClass *klass)
static constexpr int32_t kRootSemanticsNodeId
void fl_view_accessible_handle_update_semantics(FlViewAccessible *self, const FlutterSemanticsUpdate2 *update)
static AtkStateSet * fl_view_accessible_ref_state_set(AtkObject *accessible)
G_BEGIN_DECLS FlutterViewId view_id
GHashTable * semantics_nodes_by_id
gboolean root_node_created