From e4cabae56f47b33f165116adbd1228305faa7a07 Mon Sep 17 00:00:00 2001 From: Michael Goderbauer Date: Wed, 24 Jan 2018 15:08:29 -0800 Subject: [PATCH] Add a11y support for selected text (#4584) --- lib/ui/semantics.dart | 9 +++++++++ lib/ui/semantics/semantics_node.h | 2 ++ lib/ui/semantics/semantics_update_builder.cc | 4 ++++ lib/ui/semantics/semantics_update_builder.h | 2 ++ .../android/io/flutter/view/AccessibilityBridge.java | 10 +++++++++- shell/platform/android/platform_view_android.cc | 4 +++- 6 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/ui/semantics.dart b/lib/ui/semantics.dart index 4b9a7f1e81..926f464bb5 100644 --- a/lib/ui/semantics.dart +++ b/lib/ui/semantics.dart @@ -293,6 +293,9 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 { /// string describes what result an action performed on this node has. The /// reading direction of all these strings is given by `textDirection`. /// + /// The fields 'textSelectionStart' and 'textSelectionEnd' describe the + /// currently selected text within `value`. + /// /// The `rect` is the region occupied by this node in its own coordinate /// system. /// @@ -302,6 +305,8 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 { int id, int flags, int actions, + int textSelectionStart, + int textSelectionEnd, Rect rect, String label, String hint, @@ -318,6 +323,8 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 { id, flags, actions, + textSelectionStart, + textSelectionEnd, rect.left, rect.top, rect.right, @@ -336,6 +343,8 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 { int id, int flags, int actions, + int textSelectionStart, + int textSelectionEnd, double left, double top, double right, diff --git a/lib/ui/semantics/semantics_node.h b/lib/ui/semantics/semantics_node.h index 2db9d9cfa8..61a97c9367 100644 --- a/lib/ui/semantics/semantics_node.h +++ b/lib/ui/semantics/semantics_node.h @@ -55,6 +55,8 @@ struct SemanticsNode { int32_t id = 0; int32_t flags = 0; int32_t actions = 0; + int32_t textSelectionStart = -1; + int32_t textSelectionEnd = -1; std::string label; std::string hint; std::string value; diff --git a/lib/ui/semantics/semantics_update_builder.cc b/lib/ui/semantics/semantics_update_builder.cc index 49de90b6bc..7896747792 100644 --- a/lib/ui/semantics/semantics_update_builder.cc +++ b/lib/ui/semantics/semantics_update_builder.cc @@ -37,6 +37,8 @@ SemanticsUpdateBuilder::~SemanticsUpdateBuilder() = default; void SemanticsUpdateBuilder::updateNode(int id, int flags, int actions, + int textSelectionStart, + int textSelectionEnd, double left, double top, double right, @@ -53,6 +55,8 @@ void SemanticsUpdateBuilder::updateNode(int id, node.id = id; node.flags = flags; node.actions = actions; + node.textSelectionStart = textSelectionStart; + node.textSelectionEnd = textSelectionEnd; node.rect = SkRect::MakeLTRB(left, top, right, bottom); node.label = label; node.hint = hint; diff --git a/lib/ui/semantics/semantics_update_builder.h b/lib/ui/semantics/semantics_update_builder.h index ae8cbee7ad..160816823d 100644 --- a/lib/ui/semantics/semantics_update_builder.h +++ b/lib/ui/semantics/semantics_update_builder.h @@ -28,6 +28,8 @@ class SemanticsUpdateBuilder void updateNode(int id, int flags, int actions, + int textSelectionStart, + int textSelectionEnd, double left, double top, double right, diff --git a/shell/platform/android/io/flutter/view/AccessibilityBridge.java b/shell/platform/android/io/flutter/view/AccessibilityBridge.java index 02327c14fe..4ae2dfbe49 100644 --- a/shell/platform/android/io/flutter/view/AccessibilityBridge.java +++ b/shell/platform/android/io/flutter/view/AccessibilityBridge.java @@ -123,8 +123,12 @@ class AccessibilityBridge extends AccessibilityNodeProvider implements BasicMess if (object.hasFlag(Flag.IS_TEXT_FIELD)) { result.setClassName("android.widget.EditText"); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { result.setEditable(true); + if (object.textSelectionStart != -1 && object.textSelectionEnd != -1) { + result.setTextSelection(object.textSelectionStart, object.textSelectionEnd); + } + } // Cursor movements int granularities = 0; @@ -599,6 +603,8 @@ class AccessibilityBridge extends AccessibilityNodeProvider implements BasicMess int flags; int actions; + int textSelectionStart; + int textSelectionEnd; String label; String value; String increasedValue; @@ -658,6 +664,8 @@ class AccessibilityBridge extends AccessibilityNodeProvider implements BasicMess flags = buffer.getInt(); actions = buffer.getInt(); + textSelectionStart = buffer.getInt(); + textSelectionEnd = buffer.getInt(); int stringIndex = buffer.getInt(); label = stringIndex == -1 ? null : strings[stringIndex]; diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index 1dbc2634d2..be6cc26b1f 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -461,7 +461,7 @@ bool PlatformViewAndroid::ResourceContextMakeCurrent() { void PlatformViewAndroid::UpdateSemantics( std::vector update) { - constexpr size_t kBytesPerNode = 30 * sizeof(int32_t); + constexpr size_t kBytesPerNode = 32 * sizeof(int32_t); constexpr size_t kBytesPerChild = sizeof(int32_t); JNIEnv* env = fml::jni::AttachCurrentThread(); @@ -488,6 +488,8 @@ void PlatformViewAndroid::UpdateSemantics( buffer_int32[position++] = node.id; buffer_int32[position++] = node.flags; buffer_int32[position++] = node.actions; + buffer_int32[position++] = node.textSelectionStart; + buffer_int32[position++] = node.textSelectionEnd; if (node.label.empty()) { buffer_int32[position++] = -1; } else { -- GitLab