diff options
author | ctguil@chromium.org <ctguil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-06 00:44:59 +0000 |
---|---|---|
committer | ctguil@chromium.org <ctguil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-06 00:44:59 +0000 |
commit | e12e3f689c07014a9cd5f1b0a626f7d136e12ef8 (patch) | |
tree | 4e4a4256d230d78c23ff8e2ae4a1a3de461b5a8a | |
parent | de4817b40830c7d3af8c63e1f5ae14dde042fed0 (diff) | |
download | chromium_src-e12e3f689c07014a9cd5f1b0a626f7d136e12ef8.zip chromium_src-e12e3f689c07014a9cd5f1b0a626f7d136e12ef8.tar.gz chromium_src-e12e3f689c07014a9cd5f1b0a626f7d136e12ef8.tar.bz2 |
Enable better NVDA support for custom menus.
- Send the popupmenu events on the MenuScrollViewContainer since it is the View with the ROLE_MENUPOPUP role.
- Return AccessibilityTypes::STATE_FOCUSED for MenuScrollViewContainer since it's not focused by MenuHostWin::ShowMenuHost. NVDA won't process children menu item's focus events unless a parent claims to have focus.
TEST=The wrench menu and it's menu items are read aloud when using NVDA.
BUG=49360
Review URL: http://codereview.chromium.org/3015055
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55163 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/views/wrench_menu.cc | 4 | ||||
-rw-r--r-- | views/accessibility/accessibility_types.h | 3 | ||||
-rw-r--r-- | views/accessibility/view_accessibility.cc | 2 | ||||
-rw-r--r-- | views/controls/menu/menu_controller.cc | 11 | ||||
-rw-r--r-- | views/controls/menu/menu_scroll_view_container.cc | 9 | ||||
-rw-r--r-- | views/controls/menu/menu_scroll_view_container.h | 1 | ||||
-rw-r--r-- | views/controls/menu/submenu_view.cc | 14 |
7 files changed, 32 insertions, 12 deletions
diff --git a/chrome/browser/views/wrench_menu.cc b/chrome/browser/views/wrench_menu.cc index 292ca51..5697115 100644 --- a/chrome/browser/views/wrench_menu.cc +++ b/chrome/browser/views/wrench_menu.cc @@ -22,6 +22,7 @@ #include "gfx/canvas.h" #include "gfx/canvas_skia.h" #include "gfx/skia_util.h" +#include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "third_party/skia/include/core/SkPaint.h" @@ -483,7 +484,7 @@ class WrenchMenu::ZoomView : public ScheduleAllView, } double GetZoom(bool* enable_increment, bool* enable_decrement) { - // TODO: move this somewhere it can be shared. + // TODO(sky): move this somewhere it can be shared. TabContents* selected_tab = menu_->browser_->GetSelectedTabContents(); *enable_decrement = *enable_increment = false; if (!selected_tab) @@ -563,6 +564,7 @@ WrenchMenu::~WrenchMenu() { void WrenchMenu::Init(menus::MenuModel* model) { DCHECK(!root_.get()); root_.reset(new MenuItemView(this)); + root_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_APP)); root_->set_has_icons(true); // We have checks, radios and icons, set this // so we get the taller menu style. int next_id = 1; diff --git a/views/accessibility/accessibility_types.h b/views/accessibility/accessibility_types.h index 4718d69..eccf14f 100644 --- a/views/accessibility/accessibility_types.h +++ b/views/accessibility/accessibility_types.h @@ -38,7 +38,8 @@ class AccessibilityTypes { STATE_PROTECTED = 1 << 10, STATE_READONLY = 1 << 11, STATE_SELECTED = 1 << 12, - STATE_UNAVAILABLE = 1 << 13 + STATE_FOCUSED = 1 << 13, + STATE_UNAVAILABLE = 1 << 14 }; // This defines an enumeration of the supported accessibility roles in our diff --git a/views/accessibility/view_accessibility.cc b/views/accessibility/view_accessibility.cc index 8bb9ed4..4a9c0b3 100644 --- a/views/accessibility/view_accessibility.cc +++ b/views/accessibility/view_accessibility.cc @@ -878,6 +878,8 @@ int32 ViewAccessibility::MSAAState(AccessibilityTypes::State state) { msaa_state |= STATE_SYSTEM_READONLY; if (state & AccessibilityTypes::STATE_SELECTED) msaa_state |= STATE_SYSTEM_SELECTED; + if (state & AccessibilityTypes::STATE_FOCUSED) + msaa_state |= STATE_SYSTEM_FOCUSED; if (state & AccessibilityTypes::STATE_UNAVAILABLE) msaa_state |= STATE_SYSTEM_UNAVAILABLE; return msaa_state; diff --git a/views/controls/menu/menu_controller.cc b/views/controls/menu/menu_controller.cc index 3d49366..d5abe50 100644 --- a/views/controls/menu/menu_controller.cc +++ b/views/controls/menu/menu_controller.cc @@ -247,9 +247,6 @@ MenuItemView* MenuController::Run(gfx::NativeWindow parent, owner_ = parent; - if (button) - button->NotifyAccessibilityEvent(AccessibilityTypes::EVENT_MENUPOPUPSTART); - // Set the selection, which opens the initial menu. SetSelection(root, true, true); @@ -382,11 +379,6 @@ void MenuController::SetSelection(MenuItemView* menu_item, (MenuDepth(menu_item) != 1 || menu_item->GetType() != MenuItemView::SUBMENU)) menu_item->NotifyAccessibilityEvent(AccessibilityTypes::EVENT_FOCUS); - - if (menu_button_ && !menu_item && exit_type_ != EXIT_DESTROYED) { - menu_button_-> - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_MENUPOPUPEND); - } } void MenuController::Cancel(ExitType type) { @@ -814,7 +806,6 @@ bool MenuController::Dispatch(const MSG& msg) { #else bool MenuController::Dispatch(GdkEvent* event) { - if (exit_type_ == EXIT_ALL || exit_type_ == EXIT_DESTROYED) { gtk_main_do_event(event); return false; @@ -1212,7 +1203,7 @@ void MenuController::CommitPendingSelection() { state_.open_leading.clear(); } else { int cached_size = static_cast<int>(state_.open_leading.size()); - DCHECK(menu_depth >= 0); + DCHECK_GE(menu_depth, 0); while (cached_size-- >= menu_depth) state_.open_leading.pop_back(); } diff --git a/views/controls/menu/menu_scroll_view_container.cc b/views/controls/menu/menu_scroll_view_container.cc index 532366c..a88f0a4 100644 --- a/views/controls/menu/menu_scroll_view_container.cc +++ b/views/controls/menu/menu_scroll_view_container.cc @@ -274,4 +274,13 @@ bool MenuScrollViewContainer::GetAccessibleRole( return true; } +bool MenuScrollViewContainer::GetAccessibleState( + AccessibilityTypes::State* state) { + DCHECK(state); + // Some AT (like NVDA) will not process focus events on menu item children + // unless a parent claims to be focused. + *state = AccessibilityTypes::STATE_FOCUSED; + return true; +} + } // namespace views diff --git a/views/controls/menu/menu_scroll_view_container.h b/views/controls/menu/menu_scroll_view_container.h index cf7788e..41a0188 100644 --- a/views/controls/menu/menu_scroll_view_container.h +++ b/views/controls/menu/menu_scroll_view_container.h @@ -30,6 +30,7 @@ class MenuScrollViewContainer : public View { const gfx::Rect& current); virtual gfx::Size GetPreferredSize(); virtual bool GetAccessibleRole(AccessibilityTypes::Role* role); + virtual bool GetAccessibleState(AccessibilityTypes::State* state); private: class MenuScrollView; diff --git a/views/controls/menu/submenu_view.cc b/views/controls/menu/submenu_view.cc index de74aa1..2cfd8b8 100644 --- a/views/controls/menu/submenu_view.cc +++ b/views/controls/menu/submenu_view.cc @@ -227,6 +227,9 @@ void SubmenuView::ShowAt(gfx::NativeWindow parent, bool do_capture) { if (host_) { host_->ShowMenuHost(do_capture); + + GetScrollViewContainer()->NotifyAccessibilityEvent( + AccessibilityTypes::EVENT_MENUPOPUPSTART); return; } @@ -236,6 +239,9 @@ void SubmenuView::ShowAt(gfx::NativeWindow parent, // Make sure the first row is visible. ScrollRectToVisible(gfx::Rect(gfx::Point(), gfx::Size(1, 1))); host_->Init(parent, bounds, scroll_view_container_, do_capture); + + GetScrollViewContainer()->NotifyAccessibilityEvent( + AccessibilityTypes::EVENT_MENUPOPUPSTART); } void SubmenuView::Reposition(const gfx::Rect& bounds) { @@ -245,6 +251,9 @@ void SubmenuView::Reposition(const gfx::Rect& bounds) { void SubmenuView::Close() { if (host_) { + GetScrollViewContainer()->NotifyAccessibilityEvent( + AccessibilityTypes::EVENT_MENUPOPUPEND); + host_->DestroyMenuHost(); host_ = NULL; } @@ -288,6 +297,11 @@ MenuScrollViewContainer* SubmenuView::GetScrollViewContainer() { scroll_view_container_ = new MenuScrollViewContainer(this); // Otherwise MenuHost would delete us. scroll_view_container_->set_parent_owned(false); + + // Use the parent menu item accessible name for the menu view. + std::wstring accessible_name; + GetMenuItem()->GetAccessibleName(&accessible_name); + scroll_view_container_->SetAccessibleName(accessible_name); } return scroll_view_container_; } |