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

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

Issue 2393123002: Implement caching asynchronous accessibility hit testing. (Closed)
Patch Set: 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 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 ui::AXTreeSource<const ui::AXNode*, ui::AXNodeData, ui::AXTreeData>> 1072 ui::AXTreeSource<const ui::AXNode*, ui::AXNodeData, ui::AXTreeData>>
1070 tree_source(tree_->CreateTreeSource()); 1073 tree_source(tree_->CreateTreeSource());
1071 ui::AXTreeSerializer<const ui::AXNode*, 1074 ui::AXTreeSerializer<const ui::AXNode*,
1072 ui::AXNodeData, 1075 ui::AXNodeData,
1073 ui::AXTreeData> serializer(tree_source.get()); 1076 ui::AXTreeData> serializer(tree_source.get());
1074 ui::AXTreeUpdate update; 1077 ui::AXTreeUpdate update;
1075 serializer.SerializeChanges(tree_->root(), &update); 1078 serializer.SerializeChanges(tree_->root(), &update);
1076 return update; 1079 return update;
1077 } 1080 }
1078 1081
1082 BrowserAccessibility* BrowserAccessibilityManager::CachingAsyncHitTest(
1083 const gfx::Point& screen_point) {
1084 BrowserAccessibilityManager* root_manager = GetRootManager();
1085 if (root_manager && root_manager != this)
1086 return root_manager->CachingAsyncHitTest(screen_point);
1087
1088 if (!delegate())
1089 return nullptr;
1090
1091 // This triggers an asynchronous request to compute the true object that's
1092 // under |screen_point|.
1093 gfx::Point local_point = screen_point - GetViewBounds().OffsetFromOrigin();
1094 delegate()->AccessibilityHitTest(local_point);
1095
1096 // Unfortunately we still have to return an answer synchronously because
1097 // the APIs were designed that way. The best case scenario is that the
1098 // screen point is within the bounds of the last result we got from a
1099 // call to AccessibilityHitTest - in that case, we can return that object!
1100 if (last_hover_bounds_.Contains(screen_point)) {
1101 BrowserAccessibilityManager* manager =
1102 BrowserAccessibilityManager::FromID(last_hover_ax_tree_id_);
1103 if (manager) {
1104 BrowserAccessibility* node = manager->GetFromID(last_hover_node_id_);
1105 if (node)
1106 return node;
1107 }
1108 }
1109
1110 // If that test failed we have to fall back on searching the accessibility
1111 // tree locally for the best bounding box match. This is generally right
1112 // for simple pages but wrong in cases of z-index, overflow, and other
1113 // more complicated layouts. The hope is that if the user is moving the
1114 // mouse, this fallback will only be used transiently, and the asynchronous
1115 // result will be used for the next call.
1116 return GetRoot()->ApproximateHitTest(screen_point);
1117 }
1118
1119 void BrowserAccessibilityManager::CacheHitTestResult(
1120 BrowserAccessibility* hit_test_result) {
1121 // Walk up to the highest ancestor that's a leaf node; we don't want to
1122 // return a node that's hidden from the tree.
1123 BrowserAccessibility* parent = hit_test_result->GetParent();
1124 while (parent) {
1125 if (parent->PlatformChildCount() == 0)
1126 hit_test_result = parent;
1127 parent = parent->GetParent();
1128 }
1129
1130 last_hover_ax_tree_id_ = hit_test_result->manager()->ax_tree_id();
1131 last_hover_node_id_ = hit_test_result->GetId();
1132 last_hover_bounds_ = hit_test_result->GetScreenBoundsRect();
1133 }
1134
1079 } // namespace content 1135 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698