Commit f1d83b7c authored by Julie Jeongeun Kim's avatar Julie Jeongeun Kim Committed by Commit Bot

[a11y] AXPlatformNodeAuraLinux::HitTestSync recurses into descendants

This CL allows atk_ref_accessible_at_point on the native frame or
panel to hittest web area.

According to the comment from
ViewAXPlatformNodeDelegate::HitTestSync, AXPlatformNode
is supposed to do a recursive hit test and AXPlatformNodeWin
works recursively already. So, AXPlatformNodeAuraLinux hittests
recursively.

The difference between Windows and AuraLinux is that WebArea
is also a descendant of the top window in AuraLinux.

AX-Relnotes: atk_ref_accessible_at_point recurses into descendants.
So, it finds a node from the web page when it's called on the
ancestor of web area.

Bug: 1051616
Change-Id: I03f0a37999fdaf9b2656b7eddc805467657a4b17
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2210291Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Commit-Queue: Julie Kim <jkim@igalia.com>
Cr-Commit-Position: refs/heads/master@{#773020}
parent ab01986e
...@@ -1731,4 +1731,68 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest, ...@@ -1731,4 +1731,68 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
} }
} }
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
HitTestOnAncestorOfWebRoot) {
// Load the page.
LoadInitialAccessibilityTreeFromHtml(R"HTML(
<button>This is a button</button>
)HTML");
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
BrowserAccessibilityManager* manager =
web_contents->GetRootBrowserAccessibilityManager();
// Find a node to hit test. Note that this is a really simple page,
// so synchronous hit testing will work fine.
BrowserAccessibility* node = manager->GetRoot();
while (node && node->GetRole() != ax::mojom::Role::kButton)
node = manager->NextInTreeOrder(node);
DCHECK(node);
// Get the screen bounds of the hit target and find the point in the middle.
gfx::Rect bounds = node->GetClippedScreenBoundsRect();
gfx::Point point = bounds.CenterPoint();
// Get the root AXPlatformNodeAuraLinux.
ui::AXPlatformNodeAuraLinux* root_platform_node =
static_cast<ui::AXPlatformNodeAuraLinux*>(
ui::AXPlatformNode::FromNativeViewAccessible(
manager->GetRoot()->GetNativeViewAccessible()));
// First test that calling accHitTest on the root node returns the button.
{
gfx::NativeViewAccessible hit_child = root_platform_node->HitTestSync(
point.x(), point.y(), AtkCoordType::ATK_XY_SCREEN);
ASSERT_NE(nullptr, hit_child);
ui::AXPlatformNode* hit_child_node =
ui::AXPlatformNode::FromNativeViewAccessible(hit_child);
ASSERT_NE(nullptr, hit_child_node);
EXPECT_EQ(node->GetId(), hit_child_node->GetDelegate()->GetData().id);
}
// Now test it again, but this time caliing accHitTest on the parent
// IAccessible of the web root node.
{
RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
shell()->web_contents()->GetRenderWidgetHostView());
gfx::NativeViewAccessible ancestor = rwhva->GetParentNativeViewAccessible();
ASSERT_NE(nullptr, ancestor);
ui::AXPlatformNodeAuraLinux* ancestor_node =
static_cast<ui::AXPlatformNodeAuraLinux*>(
ui::AXPlatformNode::FromNativeViewAccessible(ancestor));
ASSERT_NE(nullptr, ancestor_node);
gfx::NativeViewAccessible hit_child = ancestor_node->HitTestSync(
point.x(), point.y(), AtkCoordType::ATK_XY_SCREEN);
ASSERT_NE(nullptr, hit_child);
ui::AXPlatformNode* hit_child_node =
ui::AXPlatformNode::FromNativeViewAccessible(hit_child);
ASSERT_NE(nullptr, hit_child_node);
EXPECT_EQ(node->GetId(), hit_child_node->GetDelegate()->GetData().id);
}
}
} // namespace content } // namespace content
...@@ -825,6 +825,7 @@ void RenderWidgetHostViewAura::OnLegacyWindowDestroyed() { ...@@ -825,6 +825,7 @@ void RenderWidgetHostViewAura::OnLegacyWindowDestroyed() {
legacy_render_widget_host_HWND_ = nullptr; legacy_render_widget_host_HWND_ = nullptr;
legacy_window_destroyed_ = true; legacy_window_destroyed_ = true;
} }
#endif
gfx::NativeViewAccessible gfx::NativeViewAccessible
RenderWidgetHostViewAura::GetParentNativeViewAccessible() { RenderWidgetHostViewAura::GetParentNativeViewAccessible() {
...@@ -842,7 +843,6 @@ RenderWidgetHostViewAura::GetParentNativeViewAccessible() { ...@@ -842,7 +843,6 @@ RenderWidgetHostViewAura::GetParentNativeViewAccessible() {
return nullptr; return nullptr;
} }
#endif
void RenderWidgetHostViewAura::ResetFallbackToFirstNavigationSurface() { void RenderWidgetHostViewAura::ResetFallbackToFirstNavigationSurface() {
if (delegated_frame_host_) if (delegated_frame_host_)
......
...@@ -303,9 +303,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAura ...@@ -303,9 +303,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
// Notification that the LegacyRenderWidgetHostHWND was destroyed. // Notification that the LegacyRenderWidgetHostHWND was destroyed.
void OnLegacyWindowDestroyed(); void OnLegacyWindowDestroyed();
#endif
gfx::NativeViewAccessible GetParentNativeViewAccessible(); gfx::NativeViewAccessible GetParentNativeViewAccessible();
#endif
// Method to indicate if this instance is shutting down or closing. // Method to indicate if this instance is shutting down or closing.
// TODO(shrikant): Discuss around to see if it makes sense to add this method // TODO(shrikant): Discuss around to see if it makes sense to add this method
......
...@@ -4176,7 +4176,30 @@ gfx::NativeViewAccessible ...@@ -4176,7 +4176,30 @@ gfx::NativeViewAccessible
AXPlatformNodeAuraLinux::HitTestSync(gint x, gint y, AtkCoordType coord_type) { AXPlatformNodeAuraLinux::HitTestSync(gint x, gint y, AtkCoordType coord_type) {
gfx::Point scroll_to(x, y); gfx::Point scroll_to(x, y);
scroll_to = ConvertPointToScreenCoordinates(scroll_to, coord_type); scroll_to = ConvertPointToScreenCoordinates(scroll_to, coord_type);
return delegate_->HitTestSync(scroll_to.x(), scroll_to.y());
AXPlatformNode* current_result = this;
while (true) {
gfx::NativeViewAccessible hit_child =
current_result->GetDelegate()->HitTestSync(scroll_to.x(),
scroll_to.y());
if (!hit_child)
return nullptr;
AXPlatformNode* hit_child_node =
AXPlatformNode::FromNativeViewAccessible(hit_child);
if (!hit_child_node || !hit_child_node->IsDescendantOf(current_result))
break;
// If we get the same node, we're done.
if (hit_child_node == current_result)
break;
// Continue to check recursively. That's because HitTestSync may have
// returned the best result within a particular accessibility tree,
// but we might need to recurse further in a tree of a different type
// (for example, from Views to Web).
current_result = hit_child_node;
}
return current_result->GetNativeViewAccessible();
} }
bool AXPlatformNodeAuraLinux::GrabFocus() { bool AXPlatformNodeAuraLinux::GrabFocus() {
......
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