未验证 提交 a00f9458 编写于 作者: M Michael Goderbauer 提交者: GitHub

Add accessibilityFocus and loseAccessibilityFocus as a11y actions (#4655)

上级 8ac6f6ef
......@@ -24,6 +24,8 @@ class SemanticsAction {
static const int _kCopyIndex = 1 << 12;
static const int _kCutIndex = 1 << 13;
static const int _kPasteIndex = 1 << 14;
static const int _kDidGainAccessibilityFocusIndex = 1 << 15;
static const int _kDidLoseAccessibilityFocusIndex = 1 << 16;
/// The numerical value for this action.
///
......@@ -118,6 +120,32 @@ class SemanticsAction {
/// Paste the current content of the clipboard.
static const SemanticsAction paste = const SemanticsAction._(_kPasteIndex);
/// Indicates that the nodes has gained accessibility focus.
///
/// This handler is invoked when the node annotated with this handler gains
/// the accessibility focus. The accessibility focus is the
/// green (on Android with TalkBack) or black (on iOS with VoiceOver)
/// rectangle shown on screen to indicate what element an accessibility
/// user is currently interacting with.
///
/// The accessibility focus is different from the input focus. The input focus
/// is usually held by the element that currently responds to keyboard inputs.
/// Accessibility focus and input focus can be held by two different nodes!
static const SemanticsAction didGainAccessibilityFocus = const SemanticsAction._(_kDidGainAccessibilityFocusIndex);
/// Indicates that the nodes has lost accessibility focus.
///
/// This handler is invoked when the node annotated with this handler
/// loses the accessibility focus. The accessibility focus is
/// the green (on Android with TalkBack) or black (on iOS with VoiceOver)
/// rectangle shown on screen to indicate what element an accessibility
/// user is currently interacting with.
///
/// The accessibility focus is different from the input focus. The input focus
/// is usually held by the element that currently responds to keyboard inputs.
/// Accessibility focus and input focus can be held by two different nodes!
static const SemanticsAction didLoseAccessibilityFocus = const SemanticsAction._(_kDidLoseAccessibilityFocusIndex);
/// The possible semantics actions.
///
/// The map's key is the [index] of the action and the value is the action
......@@ -138,6 +166,8 @@ class SemanticsAction {
_kCopyIndex: copy,
_kCutIndex: cut,
_kPasteIndex: paste,
_kDidGainAccessibilityFocusIndex: didGainAccessibilityFocus,
_kDidLoseAccessibilityFocusIndex: didLoseAccessibilityFocus,
};
@override
......@@ -173,6 +203,10 @@ class SemanticsAction {
return 'SemanticsAction.cut';
case _kPasteIndex:
return 'SemanticsAction.paste';
case _kDidGainAccessibilityFocusIndex:
return 'SemanticsAction.didGainAccessibilityFocus';
case _kDidLoseAccessibilityFocusIndex:
return 'SemanticsAction.didLoseAccessibilityFocus';
}
return null;
}
......
......@@ -26,6 +26,15 @@ enum class SemanticsAction : int32_t {
kScrollDown = 1 << 5,
kIncrease = 1 << 6,
kDecrease = 1 << 7,
kShowOnScreen = 1 << 8,
kMoveCursorForwardByCharacter = 1 << 9,
kMoveCursorBackwardByCharacter = 1 << 10,
kSetSelection = 1 << 11,
kCopy = 1 << 12,
kCut = 1 << 13,
kPaste = 1 << 14,
kDidGainAccessibilityFocus = 1 << 15,
kDidLoseAccessibilityFocus = 1 << 16,
};
const int kScrollableSemanticsActions =
......
......@@ -63,7 +63,9 @@ class AccessibilityBridge extends AccessibilityNodeProvider implements BasicMess
SET_SELECTION(1 << 11),
COPY(1 << 12),
CUT(1 << 13),
PASTE(1 << 14);
PASTE(1 << 14),
DID_GAIN_ACCESSIBILITY_FOCUS(1 << 15),
DID_LOSE_ACCESSIBILITY_FOCUS(1 << 16);
Action(int value) {
this.value = value;
......@@ -312,11 +314,13 @@ class AccessibilityBridge extends AccessibilityNodeProvider implements BasicMess
return performCursorMoveAction(object, virtualViewId, arguments, true);
}
case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: {
mOwner.dispatchSemanticsAction(virtualViewId, Action.DID_LOSE_ACCESSIBILITY_FOCUS);
sendAccessibilityEvent(virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
mA11yFocusedObject = null;
return true;
}
case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: {
mOwner.dispatchSemanticsAction(virtualViewId, Action.DID_GAIN_ACCESSIBILITY_FOCUS);
sendAccessibilityEvent(virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
if (mA11yFocusedObject == null) {
......
......@@ -257,6 +257,20 @@ bool GeometryComparator(SemanticsObject* a, SemanticsObject* b) {
return YES;
}
#pragma mark UIAccessibilityFocus overrides
- (void)accessibilityElementDidBecomeFocused {
if ([self node].HasAction(blink::SemanticsAction::kDidGainAccessibilityFocus)) {
[self bridge] -> DispatchSemanticsAction([self uid], blink::SemanticsAction::kDidGainAccessibilityFocus);
}
}
- (void)accessibilityElementDidLoseFocus {
if ([self node].HasAction(blink::SemanticsAction::kDidLoseAccessibilityFocus)) {
[self bridge] -> DispatchSemanticsAction([self uid], blink::SemanticsAction::kDidLoseAccessibilityFocus);
}
}
@end
@implementation FlutterSemanticsObject {
......
......@@ -224,10 +224,12 @@
- (void)accessibilityElementDidBecomeFocused {
[[self textInputSurrogate] accessibilityElementDidBecomeFocused];
[super accessibilityElementDidBecomeFocused];
}
- (void)accessibilityElementDidLoseFocus {
[[self textInputSurrogate] accessibilityElementDidLoseFocus];
[super accessibilityElementDidLoseFocus];
}
- (BOOL)accessibilityElementIsFocused {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册