mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Update Linux embedder to latest semantics API (flutter/engine#51030)
Change to the latest semantics API and remove an unused class.
This commit is contained in:
parent
65f3a2348b
commit
da5550db7f
@ -36876,8 +36876,6 @@ ORIGIN: ../../../flutter/shell/platform/glfw/system_utils.h + ../../../flutter/L
|
||||
ORIGIN: ../../../flutter/shell/platform/glfw/system_utils_test.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/glfw/text_input_plugin.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/glfw/text_input_plugin.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_accessibility_plugin.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_accessibility_plugin.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_accessible_node.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_accessible_node.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_accessible_node_test.cc + ../../../flutter/LICENSE
|
||||
@ -39751,8 +39749,6 @@ FILE: ../../../flutter/shell/platform/glfw/system_utils.h
|
||||
FILE: ../../../flutter/shell/platform/glfw/system_utils_test.cc
|
||||
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.cc
|
||||
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.h
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_accessibility_plugin.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_accessibility_plugin.h
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_accessible_node.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_accessible_node.h
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_accessible_node_test.cc
|
||||
|
||||
@ -96,7 +96,6 @@ source_set("flutter_linux_sources") {
|
||||
configs += [ "//flutter/shell/platform/linux/config:gtk" ]
|
||||
|
||||
sources = [
|
||||
"fl_accessibility_plugin.cc",
|
||||
"fl_accessible_node.cc",
|
||||
"fl_accessible_text_field.cc",
|
||||
"fl_backing_store_provider.cc",
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/shell/platform/linux/fl_accessibility_plugin.h"
|
||||
#include "flutter/shell/platform/linux/fl_view_accessible.h"
|
||||
|
||||
struct _FlAccessibilityPlugin {
|
||||
GObject parent_instance;
|
||||
|
||||
FlView* view;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FlAccessibilityPlugin, fl_accessibility_plugin, G_TYPE_OBJECT)
|
||||
|
||||
static void fl_accessibility_plugin_dispose(GObject* object) {
|
||||
FlAccessibilityPlugin* self = FL_ACCESSIBILITY_PLUGIN(object);
|
||||
|
||||
if (self->view != nullptr) {
|
||||
g_object_remove_weak_pointer(G_OBJECT(self),
|
||||
reinterpret_cast<gpointer*>(&(self->view)));
|
||||
self->view = nullptr;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(fl_accessibility_plugin_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void fl_accessibility_plugin_class_init(
|
||||
FlAccessibilityPluginClass* klass) {
|
||||
G_OBJECT_CLASS(klass)->dispose = fl_accessibility_plugin_dispose;
|
||||
}
|
||||
|
||||
static void fl_accessibility_plugin_init(FlAccessibilityPlugin* self) {}
|
||||
|
||||
FlAccessibilityPlugin* fl_accessibility_plugin_new(FlView* view) {
|
||||
FlAccessibilityPlugin* self = FL_ACCESSIBILITY_PLUGIN(
|
||||
g_object_new(fl_accessibility_plugin_get_type(), nullptr));
|
||||
|
||||
self->view = view;
|
||||
g_object_add_weak_pointer(G_OBJECT(self),
|
||||
reinterpret_cast<gpointer*>(&(self->view)));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void fl_accessibility_plugin_handle_update_semantics_node(
|
||||
FlAccessibilityPlugin* self,
|
||||
const FlutterSemanticsNode* node) {
|
||||
if (self->view == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
AtkObject* accessible = gtk_widget_get_accessible(GTK_WIDGET(self->view));
|
||||
fl_view_accessible_handle_update_semantics_node(
|
||||
FL_VIEW_ACCESSIBLE(accessible), node);
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_ACCESSIBILITY_PLUGIN_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_ACCESSIBILITY_PLUGIN_H_
|
||||
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_view.h"
|
||||
|
||||
#include "flutter/shell/platform/embedder/embedder.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlAccessibilityPlugin,
|
||||
fl_accessibility_plugin,
|
||||
FL,
|
||||
ACCESSIBILITY_PLUGIN,
|
||||
GObject);
|
||||
|
||||
/**
|
||||
* FlAccessibilityPlugin:
|
||||
*
|
||||
* #FlAccessibilityPlugin is a plugin that handles semantic node updates and
|
||||
* converts them to ATK events.
|
||||
*/
|
||||
|
||||
/**
|
||||
* fl_accessibility_plugin_new:
|
||||
* @view: an #FlView to export accessibility information to.
|
||||
*
|
||||
* Creates a new plugin handles semantic node updates.
|
||||
*
|
||||
* Returns: a new #FlAccessibilityPlugin.
|
||||
*/
|
||||
FlAccessibilityPlugin* fl_accessibility_plugin_new(FlView* view);
|
||||
|
||||
/**
|
||||
* fl_accessibility_plugin_handle_update_semantics_node:
|
||||
* @plugin: an #FlAccessibilityPlugin.
|
||||
* @node: semantic node information.
|
||||
*
|
||||
* Handle a semantics node update.
|
||||
*/
|
||||
void fl_accessibility_plugin_handle_update_semantics_node(
|
||||
FlAccessibilityPlugin* plugin,
|
||||
const FlutterSemanticsNode* node);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_ACCESSIBILITY_PLUGIN_H_
|
||||
@ -59,9 +59,9 @@ struct _FlEngine {
|
||||
GDestroyNotify platform_message_handler_destroy_notify;
|
||||
|
||||
// Function to call when a semantic node is received.
|
||||
FlEngineUpdateSemanticsNodeHandler update_semantics_node_handler;
|
||||
gpointer update_semantics_node_handler_data;
|
||||
GDestroyNotify update_semantics_node_handler_destroy_notify;
|
||||
FlEngineUpdateSemanticsHandler update_semantics_handler;
|
||||
gpointer update_semantics_handler_data;
|
||||
GDestroyNotify update_semantics_handler_destroy_notify;
|
||||
|
||||
// Function to call right before the engine is restarted.
|
||||
FlEngineOnPreEngineRestartHandler on_pre_engine_restart_handler;
|
||||
@ -333,13 +333,13 @@ static void fl_engine_platform_message_cb(const FlutterPlatformMessage* message,
|
||||
}
|
||||
|
||||
// Called when a semantic node update is received from the engine.
|
||||
static void fl_engine_update_semantics_node_cb(const FlutterSemanticsNode* node,
|
||||
void* user_data) {
|
||||
static void fl_engine_update_semantics_cb(const FlutterSemanticsUpdate2* update,
|
||||
void* user_data) {
|
||||
FlEngine* self = FL_ENGINE(user_data);
|
||||
|
||||
if (self->update_semantics_node_handler != nullptr) {
|
||||
self->update_semantics_node_handler(
|
||||
self, node, self->update_semantics_node_handler_data);
|
||||
if (self->update_semantics_handler != nullptr) {
|
||||
self->update_semantics_handler(self, update,
|
||||
self->update_semantics_handler_data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -425,12 +425,12 @@ static void fl_engine_dispose(GObject* object) {
|
||||
self->platform_message_handler_data = nullptr;
|
||||
self->platform_message_handler_destroy_notify = nullptr;
|
||||
|
||||
if (self->update_semantics_node_handler_destroy_notify) {
|
||||
self->update_semantics_node_handler_destroy_notify(
|
||||
self->update_semantics_node_handler_data);
|
||||
if (self->update_semantics_handler_destroy_notify) {
|
||||
self->update_semantics_handler_destroy_notify(
|
||||
self->update_semantics_handler_data);
|
||||
}
|
||||
self->update_semantics_node_handler_data = nullptr;
|
||||
self->update_semantics_node_handler_destroy_notify = nullptr;
|
||||
self->update_semantics_handler_data = nullptr;
|
||||
self->update_semantics_handler_destroy_notify = nullptr;
|
||||
|
||||
if (self->on_pre_engine_restart_handler_destroy_notify) {
|
||||
self->on_pre_engine_restart_handler_destroy_notify(
|
||||
@ -527,7 +527,7 @@ gboolean fl_engine_start(FlEngine* self, GError** error) {
|
||||
args.command_line_argv =
|
||||
reinterpret_cast<const char* const*>(command_line_args->pdata);
|
||||
args.platform_message_callback = fl_engine_platform_message_cb;
|
||||
args.update_semantics_node_callback = fl_engine_update_semantics_node_cb;
|
||||
args.update_semantics_callback2 = fl_engine_update_semantics_cb;
|
||||
args.custom_task_runners = &custom_task_runners;
|
||||
args.shutdown_dart_vm_when_done = true;
|
||||
args.on_pre_engine_restart_callback = fl_engine_on_pre_engine_restart_cb;
|
||||
@ -610,21 +610,21 @@ void fl_engine_set_platform_message_handler(
|
||||
self->platform_message_handler_destroy_notify = destroy_notify;
|
||||
}
|
||||
|
||||
void fl_engine_set_update_semantics_node_handler(
|
||||
void fl_engine_set_update_semantics_handler(
|
||||
FlEngine* self,
|
||||
FlEngineUpdateSemanticsNodeHandler handler,
|
||||
FlEngineUpdateSemanticsHandler handler,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_notify) {
|
||||
g_return_if_fail(FL_IS_ENGINE(self));
|
||||
|
||||
if (self->update_semantics_node_handler_destroy_notify) {
|
||||
self->update_semantics_node_handler_destroy_notify(
|
||||
self->update_semantics_node_handler_data);
|
||||
if (self->update_semantics_handler_destroy_notify) {
|
||||
self->update_semantics_handler_destroy_notify(
|
||||
self->update_semantics_handler_data);
|
||||
}
|
||||
|
||||
self->update_semantics_node_handler = handler;
|
||||
self->update_semantics_node_handler_data = user_data;
|
||||
self->update_semantics_node_handler_destroy_notify = destroy_notify;
|
||||
self->update_semantics_handler = handler;
|
||||
self->update_semantics_handler_data = user_data;
|
||||
self->update_semantics_handler_destroy_notify = destroy_notify;
|
||||
}
|
||||
|
||||
void fl_engine_set_on_pre_engine_restart_handler(
|
||||
|
||||
@ -48,16 +48,16 @@ typedef gboolean (*FlEnginePlatformMessageHandler)(
|
||||
gpointer user_data);
|
||||
|
||||
/**
|
||||
* FlEngineUpdateSemanticsNodeHandler:
|
||||
* FlEngineUpdateSemanticsHandler:
|
||||
* @engine: an #FlEngine.
|
||||
* @node: semantic node information.
|
||||
* @user_data: (closure): data provided when registering this handler.
|
||||
*
|
||||
* Function called when semantics node updates are received.
|
||||
*/
|
||||
typedef void (*FlEngineUpdateSemanticsNodeHandler)(
|
||||
typedef void (*FlEngineUpdateSemanticsHandler)(
|
||||
FlEngine* engine,
|
||||
const FlutterSemanticsNode* node,
|
||||
const FlutterSemanticsUpdate2* update,
|
||||
gpointer user_data);
|
||||
|
||||
/**
|
||||
@ -112,18 +112,18 @@ void fl_engine_set_platform_message_handler(
|
||||
GDestroyNotify destroy_notify);
|
||||
|
||||
/**
|
||||
* fl_engine_set_update_semantics_node_handler:
|
||||
* fl_engine_set_update_semantics_handler:
|
||||
* @engine: an #FlEngine.
|
||||
* @handler: function to call when a semantics node update is received.
|
||||
* @handler: function to call when a semantics update is received.
|
||||
* @user_data: (closure): user data to pass to @handler.
|
||||
* @destroy_notify: (allow-none): a function which gets called to free
|
||||
* @user_data, or %NULL.
|
||||
*
|
||||
* Registers the function called when a semantics node update is reveived.
|
||||
* Registers the function called when a semantics update is received.
|
||||
*/
|
||||
void fl_engine_set_update_semantics_node_handler(
|
||||
void fl_engine_set_update_semantics_handler(
|
||||
FlEngine* engine,
|
||||
FlEngineUpdateSemanticsNodeHandler handler,
|
||||
FlEngineUpdateSemanticsHandler handler,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_notify);
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "flutter/shell/platform/linux/fl_accessibility_plugin.h"
|
||||
#include "flutter/shell/platform/linux/fl_engine_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_key_event.h"
|
||||
#include "flutter/shell/platform/linux/fl_keyboard_manager.h"
|
||||
@ -46,7 +45,6 @@ struct _FlView {
|
||||
GdkWindowState window_state;
|
||||
|
||||
// Flutter system channel handlers.
|
||||
FlAccessibilityPlugin* accessibility_plugin;
|
||||
FlKeyboardManager* keyboard_manager;
|
||||
FlScrollingManager* scrolling_manager;
|
||||
FlTextInputPlugin* text_input_plugin;
|
||||
@ -225,14 +223,15 @@ static void handle_geometry_changed(FlView* self) {
|
||||
}
|
||||
}
|
||||
|
||||
// Called when the engine updates accessibility nodes.
|
||||
static void update_semantics_node_cb(FlEngine* engine,
|
||||
const FlutterSemanticsNode* node,
|
||||
gpointer user_data) {
|
||||
// Called when the engine updates accessibility.
|
||||
static void update_semantics_cb(FlEngine* engine,
|
||||
const FlutterSemanticsUpdate2* update,
|
||||
gpointer user_data) {
|
||||
FlView* self = FL_VIEW(user_data);
|
||||
|
||||
fl_accessibility_plugin_handle_update_semantics_node(
|
||||
self->accessibility_plugin, node);
|
||||
AtkObject* accessible = gtk_widget_get_accessible(GTK_WIDGET(self));
|
||||
fl_view_accessible_handle_update_semantics(FL_VIEW_ACCESSIBLE(accessible),
|
||||
update);
|
||||
}
|
||||
|
||||
// Invoked by the engine right before the engine is restarted.
|
||||
@ -559,8 +558,8 @@ static void fl_view_constructed(GObject* object) {
|
||||
|
||||
self->renderer = FL_RENDERER(fl_renderer_gl_new());
|
||||
self->engine = fl_engine_new(self->project, self->renderer);
|
||||
fl_engine_set_update_semantics_node_handler(
|
||||
self->engine, update_semantics_node_cb, self, nullptr);
|
||||
fl_engine_set_update_semantics_handler(self->engine, update_semantics_cb,
|
||||
self, nullptr);
|
||||
fl_engine_set_on_pre_engine_restart_handler(
|
||||
self->engine, on_pre_engine_restart_cb, self, nullptr);
|
||||
|
||||
@ -569,7 +568,6 @@ static void fl_view_constructed(GObject* object) {
|
||||
|
||||
// Create system channel handlers.
|
||||
FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(self->engine);
|
||||
self->accessibility_plugin = fl_accessibility_plugin_new(self);
|
||||
init_scrolling(self);
|
||||
self->mouse_cursor_plugin = fl_mouse_cursor_plugin_new(messenger, self);
|
||||
self->platform_plugin = fl_platform_plugin_new(messenger);
|
||||
@ -666,8 +664,8 @@ static void fl_view_dispose(GObject* object) {
|
||||
FlView* self = FL_VIEW(object);
|
||||
|
||||
if (self->engine != nullptr) {
|
||||
fl_engine_set_update_semantics_node_handler(self->engine, nullptr, nullptr,
|
||||
nullptr);
|
||||
fl_engine_set_update_semantics_handler(self->engine, nullptr, nullptr,
|
||||
nullptr);
|
||||
fl_engine_set_on_pre_engine_restart_handler(self->engine, nullptr, nullptr,
|
||||
nullptr);
|
||||
}
|
||||
@ -681,7 +679,6 @@ static void fl_view_dispose(GObject* object) {
|
||||
g_clear_object(&self->project);
|
||||
g_clear_object(&self->renderer);
|
||||
g_clear_object(&self->engine);
|
||||
g_clear_object(&self->accessibility_plugin);
|
||||
g_clear_object(&self->keyboard_manager);
|
||||
if (self->keymap_keys_changed_cb_id != 0) {
|
||||
g_signal_handler_disconnect(self->keymap, self->keymap_keys_changed_cb_id);
|
||||
|
||||
@ -15,9 +15,6 @@ struct _FlViewAccessible {
|
||||
|
||||
// Semantics nodes keyed by ID
|
||||
GHashTable* semantics_nodes_by_id;
|
||||
|
||||
// Child IDs stored until commit_updates is called
|
||||
GHashTable* pending_children;
|
||||
};
|
||||
|
||||
enum { kProp0, kPropEngine, kPropLast };
|
||||
@ -42,7 +39,7 @@ static FlEngine* get_engine(FlViewAccessible* self) {
|
||||
}
|
||||
|
||||
static FlAccessibleNode* create_node(FlViewAccessible* self,
|
||||
const FlutterSemanticsNode* semantics) {
|
||||
FlutterSemanticsNode2* semantics) {
|
||||
FlEngine* engine = get_engine(self);
|
||||
|
||||
if (semantics->flags & kFlutterSemanticsFlagIsTextField) {
|
||||
@ -60,7 +57,7 @@ static FlAccessibleNode* lookup_node(FlViewAccessible* self, int32_t id) {
|
||||
// Gets the ATK node for the given id.
|
||||
// If the node doesn't exist it will be created.
|
||||
static FlAccessibleNode* get_node(FlViewAccessible* self,
|
||||
const FlutterSemanticsNode* semantics) {
|
||||
FlutterSemanticsNode2* semantics) {
|
||||
FlAccessibleNode* node = lookup_node(self, semantics->id);
|
||||
if (node != nullptr) {
|
||||
return node;
|
||||
@ -78,33 +75,6 @@ static FlAccessibleNode* get_node(FlViewAccessible* self,
|
||||
return node;
|
||||
}
|
||||
|
||||
static void commit_updates(FlViewAccessible* self) {
|
||||
g_hash_table_foreach_remove(
|
||||
self->pending_children,
|
||||
[](gpointer key, gpointer value, gpointer user_data) -> gboolean {
|
||||
FlViewAccessible* self = FL_VIEW_ACCESSIBLE(user_data);
|
||||
|
||||
FlAccessibleNode* parent = FL_ACCESSIBLE_NODE(key);
|
||||
|
||||
size_t child_count = fl_value_get_length(static_cast<FlValue*>(value));
|
||||
const int32_t* children_in_traversal_order =
|
||||
fl_value_get_int32_list(static_cast<FlValue*>(value));
|
||||
|
||||
g_autoptr(GPtrArray) children = g_ptr_array_new();
|
||||
for (size_t i = 0; i < child_count; i++) {
|
||||
FlAccessibleNode* child =
|
||||
lookup_node(self, children_in_traversal_order[i]);
|
||||
g_assert(child != nullptr);
|
||||
fl_accessible_node_set_parent(child, ATK_OBJECT(parent), i);
|
||||
g_ptr_array_add(children, child);
|
||||
}
|
||||
fl_accessible_node_set_children(parent, children);
|
||||
|
||||
return true;
|
||||
},
|
||||
self);
|
||||
}
|
||||
|
||||
// Implements AtkObject::get_n_children
|
||||
static gint fl_view_accessible_get_n_children(AtkObject* accessible) {
|
||||
FlViewAccessible* self = FL_VIEW_ACCESSIBLE(accessible);
|
||||
@ -154,7 +124,6 @@ static void fl_view_accessible_dispose(GObject* object) {
|
||||
FlViewAccessible* self = FL_VIEW_ACCESSIBLE(object);
|
||||
|
||||
g_clear_pointer(&self->semantics_nodes_by_id, g_hash_table_unref);
|
||||
g_clear_pointer(&self->pending_children, g_hash_table_unref);
|
||||
|
||||
if (self->engine != nullptr) {
|
||||
g_object_remove_weak_pointer(object,
|
||||
@ -184,34 +153,58 @@ static void fl_view_accessible_class_init(FlViewAccessibleClass* klass) {
|
||||
static void fl_view_accessible_init(FlViewAccessible* self) {
|
||||
self->semantics_nodes_by_id = g_hash_table_new_full(
|
||||
g_direct_hash, g_direct_equal, nullptr, g_object_unref);
|
||||
self->pending_children =
|
||||
}
|
||||
|
||||
void fl_view_accessible_handle_update_semantics(
|
||||
FlViewAccessible* self,
|
||||
const FlutterSemanticsUpdate2* update) {
|
||||
g_autoptr(GHashTable) pending_children =
|
||||
g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr,
|
||||
reinterpret_cast<GDestroyNotify>(fl_value_unref));
|
||||
}
|
||||
|
||||
void fl_view_accessible_handle_update_semantics_node(
|
||||
FlViewAccessible* self,
|
||||
const FlutterSemanticsNode* node) {
|
||||
if (node->id == kFlutterSemanticsNodeIdBatchEnd) {
|
||||
commit_updates(self);
|
||||
return;
|
||||
for (size_t i = 0; i < update->node_count; i++) {
|
||||
FlutterSemanticsNode2* node = update->nodes[i];
|
||||
FlAccessibleNode* atk_node = get_node(self, node);
|
||||
|
||||
fl_accessible_node_set_flags(atk_node, node->flags);
|
||||
fl_accessible_node_set_actions(atk_node, node->actions);
|
||||
fl_accessible_node_set_name(atk_node, node->label);
|
||||
fl_accessible_node_set_extents(
|
||||
atk_node, node->rect.left + node->transform.transX,
|
||||
node->rect.top + node->transform.transY,
|
||||
node->rect.right - node->rect.left, node->rect.bottom - node->rect.top);
|
||||
fl_accessible_node_set_value(atk_node, node->value);
|
||||
fl_accessible_node_set_text_selection(atk_node, node->text_selection_base,
|
||||
node->text_selection_extent);
|
||||
fl_accessible_node_set_text_direction(atk_node, node->text_direction);
|
||||
|
||||
FlValue* children = fl_value_new_int32_list(
|
||||
node->children_in_traversal_order, node->child_count);
|
||||
g_hash_table_insert(pending_children, atk_node, children);
|
||||
}
|
||||
|
||||
FlAccessibleNode* atk_node = get_node(self, node);
|
||||
g_hash_table_foreach_remove(
|
||||
pending_children,
|
||||
[](gpointer key, gpointer value, gpointer user_data) -> gboolean {
|
||||
FlViewAccessible* self = FL_VIEW_ACCESSIBLE(user_data);
|
||||
|
||||
fl_accessible_node_set_flags(atk_node, node->flags);
|
||||
fl_accessible_node_set_actions(atk_node, node->actions);
|
||||
fl_accessible_node_set_name(atk_node, node->label);
|
||||
fl_accessible_node_set_extents(
|
||||
atk_node, node->rect.left + node->transform.transX,
|
||||
node->rect.top + node->transform.transY,
|
||||
node->rect.right - node->rect.left, node->rect.bottom - node->rect.top);
|
||||
fl_accessible_node_set_value(atk_node, node->value);
|
||||
fl_accessible_node_set_text_selection(atk_node, node->text_selection_base,
|
||||
node->text_selection_extent);
|
||||
fl_accessible_node_set_text_direction(atk_node, node->text_direction);
|
||||
FlAccessibleNode* parent = FL_ACCESSIBLE_NODE(key);
|
||||
|
||||
FlValue* children = fl_value_new_int32_list(node->children_in_traversal_order,
|
||||
node->child_count);
|
||||
g_hash_table_insert(self->pending_children, atk_node, children);
|
||||
size_t child_count = fl_value_get_length(static_cast<FlValue*>(value));
|
||||
const int32_t* children_in_traversal_order =
|
||||
fl_value_get_int32_list(static_cast<FlValue*>(value));
|
||||
|
||||
g_autoptr(GPtrArray) children = g_ptr_array_new();
|
||||
for (size_t i = 0; i < child_count; i++) {
|
||||
FlAccessibleNode* child =
|
||||
lookup_node(self, children_in_traversal_order[i]);
|
||||
g_assert(child != nullptr);
|
||||
fl_accessible_node_set_parent(child, ATK_OBJECT(parent), i);
|
||||
g_ptr_array_add(children, child);
|
||||
}
|
||||
fl_accessible_node_set_children(parent, children);
|
||||
|
||||
return true;
|
||||
},
|
||||
self);
|
||||
}
|
||||
|
||||
@ -29,15 +29,15 @@ G_DECLARE_FINAL_TYPE(FlViewAccessible,
|
||||
*/
|
||||
|
||||
/**
|
||||
* fl_view_accessible_handle_update_semantics_node:
|
||||
* fl_view_accessible_handle_update_semantics:
|
||||
* @accessible: an #FlViewAccessible.
|
||||
* @node: semantic node information.
|
||||
* @update: semantic update information.
|
||||
*
|
||||
* Handle a semantics node update from Flutter.
|
||||
* Handle a semantics update from Flutter.
|
||||
*/
|
||||
void fl_view_accessible_handle_update_semantics_node(
|
||||
void fl_view_accessible_handle_update_semantics(
|
||||
FlViewAccessible* accessible,
|
||||
const FlutterSemanticsNode* node);
|
||||
const FlutterSemanticsUpdate2* update);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@ -10,30 +10,23 @@
|
||||
#include "flutter/shell/platform/linux/testing/fl_test.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_signal_handler.h"
|
||||
|
||||
static const FlutterSemanticsNode kBatchEndNode = {
|
||||
.id = kFlutterSemanticsNodeIdBatchEnd};
|
||||
|
||||
TEST(FlViewAccessibleTest, BuildTree) {
|
||||
g_autoptr(FlEngine) engine = make_mock_engine();
|
||||
g_autoptr(FlViewAccessible) accessible = FL_VIEW_ACCESSIBLE(
|
||||
g_object_new(fl_view_accessible_get_type(), "engine", engine, nullptr));
|
||||
|
||||
const int32_t children[] = {111, 222};
|
||||
const FlutterSemanticsNode root_node = {
|
||||
int32_t children[] = {111, 222};
|
||||
FlutterSemanticsNode2 root_node = {
|
||||
.id = 0,
|
||||
.label = "root",
|
||||
.child_count = 2,
|
||||
.children_in_traversal_order = children,
|
||||
};
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
|
||||
|
||||
const FlutterSemanticsNode child1_node = {.id = 111, .label = "child 1"};
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &child1_node);
|
||||
|
||||
const FlutterSemanticsNode child2_node = {.id = 222, .label = "child 2"};
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &child2_node);
|
||||
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &kBatchEndNode);
|
||||
FlutterSemanticsNode2 child1_node = {.id = 111, .label = "child 1"};
|
||||
FlutterSemanticsNode2 child2_node = {.id = 222, .label = "child 2"};
|
||||
FlutterSemanticsNode2* nodes[3] = {&root_node, &child1_node, &child2_node};
|
||||
FlutterSemanticsUpdate2 update = {.node_count = 3, .nodes = nodes};
|
||||
fl_view_accessible_handle_update_semantics(accessible, &update);
|
||||
|
||||
AtkObject* root_object =
|
||||
atk_object_ref_accessible_child(ATK_OBJECT(accessible), 0);
|
||||
@ -59,14 +52,14 @@ TEST(FlViewAccessibleTest, AddRemoveChildren) {
|
||||
g_autoptr(FlViewAccessible) accessible = FL_VIEW_ACCESSIBLE(
|
||||
g_object_new(fl_view_accessible_get_type(), "engine", engine, nullptr));
|
||||
|
||||
FlutterSemanticsNode root_node = {
|
||||
FlutterSemanticsNode2 root_node = {
|
||||
.id = 0,
|
||||
.label = "root",
|
||||
.child_count = 0,
|
||||
};
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
|
||||
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &kBatchEndNode);
|
||||
FlutterSemanticsNode2* nodes[1] = {&root_node};
|
||||
FlutterSemanticsUpdate2 update = {.node_count = 1, .nodes = nodes};
|
||||
fl_view_accessible_handle_update_semantics(accessible, &update);
|
||||
|
||||
AtkObject* root_object =
|
||||
atk_object_ref_accessible_child(ATK_OBJECT(accessible), 0);
|
||||
@ -74,21 +67,19 @@ TEST(FlViewAccessibleTest, AddRemoveChildren) {
|
||||
|
||||
// add child1
|
||||
AtkObject* child1_object = nullptr;
|
||||
FlutterSemanticsNode2 child1_node = {.id = 111, .label = "child 1"};
|
||||
{
|
||||
flutter::testing::MockSignalHandler2<gint, AtkObject*> child1_added(
|
||||
root_object, "children-changed::add");
|
||||
EXPECT_SIGNAL2(child1_added, ::testing::Eq(0), ::testing::A<AtkObject*>())
|
||||
.WillOnce(::testing::SaveArg<1>(&child1_object));
|
||||
|
||||
const int32_t children[] = {111};
|
||||
int32_t children[] = {111};
|
||||
root_node.child_count = 1;
|
||||
root_node.children_in_traversal_order = children;
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
|
||||
|
||||
const FlutterSemanticsNode child1_node = {.id = 111, .label = "child 1"};
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &child1_node);
|
||||
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &kBatchEndNode);
|
||||
FlutterSemanticsNode2* nodes[2] = {&root_node, &child1_node};
|
||||
FlutterSemanticsUpdate2 update = {.node_count = 2, .nodes = nodes};
|
||||
fl_view_accessible_handle_update_semantics(accessible, &update);
|
||||
}
|
||||
|
||||
EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 1);
|
||||
@ -101,21 +92,19 @@ TEST(FlViewAccessibleTest, AddRemoveChildren) {
|
||||
|
||||
// add child2
|
||||
AtkObject* child2_object = nullptr;
|
||||
FlutterSemanticsNode2 child2_node = {.id = 222, .label = "child 2"};
|
||||
{
|
||||
flutter::testing::MockSignalHandler2<gint, AtkObject*> child2_added(
|
||||
root_object, "children-changed::add");
|
||||
EXPECT_SIGNAL2(child2_added, ::testing::Eq(1), ::testing::A<AtkObject*>())
|
||||
.WillOnce(::testing::SaveArg<1>(&child2_object));
|
||||
|
||||
const int32_t children[] = {111, 222};
|
||||
int32_t children[] = {111, 222};
|
||||
root_node.child_count = 2;
|
||||
root_node.children_in_traversal_order = children;
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
|
||||
|
||||
const FlutterSemanticsNode child2_node = {.id = 222, .label = "child 2"};
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &child2_node);
|
||||
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &kBatchEndNode);
|
||||
FlutterSemanticsNode2* nodes[3] = {&root_node, &child1_node, &child2_node};
|
||||
FlutterSemanticsUpdate2 update = {.node_count = 3, .nodes = nodes};
|
||||
fl_view_accessible_handle_update_semantics(accessible, &update);
|
||||
}
|
||||
|
||||
EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 2);
|
||||
@ -142,9 +131,9 @@ TEST(FlViewAccessibleTest, AddRemoveChildren) {
|
||||
const int32_t children[] = {222};
|
||||
root_node.child_count = 1;
|
||||
root_node.children_in_traversal_order = children;
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
|
||||
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &kBatchEndNode);
|
||||
FlutterSemanticsNode2* nodes[3] = {&root_node, &child2_node};
|
||||
FlutterSemanticsUpdate2 update = {.node_count = 2, .nodes = nodes};
|
||||
fl_view_accessible_handle_update_semantics(accessible, &update);
|
||||
}
|
||||
|
||||
EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 1);
|
||||
@ -163,9 +152,9 @@ TEST(FlViewAccessibleTest, AddRemoveChildren) {
|
||||
::testing::Eq(child2_object));
|
||||
|
||||
root_node.child_count = 0;
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
|
||||
|
||||
fl_view_accessible_handle_update_semantics_node(accessible, &kBatchEndNode);
|
||||
FlutterSemanticsNode2* nodes[1] = {&root_node};
|
||||
FlutterSemanticsUpdate2 update = {.node_count = 1, .nodes = nodes};
|
||||
fl_view_accessible_handle_update_semantics(accessible, &update);
|
||||
}
|
||||
|
||||
EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user