Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(300)

Side by Side Diff: content/browser/accessibility/browser_accessibility_manager.cc

Issue 2393123002: Implement caching asynchronous accessibility hit testing. (Closed)
Patch Set: Made test more robust Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/accessibility/browser_accessibility_manager.h" 5 #include "content/browser/accessibility/browser_accessibility_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 osk_state_ = OSK_ALLOWED; 391 osk_state_ = OSK_ALLOWED;
392 } 392 }
393 393
394 // We already handled all focus events above. 394 // We already handled all focus events above.
395 continue; 395 continue;
396 } 396 }
397 397
398 // Fire the native event. 398 // Fire the native event.
399 BrowserAccessibility* event_target = GetFromAXNode(node); 399 BrowserAccessibility* event_target = GetFromAXNode(node);
400 if (event_target) { 400 if (event_target) {
401 if (event_type == ui::AX_EVENT_HOVER)
402 GetRootManager()->CacheHitTestResult(event_target);
403
401 NotifyAccessibilityEvent( 404 NotifyAccessibilityEvent(
402 BrowserAccessibilityEvent::FromBlink, 405 BrowserAccessibilityEvent::FromBlink,
403 event_type, 406 event_type,
404 event_target); 407 event_target);
405 } 408 }
406 } 409 }
407 } 410 }
408 411
409 void BrowserAccessibilityManager::OnLocationChanges( 412 void BrowserAccessibilityManager::OnLocationChanges(
410 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) { 413 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) {
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
1088 ui::AXTreeSource<const ui::AXNode*, ui::AXNodeData, ui::AXTreeData>> 1091 ui::AXTreeSource<const ui::AXNode*, ui::AXNodeData, ui::AXTreeData>>
1089 tree_source(tree_->CreateTreeSource()); 1092 tree_source(tree_->CreateTreeSource());
1090 ui::AXTreeSerializer<const ui::AXNode*, 1093 ui::AXTreeSerializer<const ui::AXNode*,
1091 ui::AXNodeData, 1094 ui::AXNodeData,
1092 ui::AXTreeData> serializer(tree_source.get()); 1095 ui::AXTreeData> serializer(tree_source.get());
1093 ui::AXTreeUpdate update; 1096 ui::AXTreeUpdate update;
1094 serializer.SerializeChanges(tree_->root(), &update); 1097 serializer.SerializeChanges(tree_->root(), &update);
1095 return update; 1098 return update;
1096 } 1099 }
1097 1100
1101 BrowserAccessibility* BrowserAccessibilityManager::CachingAsyncHitTest(
1102 const gfx::Point& screen_point) {
1103 BrowserAccessibilityManager* root_manager = GetRootManager();
1104 if (root_manager && root_manager != this)
1105 return root_manager->CachingAsyncHitTest(screen_point);
1106
1107 if (delegate()) {
1108 // This triggers an asynchronous request to compute the true object that's
1109 // under |screen_point|.
1110 gfx::Point local_point = screen_point - GetViewBounds().OffsetFromOrigin();
1111 delegate()->AccessibilityHitTest(local_point);
1112
1113 // Unfortunately we still have to return an answer synchronously because
1114 // the APIs were designed that way. The best case scenario is that the
1115 // screen point is within the bounds of the last result we got from a
1116 // call to AccessibilityHitTest - in that case, we can return that object!
1117 if (last_hover_bounds_.Contains(screen_point)) {
1118 BrowserAccessibilityManager* manager =
1119 BrowserAccessibilityManager::FromID(last_hover_ax_tree_id_);
1120 if (manager) {
1121 BrowserAccessibility* node = manager->GetFromID(last_hover_node_id_);
1122 if (node)
1123 return node;
1124 }
1125 }
1126 }
1127
1128 // If that test failed we have to fall back on searching the accessibility
1129 // tree locally for the best bounding box match. This is generally right
1130 // for simple pages but wrong in cases of z-index, overflow, and other
1131 // more complicated layouts. The hope is that if the user is moving the
1132 // mouse, this fallback will only be used transiently, and the asynchronous
1133 // result will be used for the next call.
1134 return GetRoot()->ApproximateHitTest(screen_point);
1135 }
1136
1137 void BrowserAccessibilityManager::CacheHitTestResult(
1138 BrowserAccessibility* hit_test_result) {
1139 // Walk up to the highest ancestor that's a leaf node; we don't want to
1140 // return a node that's hidden from the tree.
1141 BrowserAccessibility* parent = hit_test_result->GetParent();
1142 while (parent) {
1143 if (parent->PlatformChildCount() == 0)
1144 hit_test_result = parent;
1145 parent = parent->GetParent();
1146 }
1147
1148 last_hover_ax_tree_id_ = hit_test_result->manager()->ax_tree_id();
1149 last_hover_node_id_ = hit_test_result->GetId();
1150 last_hover_bounds_ = hit_test_result->GetScreenBoundsRect();
1151 }
1152
1098 } // namespace content 1153 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698