diff options
26 files changed, 172 insertions, 237 deletions
diff --git a/chrome/browser/accessibility/accessibility_win_browsertest.cc b/chrome/browser/accessibility/accessibility_win_browsertest.cc index 19bb413..87fb544 100644 --- a/chrome/browser/accessibility/accessibility_win_browsertest.cc +++ b/chrome/browser/accessibility/accessibility_win_browsertest.cc @@ -6,6 +6,7 @@ #include <vector> #include "base/memory/scoped_ptr.h" +#include "base/utf_string_conversions.h" #include "base/win/scoped_comptr.h" #include "chrome/browser/automation/ui_controls.h" #include "chrome/browser/renderer_host/render_widget_host_view_win.h" @@ -136,54 +137,53 @@ HRESULT QueryIAccessible2(IAccessible* accessible, IAccessible2** accessible2) { return hr; } -// Sets result to true if the child is located in the parent's tree. An -// exhustive search is perform here because we determine equality using -// IAccessible2::get_unique_id which is only supported by the child node. -void AccessibleContainsAccessible( - IAccessible* parent, IAccessible2* child, bool* result) { - vector<base::win::ScopedComPtr<IAccessible>> accessible_list; - accessible_list.push_back(base::win::ScopedComPtr<IAccessible>(parent)); +// Recursively search through all of the descendants reachable from an +// IAccessible node and return true if we find one with the given role +// and name. +void RecursiveFindNodeInAccessibilityTree( + IAccessible* node, + int32 expected_role, + const wstring& expected_name, + int32 depth, + bool* found) { + CComBSTR name_bstr; + node->get_accName(CreateI4Variant(CHILDID_SELF), &name_bstr); + wstring name(name_bstr.m_str, SysStringLen(name_bstr)); + VARIANT role = {0}; + node->get_accRole(CreateI4Variant(CHILDID_SELF), &role); + + // Print the accessibility tree as we go, because if this test fails + // on the bots, this is really helpful in figuring out why. + for (int i = 0; i < depth; i++) { + printf(" "); + } + printf("role=%d name=%s\n", role.lVal, WideToUTF8(name).c_str()); + + if (expected_role == role.lVal && expected_name == name) { + *found = true; + return; + } - LONG unique_id; - HRESULT hr = child->get_uniqueID(&unique_id); + LONG child_count = 0; + HRESULT hr = node->get_accChildCount(&child_count); ASSERT_EQ(S_OK, hr); - *result = false; - - while (accessible_list.size()) { - base::win::ScopedComPtr<IAccessible> accessible = accessible_list.back(); - accessible_list.pop_back(); - - base::win::ScopedComPtr<IAccessible2> accessible2; - hr = QueryIAccessible2(accessible, accessible2.Receive()); - if (SUCCEEDED(hr)) { - LONG child_id; - accessible2->get_uniqueID(&child_id); - if (child_id == unique_id) { - *result = true; - break; - } - } - LONG child_count; - hr = accessible->get_accChildCount(&child_count); - ASSERT_EQ(S_OK, hr); - if (child_count == 0) - continue; - - scoped_array<VARIANT> child_array(new VARIANT[child_count]); - LONG obtained_count = 0; - hr = AccessibleChildren( - accessible, 0, child_count, child_array.get(), &obtained_count); - ASSERT_EQ(S_OK, hr); - ASSERT_EQ(child_count, obtained_count); - - for (int index = 0; index < obtained_count; index++) { - base::win::ScopedComPtr<IAccessible> child_accessible( - GetAccessibleFromResultVariant(accessible, &child_array.get()[index])); - if (child_accessible.get()) { - accessible_list.push_back( - base::win::ScopedComPtr<IAccessible>(child_accessible)); - } + scoped_array<VARIANT> child_array(new VARIANT[child_count]); + LONG obtained_count = 0; + hr = AccessibleChildren( + node, 0, child_count, child_array.get(), &obtained_count); + ASSERT_EQ(S_OK, hr); + ASSERT_EQ(child_count, obtained_count); + + for (int index = 0; index < obtained_count; index++) { + base::win::ScopedComPtr<IAccessible> child_accessible( + GetAccessibleFromResultVariant(node, &child_array.get()[index])); + if (child_accessible.get()) { + RecursiveFindNodeInAccessibilityTree( + child_accessible.get(), expected_role, expected_name, depth + 1, + found); + if (*found) + return; } } } @@ -589,14 +589,18 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, document_checker.CheckAccessible(GetRendererAccessible()); } -// FAILS crbug.com/54220 -// This test verifies that browser-side cache of the renderer accessibility -// tree is reachable from the browser's tree. Tools that analyze windows -// accessibility trees like AccExplorer32 should be able to drill into the -// cached renderer accessibility tree. +// This test verifies that the web content's accessibility tree is a +// descendant of the main browser window's accessibility tree, so that +// tools like AccExplorer32 or AccProbe can be used to examine Chrome's +// accessibility support. +// +// If you made a change and this test now fails, check that the NativeViewHost +// that wraps the tab contents returns the IAccessible implementation +// provided by RenderWidgetHostViewWin in GetNativeViewAccessible(). IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, - DISABLED_ContainsRendererAccessibilityTree) { - GURL tree_url("data:text/html,<body><input type='checkbox' /></body>"); + ContainsRendererAccessibilityTree) { + GURL tree_url("data:text/html,<html><head><title>MyDocument</title></head>" + "<body>Content</body></html>"); browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED); GetRendererAccessible(); ui_test_utils::WaitForNotification( @@ -612,45 +616,9 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, reinterpret_cast<void**>(browser_accessible.Receive())); ASSERT_EQ(S_OK, hr); - // Get the accessibility object for the renderer client document. - base::win::ScopedComPtr<IAccessible> document_accessible( - GetRendererAccessible()); - ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL)); - base::win::ScopedComPtr<IAccessible2> document_accessible2; - hr = QueryIAccessible2(document_accessible, document_accessible2.Receive()); - ASSERT_EQ(S_OK, hr); - - // TODO(ctguil): Pointer comparison of retrieved IAccessible pointers dosen't - // seem to work for here. Perhaps make IAccessible2 available in views to make - // unique id comparison available. bool found = false; - base::win::ScopedComPtr<IAccessible> parent = document_accessible; - while (parent.get()) { - base::win::ScopedComPtr<IDispatch> parent_dispatch; - hr = parent->get_accParent(parent_dispatch.Receive()); - ASSERT_TRUE(SUCCEEDED(hr)); - if (!parent_dispatch.get()) { - ASSERT_EQ(hr, S_FALSE); - break; - } - - parent.Release(); - hr = parent_dispatch.QueryInterface(parent.Receive()); - ASSERT_EQ(S_OK, hr); - - if (parent.get() == browser_accessible.get()) { - found = true; - break; - } - } - - // If pointer comparison fails resort to the exhuasive search that can use - // IAccessible2::get_unique_id for equality comparison. - if (!found) { - AccessibleContainsAccessible( - browser_accessible, document_accessible2, &found); - } - + RecursiveFindNodeInAccessibilityTree( + browser_accessible.get(), ROLE_SYSTEM_DOCUMENT, L"MyDocument", 0, &found); ASSERT_EQ(found, true); } diff --git a/chrome/browser/accessibility/browser_views_accessibility_browsertest.cc b/chrome/browser/accessibility/browser_views_accessibility_browsertest.cc index a2da782..1ce4578 100644 --- a/chrome/browser/accessibility/browser_views_accessibility_browsertest.cc +++ b/chrome/browser/accessibility/browser_views_accessibility_browsertest.cc @@ -84,10 +84,7 @@ class BrowserViewsAccessibilityTest : public InProcessBrowserTest { int32 role) { ASSERT_TRUE(NULL != view); - TestAccessibilityInfo( - NativeViewAccessibilityWin::GetAccessibleForView(view), - name, - role); + TestAccessibilityInfo(view->GetNativeViewAccessible(), name, role); } diff --git a/chrome/browser/autocomplete/autocomplete_accessibility.cc b/chrome/browser/autocomplete/autocomplete_accessibility.cc index 0801c20..8966f94 100644 --- a/chrome/browser/autocomplete/autocomplete_accessibility.cc +++ b/chrome/browser/autocomplete/autocomplete_accessibility.cc @@ -59,8 +59,7 @@ STDMETHODIMP AutocompleteAccessibility::get_accParent(IDispatch** disp_parent) { } // Retrieve the IDispatch interface for the parent view. - *disp_parent = NativeViewAccessibilityWin::GetAccessibleForView( - omnibox_view_->parent_view()); + *disp_parent = omnibox_view_->parent_view()->GetNativeViewAccessible(); // Increment the reference count for the retrieved interface. (*disp_parent)->AddRef(); return S_OK; diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc index cbc97f6..9cc56ff 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc @@ -508,13 +508,6 @@ void RenderWidgetHostViewWin::Show() { SetParent(parent_hwnd_); ShowWindow(SW_SHOW); - // Save away our HWND in the parent window as a property so that the - // accessibility code can find it. - accessibility_prop_.reset(new ViewProp( - GetParent(), - views::kViewsNativeHostPropForAccessibility, - m_hWnd)); - DidBecomeSelected(); } @@ -525,8 +518,6 @@ void RenderWidgetHostViewWin::Hide() { return; } - accessibility_prop_.reset(); - if (::GetFocus() == m_hWnd) ::SetFocus(NULL); ShowWindow(SW_HIDE); @@ -786,12 +777,6 @@ LRESULT RenderWidgetHostViewWin::OnCreate(CREATESTRUCT* create_struct) { props_.push_back(views::SetWindowSupportsRerouteMouseWheel(m_hWnd)); props_.push_back(new ViewProp(m_hWnd, kRenderWidgetHostViewKey, static_cast<RenderWidgetHostView*>(this))); - // Save away our HWND in the parent window as a property so that the - // accessibility code can find it. - accessibility_prop_.reset(new ViewProp( - GetParent(), - views::kViewsNativeHostPropForAccessibility, - m_hWnd)); return 0; } @@ -1627,6 +1612,24 @@ void RenderWidgetHostViewWin::AccessibilityDoDefaultAction(int acc_obj_id) { render_widget_host_->routing_id(), acc_obj_id)); } +IAccessible* RenderWidgetHostViewWin::GetIAccessible() { + if (render_widget_host_ && !render_widget_host_->renderer_accessible()) { + // Attempt to detect screen readers by sending an event with our custom id. + NotifyWinEvent(EVENT_SYSTEM_ALERT, m_hWnd, kIdCustom, CHILDID_SELF); + } + + if (!browser_accessibility_manager_.get()) { + // Return busy document tree while renderer accessibility tree loads. + webkit_glue::WebAccessibility loading_tree; + loading_tree.role = WebAccessibility::ROLE_DOCUMENT; + loading_tree.state = (1 << WebAccessibility::STATE_BUSY); + browser_accessibility_manager_.reset( + BrowserAccessibilityManager::Create(m_hWnd, loading_tree, this)); + } + + return browser_accessibility_manager_->GetRoot()->toBrowserAccessibilityWin(); +} + LRESULT RenderWidgetHostViewWin::OnGetObject(UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) { if (kIdCustom == lparam) { @@ -1644,24 +1647,9 @@ LRESULT RenderWidgetHostViewWin::OnGetObject(UINT message, WPARAM wparam, return static_cast<LRESULT>(0L); } - if (render_widget_host_ && !render_widget_host_->renderer_accessible()) { - // Attempt to detect screen readers by sending an event with our custom id. - NotifyWinEvent(EVENT_SYSTEM_ALERT, m_hWnd, kIdCustom, CHILDID_SELF); - } - - if (!browser_accessibility_manager_.get()) { - // Return busy document tree while renderer accessibility tree loads. - webkit_glue::WebAccessibility loading_tree; - loading_tree.role = WebAccessibility::ROLE_DOCUMENT; - loading_tree.state = (1 << WebAccessibility::STATE_BUSY); - browser_accessibility_manager_.reset( - BrowserAccessibilityManager::Create(m_hWnd, loading_tree, this)); - } - - base::win::ScopedComPtr<IAccessible> root( - browser_accessibility_manager_->GetRoot()->toBrowserAccessibilityWin()); - if (root.get()) - return LresultFromObject(IID_IAccessible, wparam, root.Detach()); + IAccessible* iaccessible = GetIAccessible(); + if (iaccessible) + return LresultFromObject(IID_IAccessible, wparam, iaccessible); handled = false; return static_cast<LRESULT>(0L); diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.h b/chrome/browser/renderer_host/render_widget_host_view_win.h index ce210ed..42b76d7 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.h +++ b/chrome/browser/renderer_host/render_widget_host_view_win.h @@ -77,6 +77,8 @@ class RenderWidgetHostViewWin void ScheduleComposite(); + IAccessible* GetIAccessible(); + DECLARE_WND_CLASS_EX(kRenderWidgetHostHWNDClass, CS_DBLCLKS, 0); BEGIN_MSG_MAP(RenderWidgetHostHWND) @@ -364,8 +366,6 @@ class RenderWidgetHostViewWin ScopedVector<ui::ViewProp> props_; - scoped_ptr<ui::ViewProp> accessibility_prop_; - DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewWin); }; diff --git a/chrome/browser/ui/views/tab_contents/native_tab_contents_container_win.cc b/chrome/browser/ui/views/tab_contents/native_tab_contents_container_win.cc index 5371099..244c34e 100644 --- a/chrome/browser/ui/views/tab_contents/native_tab_contents_container_win.cc +++ b/chrome/browser/ui/views/tab_contents/native_tab_contents_container_win.cc @@ -4,6 +4,7 @@ #include "chrome/browser/ui/views/tab_contents/native_tab_contents_container_win.h" +#include "chrome/browser/renderer_host/render_widget_host_view_win.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/tab_contents/tab_contents_container.h" #include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h" @@ -135,6 +136,20 @@ void NativeTabContentsContainerWin::GetAccessibleState( state->role = ui::AccessibilityTypes::ROLE_GROUPING; } +gfx::NativeViewAccessible + NativeTabContentsContainerWin::GetNativeViewAccessible() { + TabContents* tab_contents = container_->tab_contents(); + if (tab_contents) { + RenderWidgetHostViewWin* host_view_win = + static_cast<RenderWidgetHostViewWin*>( + tab_contents->GetRenderWidgetHostView()); + if (host_view_win) + return host_view_win->GetIAccessible(); + } + + return View::GetNativeViewAccessible(); +} + //////////////////////////////////////////////////////////////////////////////// // NativeTabContentsContainer, public: diff --git a/chrome/browser/ui/views/tab_contents/native_tab_contents_container_win.h b/chrome/browser/ui/views/tab_contents/native_tab_contents_container_win.h index 4d60be22..d142604 100644 --- a/chrome/browser/ui/views/tab_contents/native_tab_contents_container_win.h +++ b/chrome/browser/ui/views/tab_contents/native_tab_contents_container_win.h @@ -31,6 +31,7 @@ class NativeTabContentsContainerWin : public NativeTabContentsContainer, virtual void RequestFocus() OVERRIDE; virtual void AboutToRequestFocusFromTabTraversal(bool reverse) OVERRIDE; virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; + virtual gfx::NativeViewAccessible GetNativeViewAccessible(); private: TabContentsContainer* container_; diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h index d5846a4..8f00f6e 100644 --- a/ui/gfx/native_widget_types.h +++ b/ui/gfx/native_widget_types.h @@ -39,6 +39,7 @@ #if defined(OS_WIN) #include <windows.h> // NOLINT typedef struct HFONT__* HFONT; +struct IAccessible; #elif defined(OS_MACOSX) struct CGContext; #ifdef __OBJC__ @@ -76,6 +77,7 @@ typedef HDC NativeDrawingContext; typedef HCURSOR NativeCursor; typedef HMENU NativeMenu; typedef HRGN NativeRegion; +typedef IAccessible* NativeViewAccessible; #elif defined(OS_MACOSX) typedef NSFont* NativeFont; typedef NSView* NativeView; @@ -84,6 +86,7 @@ typedef NSTextField* NativeEditView; typedef CGContext* NativeDrawingContext; typedef void* NativeCursor; typedef void* NativeMenu; +typedef void* NativeViewAccessible; #elif defined(USE_X11) typedef PangoFontDescription* NativeFont; typedef GtkWidget* NativeView; @@ -93,6 +96,7 @@ typedef cairo_t* NativeDrawingContext; typedef GdkCursor* NativeCursor; typedef GtkWidget* NativeMenu; typedef GdkRegion* NativeRegion; +typedef void* NativeViewAccessible; #endif #if defined(OS_MACOSX) diff --git a/views/accessibility/native_view_accessibility_win.cc b/views/accessibility/native_view_accessibility_win.cc index 6796afe..e36c406 100644 --- a/views/accessibility/native_view_accessibility_win.cc +++ b/views/accessibility/native_view_accessibility_win.cc @@ -28,33 +28,6 @@ scoped_refptr<NativeViewAccessibilityWin> NativeViewAccessibilityWin::Create( return scoped_refptr<NativeViewAccessibilityWin>(instance); } -// static -IAccessible* NativeViewAccessibilityWin::GetAccessibleForView( - views::View* view) { - IAccessible* accessible = NULL; - - // First, check to see if the view is a native view. - if (view->GetClassName() == views::NativeViewHost::kViewClassName) { - views::NativeViewHost* native_host = - static_cast<views::NativeViewHost*>(view); - if (GetNativeIAccessibleInterface(native_host, &accessible) == S_OK) - return accessible; - } - - // Next, see if the view is a widget container. - if (view->GetChildWidget()) { - views::NativeWidgetWin* native_widget = - reinterpret_cast<views::NativeWidgetWin*>(view->GetChildWidget()); - if (GetNativeIAccessibleInterface( - native_widget->GetNativeView(), &accessible) == S_OK) { - return accessible; - } - } - - // Finally, use our NativeViewAccessibilityWin implementation. - return view->GetNativeViewAccessibilityWin(); -} - NativeViewAccessibilityWin::NativeViewAccessibilityWin() : view_(NULL) { } @@ -86,7 +59,7 @@ STDMETHODIMP NativeViewAccessibilityWin::accHitTest( child->lVal = CHILDID_SELF; } else { child->vt = VT_DISPATCH; - child->pdispVal = GetAccessibleForView(view); + child->pdispVal = view->GetNativeViewAccessible(); child->pdispVal->AddRef(); } return S_OK; @@ -156,7 +129,7 @@ STDMETHODIMP NativeViewAccessibilityWin::accNavigate( views::View* child = view_->GetChildViewAt(child_id); end->vt = VT_DISPATCH; - end->pdispVal = GetAccessibleForView(child); + end->pdispVal = child->GetNativeViewAccessible(); end->pdispVal->AddRef(); return S_OK; } @@ -190,7 +163,7 @@ STDMETHODIMP NativeViewAccessibilityWin::accNavigate( } views::View* child = parent->GetChildViewAt(view_index); - end->pdispVal = GetAccessibleForView(child); + end->pdispVal = child->GetNativeViewAccessible(); end->vt = VT_DISPATCH; end->pdispVal->AddRef(); return S_OK; @@ -270,7 +243,7 @@ STDMETHODIMP NativeViewAccessibilityWin::get_accChild(VARIANT var_child, return E_FAIL; } - *disp_child = GetAccessibleForView(child_view); + *disp_child = child_view->GetNativeViewAccessible(); (*disp_child)->AddRef(); return S_OK; } @@ -344,7 +317,7 @@ STDMETHODIMP NativeViewAccessibilityWin::get_accFocus(VARIANT* focus_child) { focus_child->lVal = CHILDID_SELF; } else if (focus && view_->Contains(focus)) { // Return the child object that has the keyboard focus. - focus_child->pdispVal = GetAccessibleForView(focus); + focus_child->pdispVal = focus->GetNativeViewAccessible(); focus_child->pdispVal->AddRef(); return S_OK; } else { @@ -432,7 +405,7 @@ STDMETHODIMP NativeViewAccessibilityWin::get_accParent( return S_OK; } - *disp_parent = GetAccessibleForView(parent_view); + *disp_parent = parent_view->GetNativeViewAccessible(); (*disp_parent)->AddRef(); return S_OK; } @@ -724,32 +697,3 @@ int32 NativeViewAccessibilityWin::MSAAState(AccessibilityTypes::State state) { msaa_state |= STATE_SYSTEM_UNAVAILABLE; return msaa_state; } - -// static -HRESULT NativeViewAccessibilityWin::GetNativeIAccessibleInterface( - views::NativeViewHost* native_host, IAccessible** accessible) { - if (!native_host || !accessible) - return E_INVALIDARG; - - HWND native_view_window = static_cast<HWND>( - ui::ViewProp::GetValue(native_host->native_view(), - views::kViewsNativeHostPropForAccessibility)); - if (!IsWindow(native_view_window)) { - native_view_window = native_host->native_view(); - } - - return GetNativeIAccessibleInterface(native_view_window, accessible); -} - -// static -HRESULT NativeViewAccessibilityWin::GetNativeIAccessibleInterface( - HWND native_view_window , IAccessible** accessible) { - if (IsWindow(native_view_window)) { - LRESULT ret = SendMessage(native_view_window, WM_GETOBJECT, 0, - OBJID_CLIENT); - return ObjectFromLresult(ret, IID_IDispatch, 0, - reinterpret_cast<void**>(accessible)); - } - - return E_FAIL; -} diff --git a/views/accessibility/native_view_accessibility_win.h b/views/accessibility/native_view_accessibility_win.h index 89708ab..2736160 100644 --- a/views/accessibility/native_view_accessibility_win.h +++ b/views/accessibility/native_view_accessibility_win.h @@ -16,11 +16,8 @@ #include "views/controls/native/native_view_host.h" #include "views/view.h" -namespace views { -extern const char kViewsNativeHostPropForAccessibility[]; // Note: do not put NativeViewAccessibilityWin in the namespace "views"; // Visual Studio 2005 does not allow an ATL::CComObject symbol in a namespace. -} //////////////////////////////////////////////////////////////////////////////// // @@ -43,9 +40,6 @@ class ATL_NO_VTABLE NativeViewAccessibilityWin // Create method for view accessibility. static scoped_refptr<NativeViewAccessibilityWin> Create(views::View* view); - // Returns the IAccessible interface for a view. - static IAccessible* GetAccessibleForView(views::View* view); - virtual ~NativeViewAccessibilityWin(); void set_view(views::View* view) { view_ = view; } @@ -150,14 +144,6 @@ class ATL_NO_VTABLE NativeViewAccessibilityWin // Helper function which sets applicable states of view. void SetState(VARIANT* msaa_state, views::View* view); - // Returns the IAccessible interface for a native view if applicable. - // Returns S_OK on success. - static HRESULT GetNativeIAccessibleInterface( - views::NativeViewHost* native_host, IAccessible** accessible); - - static HRESULT GetNativeIAccessibleInterface( - HWND native_view_window, IAccessible** accessible); - // Give CComObject access to the class constructor. template <class Base> friend class CComObject; diff --git a/views/controls/native/native_view_host.cc b/views/controls/native/native_view_host.cc index 42321e5..1b9d74e 100644 --- a/views/controls/native/native_view_host.cc +++ b/views/controls/native/native_view_host.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -200,6 +200,17 @@ bool NativeViewHost::ContainsNativeView(gfx::NativeView native_view) const { return View::ContainsNativeView(native_view); } +gfx::NativeViewAccessible NativeViewHost::GetNativeViewAccessible() { + if (native_wrapper_.get()) { + gfx::NativeViewAccessible accessible_view = + native_wrapper_->GetNativeViewAccessible(); + if (accessible_view) + return accessible_view; + } + + return View::GetNativeViewAccessible(); +} + //////////////////////////////////////////////////////////////////////////////// // NativeViewHost, private: diff --git a/views/controls/native/native_view_host.h b/views/controls/native/native_view_host.h index e19aca2..30e4ddc 100644 --- a/views/controls/native/native_view_host.h +++ b/views/controls/native/native_view_host.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -82,6 +82,7 @@ class NativeViewHost : public View { virtual void VisibilityChanged(View* starting_from, bool is_visible); virtual void OnFocus(); virtual bool ContainsNativeView(gfx::NativeView native_view) const; + virtual gfx::NativeViewAccessible GetNativeViewAccessible(); protected: virtual bool NeedsNotificationWhenVisibleBoundsChange() const; diff --git a/views/controls/native/native_view_host_gtk.cc b/views/controls/native/native_view_host_gtk.cc index fedbc416..833e4b4 100644 --- a/views/controls/native/native_view_host_gtk.cc +++ b/views/controls/native/native_view_host_gtk.cc @@ -256,6 +256,10 @@ void NativeViewHostGtk::SetFocus() { gtk_widget_grab_focus(host_->native_view()); } +gfx::NativeViewAccessible NativeViewHostGtk::GetNativeViewAccessible() { + return NULL; +} + //////////////////////////////////////////////////////////////////////////////// // NativeViewHostGtk, private: diff --git a/views/controls/native/native_view_host_gtk.h b/views/controls/native/native_view_host_gtk.h index eb98349..0ecfd99 100644 --- a/views/controls/native/native_view_host_gtk.h +++ b/views/controls/native/native_view_host_gtk.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -38,6 +38,7 @@ class NativeViewHostGtk : public NativeViewHostWrapper { virtual void ShowWidget(int x, int y, int w, int h); virtual void HideWidget(); virtual void SetFocus(); + virtual gfx::NativeViewAccessible GetNativeViewAccessible(); private: // Create and Destroy the GtkFixed that performs clipping on our hosted diff --git a/views/controls/native/native_view_host_views.cc b/views/controls/native/native_view_host_views.cc index 7d44818..4b84a05 100644 --- a/views/controls/native/native_view_host_views.cc +++ b/views/controls/native/native_view_host_views.cc @@ -75,4 +75,8 @@ void NativeViewHostViews::SetFocus() { host_->views_view()->RequestFocus(); } +gfx::NativeViewAccessible NativeViewHostViews::GetNativeViewAccessible() { + return NULL; +} + } // namespace views diff --git a/views/controls/native/native_view_host_views.h b/views/controls/native/native_view_host_views.h index 891cf49..cd9f96b 100644 --- a/views/controls/native/native_view_host_views.h +++ b/views/controls/native/native_view_host_views.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -30,6 +30,7 @@ class NativeViewHostViews : public NativeViewHostWrapper { virtual void ShowWidget(int x, int y, int w, int h); virtual void HideWidget(); virtual void SetFocus(); + virtual gfx::NativeViewAccessible GetNativeViewAccessible(); private: // Our associated NativeViewHost. diff --git a/views/controls/native/native_view_host_win.cc b/views/controls/native/native_view_host_win.cc index f25e722..b7fa074 100644 --- a/views/controls/native/native_view_host_win.cc +++ b/views/controls/native/native_view_host_win.cc @@ -4,6 +4,8 @@ #include "views/controls/native/native_view_host_win.h" +#include <oleacc.h> + #include "base/logging.h" #include "ui/gfx/canvas.h" #include "views/controls/native/native_view_host.h" @@ -123,6 +125,22 @@ void NativeViewHostWin::SetFocus() { ::SetFocus(host_->native_view()); } +gfx::NativeViewAccessible NativeViewHostWin::GetNativeViewAccessible() { + HWND hwnd = host_->native_view(); + if (!IsWindow(hwnd)) + return NULL; + + LRESULT ret = SendMessage(hwnd, WM_GETOBJECT, 0, OBJID_CLIENT); + IAccessible* accessible = NULL; + HRESULT success = ObjectFromLresult( + ret, IID_IDispatch, 0, reinterpret_cast<void**>(accessible)); + if (success == S_OK) { + return accessible; + } else { + return NULL; + } +} + //////////////////////////////////////////////////////////////////////////////// // NativeViewHostWrapper, public: diff --git a/views/controls/native/native_view_host_win.h b/views/controls/native/native_view_host_win.h index fb8d8be..e885399 100644 --- a/views/controls/native/native_view_host_win.h +++ b/views/controls/native/native_view_host_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -30,6 +30,7 @@ class NativeViewHostWin : public NativeViewHostWrapper { virtual void ShowWidget(int x, int y, int w, int h); virtual void HideWidget(); virtual void SetFocus(); + virtual gfx::NativeViewAccessible GetNativeViewAccessible(); private: // Our associated NativeViewHost. diff --git a/views/controls/native/native_view_host_wrapper.h b/views/controls/native/native_view_host_wrapper.h index 1b06b3e..8fdd8ad 100644 --- a/views/controls/native/native_view_host_wrapper.h +++ b/views/controls/native/native_view_host_wrapper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,6 +6,8 @@ #define VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_WRAPPER_H_ #pragma once +#include "ui/gfx/native_widget_types.h" + namespace views { class NativeViewHost; @@ -56,6 +58,10 @@ class NativeViewHostWrapper { // Sets focus to the gfx::NativeView. virtual void SetFocus() = 0; + // Return the native view accessible corresponding to the wrapped native + // view. + virtual gfx::NativeViewAccessible GetNativeViewAccessible() = 0; + // Creates a platform-specific instance of an object implementing this // interface. static NativeViewHostWrapper* CreateWrapper(NativeViewHost* host); diff --git a/views/controls/tabbed_pane/native_tabbed_pane_win.cc b/views/controls/tabbed_pane/native_tabbed_pane_win.cc index a585b1b..829d5a3 100644 --- a/views/controls/tabbed_pane/native_tabbed_pane_win.cc +++ b/views/controls/tabbed_pane/native_tabbed_pane_win.cc @@ -364,10 +364,6 @@ void NativeTabbedPaneWin::ViewHierarchyChanged(bool is_add, } } -Widget* NativeTabbedPaneWin::GetChildWidget() { - return content_window_; -} - //////////////////////////////////////////////////////////////////////////////// // NativeTabbedPaneWin, private: diff --git a/views/controls/tabbed_pane/native_tabbed_pane_win.h b/views/controls/tabbed_pane/native_tabbed_pane_win.h index 4fb2a2e..f3e84ea 100644 --- a/views/controls/tabbed_pane/native_tabbed_pane_win.h +++ b/views/controls/tabbed_pane/native_tabbed_pane_win.h @@ -49,7 +49,6 @@ class NativeTabbedPaneWin : public NativeControlWin, virtual void Layout(); virtual FocusTraversable* GetFocusTraversable(); virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child); - virtual Widget* GetChildWidget(); private: // Called upon creation of native control to initialize tabs that are added diff --git a/views/view.cc b/views/view.cc index edc0178..d8e95f1 100644 --- a/views/view.cc +++ b/views/view.cc @@ -89,12 +89,6 @@ bool View::IsHotTracked() const { return false; } -// FATE TBD -------------------------------------------------------------------- - -Widget* View::GetChildWidget() { - return NULL; -} - // Creation and lifetime ------------------------------------------------------- View::View() diff --git a/views/view.h b/views/view.h index 618c53d..cd90af9f 100644 --- a/views/view.h +++ b/views/view.h @@ -172,10 +172,6 @@ class View : public AcceleratorTarget { // Returns whether the view is hot-tracked. virtual bool IsHotTracked() const; - // FATE TBD ------------------------------------------------------------------ - // TODO(beng): Figure out what these methods are for and delete them. - virtual Widget* GetChildWidget(); - // Creation and lifetime ----------------------------------------------------- View(); @@ -872,11 +868,8 @@ class View : public AcceleratorTarget { // Modifies |state| to reflect the current accessible state of this view. virtual void GetAccessibleState(ui::AccessibleViewState* state) { } -#if defined(OS_WIN) - // Returns an instance of the Windows-specific accessibility interface - // for this View. - NativeViewAccessibilityWin* GetNativeViewAccessibilityWin(); -#endif + // Returns an instance of the native accessibility interface for this view. + virtual gfx::NativeViewAccessible GetNativeViewAccessible(); // Scrolling ----------------------------------------------------------------- // TODO(beng): Figure out if this can live somewhere other than View, i.e. @@ -1428,8 +1421,8 @@ class View : public AcceleratorTarget { // Accessibility ------------------------------------------------------------- + // The Windows-specific accessibility implementation for this view. #if defined(OS_WIN) - // The Windows-specific accessibility implementation for this View. scoped_refptr<NativeViewAccessibilityWin> native_view_accessibility_win_; #endif diff --git a/views/view_gtk.cc b/views/view_gtk.cc index 5155099..af62f1e 100644 --- a/views/view_gtk.cc +++ b/views/view_gtk.cc @@ -10,6 +10,11 @@ namespace views { +gfx::NativeViewAccessible View::GetNativeViewAccessible() { + NOTIMPLEMENTED(); + return NULL; +} + int View::GetHorizontalDragThreshold() { static bool determined_threshold = false; static int drag_threshold = 8; diff --git a/views/view_win.cc b/views/view_win.cc index b083dbc..fdfdfb4 100644 --- a/views/view_win.cc +++ b/views/view_win.cc @@ -21,7 +21,7 @@ namespace views { -NativeViewAccessibilityWin* View::GetNativeViewAccessibilityWin() { +gfx::NativeViewAccessible View::GetNativeViewAccessible() { if (!native_view_accessibility_win_.get()) native_view_accessibility_win_ = NativeViewAccessibilityWin::Create(this); diff --git a/views/widget/native_widget_win.cc b/views/widget/native_widget_win.cc index 997d50f..15f03b9 100644 --- a/views/widget/native_widget_win.cc +++ b/views/widget/native_widget_win.cc @@ -1292,8 +1292,7 @@ LRESULT NativeWidgetWin::OnGetObject(UINT uMsg, if (OBJID_CLIENT == l_param) { // Retrieve MSAA dispatch object for the root view. base::win::ScopedComPtr<IAccessible> root( - NativeViewAccessibilityWin::GetAccessibleForView( - GetWidget()->GetRootView())); + GetWidget()->GetRootView()->GetNativeViewAccessible()); // Create a reference that MSAA will marshall to the client. reference_result = LresultFromObject(IID_IAccessible, w_param, |