diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index af33b000f9eb16..b37775c983eaa7 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc @@ -2914,7 +2914,11 @@ int AXPlatformNodeWin::MSAARole() { return ROLE_SYSTEM_GROUPING; case AX_ROLE_WINDOW: - return ROLE_SYSTEM_WINDOW; + // Do not return ROLE_SYSTEM_WINDOW as that is a special MSAA system role + // used to indicate a real native window object. It is automatically + // created by oleacc.dll as a parent of the root of our hierarchy, + // matching the HWND. + return ROLE_SYSTEM_APPLICATION; // TODO(dmazzoni): figure out the proper MSAA role for roles listed below. case AX_ROLE_BLOCKQUOTE: diff --git a/ui/views/accessibility/native_view_accessibility_win_unittest.cc b/ui/views/accessibility/native_view_accessibility_win_unittest.cc index 0968e7f4ff9f3a..9a4d5647ec18bd 100644 --- a/ui/views/accessibility/native_view_accessibility_win_unittest.cc +++ b/ui/views/accessibility/native_view_accessibility_win_unittest.cc @@ -280,5 +280,22 @@ TEST_F(NativeViewAccessibilityWinTest, GetAllOwnedWidgetsCrash) { EXPECT_EQ(1L, child_count); } +TEST_F(NativeViewAccessibilityWinTest, WindowHasRoleApplication) { + // We expect that our internal window object does not expose + // ROLE_SYSTEM_WINDOW, but ROLE_SYSTEM_APPLICATION instead. + Widget widget; + Widget::InitParams init_params = + CreateParams(Widget::InitParams::TYPE_WINDOW); + init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + widget.Init(init_params); + + ComPtr accessible( + widget.GetRootView()->GetNativeViewAccessible()); + ScopedVariant childid_self(CHILDID_SELF); + ScopedVariant role; + EXPECT_EQ(S_OK, accessible->get_accRole(childid_self, role.Receive())); + EXPECT_EQ(role.type(), VT_I4); + EXPECT_EQ(V_I4(role.ptr()), ROLE_SYSTEM_APPLICATION); +} } // namespace test } // namespace views