Unverified Commit 04d3ecb8 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Add accessibilityFocus and loseAccessibilityFocus as a11y actions (#14603)

parent 72517f0a
8ac6f6efa177fb548dcdc81f1501f060b2ad1115
a00f94582b61dec88a140751a8a43d79d525fd8f
......@@ -3022,6 +3022,8 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
MoveCursorHandler onMoveCursorForwardByCharacter,
MoveCursorHandler onMoveCursorBackwardByCharacter,
SetSelectionHandler onSetSelection,
VoidCallback onDidGainAccessibilityFocus,
VoidCallback onDidLoseAccessibilityFocus,
}) : assert(container != null),
_container = container,
_explicitChildNodes = explicitChildNodes,
......@@ -3050,6 +3052,8 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
_onMoveCursorForwardByCharacter = onMoveCursorForwardByCharacter,
_onMoveCursorBackwardByCharacter = onMoveCursorBackwardByCharacter,
_onSetSelection = onSetSelection,
_onDidGainAccessibilityFocus = onDidGainAccessibilityFocus,
_onDidLoseAccessibilityFocus = onDidLoseAccessibilityFocus,
super(child);
/// If 'container' is true, this [RenderObject] will introduce a new
......@@ -3493,6 +3497,62 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
markNeedsSemanticsUpdate();
}
/// The handler for [SemanticsAction.didGainAccessibilityFocus].
///
/// 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!
///
/// See also:
///
/// * [onDidLoseAccessibilityFocus], which is invoked when the accessibility
/// focus is removed from the node
/// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus
VoidCallback get onDidGainAccessibilityFocus => _onDidGainAccessibilityFocus;
VoidCallback _onDidGainAccessibilityFocus;
set onDidGainAccessibilityFocus(VoidCallback handler) {
if (_onDidGainAccessibilityFocus == handler)
return;
final bool hadValue = _onDidGainAccessibilityFocus != null;
_onDidGainAccessibilityFocus = handler;
if ((handler != null) != hadValue)
markNeedsSemanticsUpdate();
}
/// The handler for [SemanticsAction.didLoseAccessibilityFocus].
///
/// 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!
///
/// See also:
///
/// * [onDidGainAccessibilityFocus], which is invoked when the node gains
/// accessibility focus
/// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus
VoidCallback get onDidLoseAccessibilityFocus => _onDidLoseAccessibilityFocus;
VoidCallback _onDidLoseAccessibilityFocus;
set onDidLoseAccessibilityFocus(VoidCallback handler) {
if (_onDidLoseAccessibilityFocus == handler)
return;
final bool hadValue = _onDidLoseAccessibilityFocus != null;
_onDidLoseAccessibilityFocus = handler;
if ((handler != null) != hadValue)
markNeedsSemanticsUpdate();
}
@override
void describeSemanticsConfiguration(SemanticsConfiguration config) {
super.describeSemanticsConfiguration(config);
......@@ -3552,6 +3612,10 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
config.onMoveCursorBackwardByCharacter = _performMoveCursorBackwardByCharacter;
if (onSetSelection != null)
config.onSetSelection = _performSetSelection;
if (onDidGainAccessibilityFocus != null)
config.onDidGainAccessibilityFocus = _performDidGainAccessibilityFocus;
if (onDidLoseAccessibilityFocus != null)
config.onDidLoseAccessibilityFocus = _performDidLoseAccessibilityFocus;
}
void _performTap() {
......@@ -3623,6 +3687,16 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
if (onSetSelection != null)
onSetSelection(selection);
}
void _performDidGainAccessibilityFocus() {
if (onDidGainAccessibilityFocus != null)
onDidGainAccessibilityFocus();
}
void _performDidLoseAccessibilityFocus() {
if (onDidLoseAccessibilityFocus != null)
onDidLoseAccessibilityFocus();
}
}
/// Causes the semantics of all earlier render objects below the same semantic
......
......@@ -329,6 +329,8 @@ class SemanticsProperties extends DiagnosticableTree {
this.onMoveCursorForwardByCharacter,
this.onMoveCursorBackwardByCharacter,
this.onSetSelection,
this.onDidGainAccessibilityFocus,
this.onDidLoseAccessibilityFocus,
});
/// If non-null, indicates that this subtree represents something that can be
......@@ -590,6 +592,44 @@ class SemanticsProperties extends DiagnosticableTree {
/// beginning/end" or "Select all" from the local context menu.
final SetSelectionHandler onSetSelection;
/// The handler for [SemanticsAction.didGainAccessibilityFocus].
///
/// 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!
///
/// See also:
///
/// * [onDidLoseAccessibilityFocus], which is invoked when the accessibility
/// focus is removed from the node
/// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus
final VoidCallback onDidGainAccessibilityFocus;
/// The handler for [SemanticsAction.didLoseAccessibilityFocus].
///
/// 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!
///
/// See also:
///
/// * [onDidGainAccessibilityFocus], which is invoked when the node gains
/// accessibility focus
/// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus
final VoidCallback onDidLoseAccessibilityFocus;
@override
void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description);
......@@ -1977,6 +2017,54 @@ class SemanticsConfiguration {
_onSetSelection = value;
}
/// The handler for [SemanticsAction.didGainAccessibilityFocus].
///
/// 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!
///
/// See also:
///
/// * [onDidLoseAccessibilityFocus], which is invoked when the accessibility
/// focus is removed from the node
/// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus
VoidCallback get onDidGainAccessibilityFocus => _onDidGainAccessibilityFocus;
VoidCallback _onDidGainAccessibilityFocus;
set onDidGainAccessibilityFocus(VoidCallback value) {
_addArgumentlessAction(SemanticsAction.didGainAccessibilityFocus, value);
_onDidGainAccessibilityFocus = value;
}
/// The handler for [SemanticsAction.didLoseAccessibilityFocus].
///
/// 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!
///
/// See also:
///
/// * [onDidGainAccessibilityFocus], which is invoked when the node gains
/// accessibility focus
/// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus
VoidCallback get onDidLoseAccessibilityFocus => _onDidLoseAccessibilityFocus;
VoidCallback _onDidLoseAccessibilityFocus;
set onDidLoseAccessibilityFocus(VoidCallback value) {
_addArgumentlessAction(SemanticsAction.didLoseAccessibilityFocus, value);
_onDidLoseAccessibilityFocus = value;
}
/// Returns the action handler registered for [action] or null if none was
/// registered.
///
......
......@@ -4869,6 +4869,8 @@ class Semantics extends SingleChildRenderObjectWidget {
MoveCursorHandler onMoveCursorForwardByCharacter,
MoveCursorHandler onMoveCursorBackwardByCharacter,
SetSelectionHandler onSetSelection,
VoidCallback onDidGainAccessibilityFocus,
VoidCallback onDidLoseAccessibilityFocus,
}) : this.fromProperties(
key: key,
child: child,
......@@ -4899,6 +4901,8 @@ class Semantics extends SingleChildRenderObjectWidget {
onPaste: onPaste,
onMoveCursorForwardByCharacter: onMoveCursorForwardByCharacter,
onMoveCursorBackwardByCharacter: onMoveCursorBackwardByCharacter,
onDidGainAccessibilityFocus: onDidGainAccessibilityFocus,
onDidLoseAccessibilityFocus: onDidLoseAccessibilityFocus,
onSetSelection: onSetSelection,),
);
......@@ -4977,6 +4981,8 @@ class Semantics extends SingleChildRenderObjectWidget {
onMoveCursorForwardByCharacter: properties.onMoveCursorForwardByCharacter,
onMoveCursorBackwardByCharacter: properties.onMoveCursorBackwardByCharacter,
onSetSelection: properties.onSetSelection,
onDidGainAccessibilityFocus: properties.onDidGainAccessibilityFocus,
onDidLoseAccessibilityFocus: properties.onDidLoseAccessibilityFocus,
);
}
......@@ -5020,7 +5026,9 @@ class Semantics extends SingleChildRenderObjectWidget {
..onPaste = properties.onPaste
..onMoveCursorForwardByCharacter = properties.onMoveCursorForwardByCharacter
..onMoveCursorBackwardByCharacter = properties.onMoveCursorForwardByCharacter
..onSetSelection = properties.onSetSelection;
..onSetSelection = properties.onSetSelection
..onDidGainAccessibilityFocus = properties.onDidGainAccessibilityFocus
..onDidLoseAccessibilityFocus = properties.onDidLoseAccessibilityFocus;
}
@override
......
......@@ -398,6 +398,8 @@ void main() {
onMoveCursorForwardByCharacter: (bool _) => performedActions.add(SemanticsAction.moveCursorForwardByCharacter),
onMoveCursorBackwardByCharacter: (bool _) => performedActions.add(SemanticsAction.moveCursorBackwardByCharacter),
onSetSelection: (TextSelection _) => performedActions.add(SemanticsAction.setSelection),
onDidGainAccessibilityFocus: () => performedActions.add(SemanticsAction.didGainAccessibilityFocus),
onDidLoseAccessibilityFocus: () => performedActions.add(SemanticsAction.didLoseAccessibilityFocus),
)
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment