diff --git a/lib/ui/semantics.dart b/lib/ui/semantics.dart index 7258042544cfd8ff5ab3d08154a775666d8fee74..fde5f6be8997cd555423957bb0d01c1d038d52a9 100644 --- a/lib/ui/semantics.dart +++ b/lib/ui/semantics.dart @@ -112,6 +112,7 @@ class SemanticsAction { class SemanticsFlags { static const int _kHasCheckedStateIndex = 1 << 0; static const int _kIsCheckedIndex = 1 << 1; + static const int _kIsSelectedIndex = 1 << 2; const SemanticsFlags._(this.index); @@ -133,12 +134,22 @@ class SemanticsFlags { /// For example, if a checkbox has a visible checkmark, [isChecked] is true. static const SemanticsFlags isChecked = const SemanticsFlags._(_kIsCheckedIndex); + + /// Whether a semantics node is selected. + /// + /// If true, the semantics node is "selected". If false, the semantics node is + /// "unselected". + /// + /// For example, the active tab in a tab bar has [isSelected] set to true. + static const SemanticsFlags isSelected = const SemanticsFlags._(_kIsSelectedIndex); + /// The possible semantics flags. /// /// The map's key is the [index] of the flag and the value is the flag itself. static final Map values = const { _kHasCheckedStateIndex: hasCheckedState, _kIsCheckedIndex: isChecked, + _kIsSelectedIndex: isSelected, }; @override @@ -148,6 +159,8 @@ class SemanticsFlags { return 'SemanticsFlags.hasCheckedState'; case _kIsCheckedIndex: return 'SemanticsFlags.isChecked'; + case _kIsSelectedIndex: + return 'SemanticsFlags.isSelected'; } return null; } diff --git a/lib/ui/semantics/semantics_node.h b/lib/ui/semantics/semantics_node.h index e221d3173716448cfb87eacdded8cd116cb64b89..0dd6e3dd3b858bc378fb2fcbeae831a22af8313e 100644 --- a/lib/ui/semantics/semantics_node.h +++ b/lib/ui/semantics/semantics_node.h @@ -31,6 +31,7 @@ enum class SemanticsAction : int32_t { enum class SemanticsFlags : int32_t { kHasCheckedState = 1 << 0, kIsChecked = 1 << 1, + kIsSelected = 1 << 2, }; struct SemanticsNode { diff --git a/shell/platform/android/io/flutter/view/AccessibilityBridge.java b/shell/platform/android/io/flutter/view/AccessibilityBridge.java index 9336f1a45f3022076445d0b0d00eb5d09e4897d2..77d894d1903fc7fcc16ecbd3335827c7e8b26cd7 100644 --- a/shell/platform/android/io/flutter/view/AccessibilityBridge.java +++ b/shell/platform/android/io/flutter/view/AccessibilityBridge.java @@ -48,6 +48,7 @@ class AccessibilityBridge extends AccessibilityNodeProvider { private static final int SEMANTICS_FLAG_HAS_CHECKED_STATE = 1 << 0; private static final int SEMANTICS_FLAG_IS_CHECKED = 1 << 1; + private static final int SEMANTICS_FLAG_IS_SELECTED = 1 << 2; AccessibilityBridge(FlutterView owner) { assert owner != null; @@ -119,6 +120,7 @@ class AccessibilityBridge extends AccessibilityNodeProvider { result.setCheckable((object.flags & SEMANTICS_FLAG_HAS_CHECKED_STATE) != 0); result.setChecked((object.flags & SEMANTICS_FLAG_IS_CHECKED) != 0); + result.setSelected((object.flags & SEMANTICS_FLAG_IS_SELECTED) != 0); result.setText(object.label); // TODO(ianh): use setTraversalBefore/setTraversalAfter to set diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm index 6c65644eb0d82235adb623e4ae6a807ce0ea2550..6feeaa27c5a4d6ee21edbd54c6650375068d7cbf 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm @@ -116,6 +116,10 @@ blink::SemanticsAction GetSemanticsActionForScrollDirection( _node.HasAction(blink::SemanticsAction::kDecrease)) { traits |= UIAccessibilityTraitAdjustable; } + if (_node.HasFlag(blink::SemanticsFlags::kIsSelected) || + _node.HasFlag(blink::SemanticsFlags::kIsChecked)) { + traits |= UIAccessibilityTraitSelected; + } return traits; }