Commit c9c86ac1 authored by dmazzoni's avatar dmazzoni Committed by Commit bot

Draw a focus ring around native views when ChromeVox is running.

Previously a focus ring was only drawn around web elements; this uses a
new API to draw the focus ring around native views, too, by adding a new
field to the existing private accessibility API with the bounding rect of
the focused view.

BUG=314889

Review URL: https://codereview.chromium.org/600063002

Cr-Commit-Position: refs/heads/master@{#296970}
parent 03f26fbf
...@@ -63,6 +63,14 @@ void AccessibilityControlInfo::SerializeToDict( ...@@ -63,6 +63,14 @@ void AccessibilityControlInfo::SerializeToDict(
dict->SetString(keys::kTypeKey, type()); dict->SetString(keys::kTypeKey, type());
if (!context_.empty()) if (!context_.empty())
dict->SetString(keys::kContextKey, context_); dict->SetString(keys::kContextKey, context_);
if (!bounds_.IsEmpty()) {
base::DictionaryValue* bounds_value = new base::DictionaryValue();
bounds_value->SetInteger(keys::kLeft, bounds_.x());
bounds_value->SetInteger(keys::kTop, bounds_.y());
bounds_value->SetInteger(keys::kWidth, bounds_.width());
bounds_value->SetInteger(keys::kHeight, bounds_.height());
dict->Set(keys::kBoundsKey, bounds_value);
}
} }
AccessibilityWindowInfo::AccessibilityWindowInfo(Profile* profile, AccessibilityWindowInfo::AccessibilityWindowInfo(Profile* profile,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <string> #include <string>
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "ui/accessibility/ax_enums.h" #include "ui/accessibility/ax_enums.h"
#include "ui/gfx/rect.h"
class AccessibilityControlInfo; class AccessibilityControlInfo;
class AccessibilityMenuInfo; class AccessibilityMenuInfo;
...@@ -70,6 +71,9 @@ class AccessibilityControlInfo : public AccessibilityEventInfo { ...@@ -70,6 +71,9 @@ class AccessibilityControlInfo : public AccessibilityEventInfo {
const std::string& context() const { return context_; } const std::string& context() const { return context_; }
void set_bounds(const gfx::Rect& bounds) { bounds_ = bounds; }
const gfx::Rect& bounds() const { return bounds_; }
protected: protected:
AccessibilityControlInfo(Profile* profile, AccessibilityControlInfo(Profile* profile,
const std::string& name); const std::string& name);
...@@ -82,6 +86,9 @@ class AccessibilityControlInfo : public AccessibilityEventInfo { ...@@ -82,6 +86,9 @@ class AccessibilityControlInfo : public AccessibilityEventInfo {
// A string describing the context of the control, such as the name of // A string describing the context of the control, such as the name of
// the group or toolbar it's contained in. // the group or toolbar it's contained in.
std::string context_; std::string context_;
// The bounds of the control in global screen coordinates.
gfx::Rect bounds_;
}; };
// Accessibility information about a window passed to onWindowOpened // Accessibility information about a window passed to onWindowOpened
......
...@@ -323,10 +323,10 @@ bool AccessibilityPrivateSetFocusRingFunction::RunSync() { ...@@ -323,10 +323,10 @@ bool AccessibilityPrivateSetFocusRingFunction::RunSync() {
base::DictionaryValue* rect_value = NULL; base::DictionaryValue* rect_value = NULL;
EXTENSION_FUNCTION_VALIDATE(rect_values->GetDictionary(i, &rect_value)); EXTENSION_FUNCTION_VALIDATE(rect_values->GetDictionary(i, &rect_value));
int left, top, width, height; int left, top, width, height;
EXTENSION_FUNCTION_VALIDATE(rect_value->GetInteger("left", &left)); EXTENSION_FUNCTION_VALIDATE(rect_value->GetInteger(keys::kLeft, &left));
EXTENSION_FUNCTION_VALIDATE(rect_value->GetInteger("top", &top)); EXTENSION_FUNCTION_VALIDATE(rect_value->GetInteger(keys::kTop, &top));
EXTENSION_FUNCTION_VALIDATE(rect_value->GetInteger("width", &width)); EXTENSION_FUNCTION_VALIDATE(rect_value->GetInteger(keys::kWidth, &width));
EXTENSION_FUNCTION_VALIDATE(rect_value->GetInteger("height", &height)); EXTENSION_FUNCTION_VALIDATE(rect_value->GetInteger(keys::kHeight, &height));
rects.push_back(gfx::Rect(left, top, width, height)); rects.push_back(gfx::Rect(left, top, width, height));
} }
......
...@@ -23,6 +23,7 @@ const char kCheckedKey[] = "details.isChecked"; ...@@ -23,6 +23,7 @@ const char kCheckedKey[] = "details.isChecked";
const char kHasSubmenuKey[] = "details.hasSubmenu"; const char kHasSubmenuKey[] = "details.hasSubmenu";
const char kMessageKey[] = "message"; const char kMessageKey[] = "message";
const char kStringValueKey[] = "details.stringValue"; const char kStringValueKey[] = "details.stringValue";
const char kBoundsKey[] = "bounds";
// Types of controls that can receive accessibility events. // Types of controls that can receive accessibility events.
const char kTypeAlert[] = "alert"; const char kTypeAlert[] = "alert";
...@@ -42,6 +43,12 @@ const char kTypeTree[] = "tree"; ...@@ -42,6 +43,12 @@ const char kTypeTree[] = "tree";
const char kTypeTreeItem[] = "treeitem"; const char kTypeTreeItem[] = "treeitem";
const char kTypeWindow[] = "window"; const char kTypeWindow[] = "window";
// ScreenRect fields.
const char kLeft[] = "left";
const char kTop[] = "top";
const char kWidth[] = "width";
const char kHeight[] = "height";
// Errors. // Errors.
const char kErrorNotSupported[] = "This API is not supported on this platform."; const char kErrorNotSupported[] = "This API is not supported on this platform.";
......
...@@ -26,6 +26,7 @@ extern const char kCheckedKey[]; ...@@ -26,6 +26,7 @@ extern const char kCheckedKey[];
extern const char kHasSubmenuKey[]; extern const char kHasSubmenuKey[];
extern const char kMessageKey[]; extern const char kMessageKey[];
extern const char kStringValueKey[]; extern const char kStringValueKey[];
extern const char kBoundsKey[];
// Types of controls that can receive accessibility events. // Types of controls that can receive accessibility events.
extern const char kTypeAlert[]; extern const char kTypeAlert[];
...@@ -46,6 +47,12 @@ extern const char kTypeTreeItem[]; ...@@ -46,6 +47,12 @@ extern const char kTypeTreeItem[];
extern const char kTypeVolume[]; extern const char kTypeVolume[];
extern const char kTypeWindow[]; extern const char kTypeWindow[];
// ScreenRect fields.
extern const char kLeft[];
extern const char kTop[];
extern const char kWidth[];
extern const char kHeight[];
// Errors. // Errors.
extern const char kErrorNotSupported[]; extern const char kErrorNotSupported[];
......
...@@ -162,6 +162,12 @@ cvox.AccessibilityApiHandler.prototype.setWebContext = function() { ...@@ -162,6 +162,12 @@ cvox.AccessibilityApiHandler.prototype.setWebContext = function() {
this.lastContext = '--internal-web--'; this.lastContext = '--internal-web--';
this.editableTextHandler = null; this.editableTextHandler = null;
this.editableTextName = ''; this.editableTextName = '';
if (chrome.accessibilityPrivate.setFocusRing &&
cvox.ChromeVox.isChromeOS) {
// Clear the focus ring.
chrome.accessibilityPrivate.setFocusRing([]);
}
}; };
/** /**
...@@ -401,6 +407,12 @@ cvox.AccessibilityApiHandler.prototype.onControlFocused = function(ctl) { ...@@ -401,6 +407,12 @@ cvox.AccessibilityApiHandler.prototype.onControlFocused = function(ctl) {
return; return;
} }
if (ctl.bounds &&
chrome.accessibilityPrivate.setFocusRing &&
cvox.ChromeVox.isChromeOS) {
chrome.accessibilityPrivate.setFocusRing([ctl.bounds]);
}
// Call this first because it may clear this.editableTextHandler. // Call this first because it may clear this.editableTextHandler.
var description = this.describe(ctl, false); var description = this.describe(ctl, false);
......
...@@ -52,6 +52,14 @@ chrome.accessibilityPrivate.setNativeAccessibilityEnabled = function(on) { ...@@ -52,6 +52,14 @@ chrome.accessibilityPrivate.setNativeAccessibilityEnabled = function(on) {
chrome.accessibilityPrivate.getAlertsForTab = chrome.accessibilityPrivate.getAlertsForTab =
function(tabId, callback) {}; function(tabId, callback) {};
/**
* @param {Array.<{left: number, top: number, width: number, height: number}>}
* rects The bounding rects to draw focus ring(s) around, in global
* screen coordinates.
*/
chrome.accessibilityPrivate.setFocusRing = function(rects) {
};
/** @type ChromeEvent */ /** @type ChromeEvent */
chrome.accessibilityPrivate.onWindowOpened; chrome.accessibilityPrivate.onWindowOpened;
......
...@@ -262,6 +262,7 @@ void AccessibilityEventRouterViews::SendTabNotification( ...@@ -262,6 +262,7 @@ void AccessibilityEventRouterViews::SendTabNotification(
std::string name = base::UTF16ToUTF8(state.name); std::string name = base::UTF16ToUTF8(state.name);
std::string context = GetViewContext(view); std::string context = GetViewContext(view);
AccessibilityTabInfo info(profile, name, context, state.index, state.count); AccessibilityTabInfo info(profile, name, context, state.index, state.count);
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
...@@ -272,6 +273,7 @@ void AccessibilityEventRouterViews::SendButtonNotification( ...@@ -272,6 +273,7 @@ void AccessibilityEventRouterViews::SendButtonNotification(
Profile* profile) { Profile* profile) {
AccessibilityButtonInfo info( AccessibilityButtonInfo info(
profile, GetViewName(view), GetViewContext(view)); profile, GetViewName(view), GetViewContext(view));
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
...@@ -282,6 +284,7 @@ void AccessibilityEventRouterViews::SendStaticTextNotification( ...@@ -282,6 +284,7 @@ void AccessibilityEventRouterViews::SendStaticTextNotification(
Profile* profile) { Profile* profile) {
AccessibilityStaticTextInfo info( AccessibilityStaticTextInfo info(
profile, GetViewName(view), GetViewContext(view)); profile, GetViewName(view), GetViewContext(view));
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
...@@ -291,6 +294,7 @@ void AccessibilityEventRouterViews::SendLinkNotification( ...@@ -291,6 +294,7 @@ void AccessibilityEventRouterViews::SendLinkNotification(
ui::AXEvent event, ui::AXEvent event,
Profile* profile) { Profile* profile) {
AccessibilityLinkInfo info(profile, GetViewName(view), GetViewContext(view)); AccessibilityLinkInfo info(profile, GetViewName(view), GetViewContext(view));
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
...@@ -300,6 +304,7 @@ void AccessibilityEventRouterViews::SendMenuNotification( ...@@ -300,6 +304,7 @@ void AccessibilityEventRouterViews::SendMenuNotification(
ui::AXEvent event, ui::AXEvent event,
Profile* profile) { Profile* profile) {
AccessibilityMenuInfo info(profile, GetViewName(view)); AccessibilityMenuInfo info(profile, GetViewName(view));
info.set_bounds(view->GetBoundsInScreen());
SendMenuAccessibilityNotification(event, &info); SendMenuAccessibilityNotification(event, &info);
} }
...@@ -330,6 +335,7 @@ void AccessibilityEventRouterViews::SendMenuItemNotification( ...@@ -330,6 +335,7 @@ void AccessibilityEventRouterViews::SendMenuItemNotification(
AccessibilityMenuItemInfo info( AccessibilityMenuItemInfo info(
profile, name, context, has_submenu, index, count); profile, name, context, has_submenu, index, count);
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
...@@ -339,6 +345,7 @@ void AccessibilityEventRouterViews::SendTreeNotification( ...@@ -339,6 +345,7 @@ void AccessibilityEventRouterViews::SendTreeNotification(
ui::AXEvent event, ui::AXEvent event,
Profile* profile) { Profile* profile) {
AccessibilityTreeInfo info(profile, GetViewName(view)); AccessibilityTreeInfo info(profile, GetViewName(view));
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
...@@ -384,6 +391,7 @@ void AccessibilityEventRouterViews::SendTreeItemNotification( ...@@ -384,6 +391,7 @@ void AccessibilityEventRouterViews::SendTreeItemNotification(
AccessibilityTreeItemInfo info( AccessibilityTreeItemInfo info(
profile, name, context, depth, index, siblings_count, children_count, profile, name, context, depth, index, siblings_count, children_count,
is_expanded); is_expanded);
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
...@@ -400,6 +408,7 @@ void AccessibilityEventRouterViews::SendTextfieldNotification( ...@@ -400,6 +408,7 @@ void AccessibilityEventRouterViews::SendTextfieldNotification(
AccessibilityTextBoxInfo info(profile, name, context, password); AccessibilityTextBoxInfo info(profile, name, context, password);
std::string value = base::UTF16ToUTF8(state.value); std::string value = base::UTF16ToUTF8(state.value);
info.SetValue(value, state.selection_start, state.selection_end); info.SetValue(value, state.selection_start, state.selection_end);
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
...@@ -415,6 +424,7 @@ void AccessibilityEventRouterViews::SendComboboxNotification( ...@@ -415,6 +424,7 @@ void AccessibilityEventRouterViews::SendComboboxNotification(
std::string context = GetViewContext(view); std::string context = GetViewContext(view);
AccessibilityComboBoxInfo info( AccessibilityComboBoxInfo info(
profile, name, context, value, state.index, state.count); profile, name, context, value, state.index, state.count);
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
...@@ -432,6 +442,7 @@ void AccessibilityEventRouterViews::SendCheckboxNotification( ...@@ -432,6 +442,7 @@ void AccessibilityEventRouterViews::SendCheckboxNotification(
name, name,
context, context,
state.HasStateFlag(ui::AX_STATE_CHECKED)); state.HasStateFlag(ui::AX_STATE_CHECKED));
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
...@@ -454,6 +465,7 @@ void AccessibilityEventRouterViews::SendWindowNotification( ...@@ -454,6 +465,7 @@ void AccessibilityEventRouterViews::SendWindowNotification(
window_text = base::UTF16ToUTF8(state.name); window_text = base::UTF16ToUTF8(state.name);
AccessibilityWindowInfo info(profile, window_text); AccessibilityWindowInfo info(profile, window_text);
info.set_bounds(view->GetBoundsInScreen());
SendWindowAccessibilityNotification(event, &info); SendWindowAccessibilityNotification(event, &info);
} }
...@@ -473,6 +485,7 @@ void AccessibilityEventRouterViews::SendSliderNotification( ...@@ -473,6 +485,7 @@ void AccessibilityEventRouterViews::SendSliderNotification(
name, name,
context, context,
value); value);
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
...@@ -488,6 +501,7 @@ void AccessibilityEventRouterViews::SendAlertControlNotification( ...@@ -488,6 +501,7 @@ void AccessibilityEventRouterViews::SendAlertControlNotification(
AccessibilityAlertInfo info( AccessibilityAlertInfo info(
profile, profile,
name); name);
info.set_bounds(view->GetBoundsInScreen());
SendControlAccessibilityNotification(event, &info); SendControlAccessibilityNotification(event, &info);
} }
......
...@@ -123,6 +123,17 @@ ...@@ -123,6 +123,17 @@
} }
} }
}, },
{
"id": "ScreenRect",
"type": "object",
"description": "Bounding rectangle in global screen coordinates.",
"properties": {
"left": {"type": "integer", "description": "Left coordinate in global screen coordinates."},
"top": {"type": "integer", "description": "Top coordinate in global screen coordinates."},
"width": {"type": "integer", "description": "Width in pixels."},
"height": {"type": "integer", "description": "Height in pixels."}
}
},
{ {
"id": "AccessibilityObject", "id": "AccessibilityObject",
"type": "object", "type": "object",
...@@ -157,19 +168,13 @@ ...@@ -157,19 +168,13 @@
{ "$ref": "TreeDetails" }, { "$ref": "TreeDetails" },
{ "$ref": "TreeItemDetails" } { "$ref": "TreeItemDetails" }
] ]
},
"bounds": {
"$ref": "ScreenRect",
"description": "The bounds of the object, in global screen coordinates.",
"optional": true
} }
} }
},
{
"id": "ScreenRect",
"type": "object",
"description": "Bounding rectangle in global screen coordinates.",
"properties": {
"left": {"type": "integer", "description": "Left coordinate in global screen coordinates."},
"top": {"type": "integer", "description": "Top coordinate in global screen coordinates."},
"width": {"type": "integer", "description": "Width in pixels."},
"height": {"type": "integer", "description": "Height in pixels."}
}
} }
], ],
"functions": [ "functions": [
......
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