OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ash/shell.h" | |
6 #include "chrome/browser/chromeos/accessibility/accessibility_highlight_manager. h" | |
7 #include "chrome/browser/chromeos/ui/accessibility_focus_ring_controller.h" | |
8 #include "content/public/browser/focused_node_details.h" | |
9 #include "content/public/browser/notification_service.h" | |
10 #include "content/public/browser/notification_types.h" | |
11 #include "ui/aura/window_tree_host.h" | |
12 | |
13 namespace chromeos { | |
14 | |
15 namespace { | |
16 | |
17 const gfx::Rect& OffscreenRect() { | |
18 CR_DEFINE_STATIC_LOCAL(const gfx::Rect, r, (INT_MIN, INT_MIN, 0, 0)); | |
19 return r; | |
20 } | |
21 | |
22 const gfx::Point& OffscreenPoint() { | |
23 CR_DEFINE_STATIC_LOCAL(const gfx::Point, p, (INT_MIN, INT_MIN)); | |
24 return p; | |
25 } | |
26 | |
27 ui::InputMethod* GetInputMethod(aura::Window* root_window) { | |
28 if (root_window->GetHost()) | |
29 return root_window->GetHost()->GetInputMethod(); | |
30 return nullptr; | |
31 } | |
32 | |
33 } // namespace | |
34 | |
35 AccessibilityHighlightManager::AccessibilityHighlightManager() { | |
36 ash::Shell::GetInstance()->AddPreTargetHandler(this); | |
37 registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, | |
38 content::NotificationService::AllSources()); | |
39 aura::Window* root_window = ash::Shell::GetPrimaryRootWindow(); | |
40 ui::InputMethod* input_method = GetInputMethod(root_window); | |
41 input_method->AddObserver(this); | |
42 focus_rect_ = OffscreenRect(); | |
43 cursor_point_ = OffscreenPoint(); | |
44 caret_point_ = OffscreenPoint(); | |
45 } | |
46 | |
47 AccessibilityHighlightManager::~AccessibilityHighlightManager() { | |
48 // No need to do anything during shutdown | |
49 if (!ash::Shell::HasInstance()) | |
50 return; | |
51 | |
52 ash::Shell* shell = ash::Shell::GetInstance(); | |
53 if (shell) { | |
54 shell->RemovePreTargetHandler(this); | |
55 | |
56 AccessibilityFocusRingController::GetInstance()->SetFocusRing( | |
57 std::vector<gfx::Rect>()); | |
58 AccessibilityFocusRingController::GetInstance()->SetCaretRing( | |
59 OffscreenPoint()); | |
60 AccessibilityFocusRingController::GetInstance()->SetCursorRing( | |
61 OffscreenPoint()); | |
62 | |
63 aura::Window* root_window = shell->GetPrimaryRootWindow(); | |
64 ui::InputMethod* input_method = GetInputMethod(root_window); | |
65 input_method->RemoveObserver(this); | |
66 } | |
67 } | |
68 | |
69 void AccessibilityHighlightManager::HighlightFocus(bool focus) { | |
70 focus_ = focus; | |
71 | |
72 std::vector<gfx::Rect> rects; | |
73 rects.push_back(focus_ ? focus_rect_ : OffscreenRect()); | |
74 AccessibilityFocusRingController::GetInstance()->SetFocusRing(rects); | |
75 } | |
76 | |
77 void AccessibilityHighlightManager::HighlightCursor(bool cursor) { | |
78 cursor_ = cursor; | |
79 | |
80 AccessibilityFocusRingController::GetInstance()->SetCursorRing( | |
81 cursor_ ? cursor_point_ : OffscreenPoint()); | |
82 } | |
83 | |
84 void AccessibilityHighlightManager::HighlightCaret(bool caret) { | |
85 caret_ = caret; | |
86 | |
87 AccessibilityFocusRingController::GetInstance()->SetCaretRing( | |
88 caret_ ? caret_point_ : OffscreenPoint()); | |
89 } | |
90 | |
91 void AccessibilityHighlightManager::OnMouseEvent(ui::MouseEvent* event) { | |
92 if (event->type() == ui::ET_MOUSE_MOVED) { | |
93 cursor_point_ = event->root_location(); | |
xiyuan
2016/03/21 22:59:31
Think we should use event->location() instead of r
dmazzoni
2016/03/22 04:09:30
Done. I'll do some more testing with multi-monitor
| |
94 AccessibilityFocusRingController::GetInstance()->SetCursorRing( | |
95 cursor_ ? cursor_point_ : OffscreenPoint()); | |
96 } | |
97 } | |
98 | |
99 void AccessibilityHighlightManager::Observe( | |
100 int type, | |
101 const content::NotificationSource& source, | |
102 const content::NotificationDetails& details) { | |
103 DCHECK_EQ(type, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE); | |
104 content::FocusedNodeDetails* node_details = | |
105 content::Details<content::FocusedNodeDetails>(details).ptr(); | |
106 focus_rect_ = node_details->node_bounds_in_screen; | |
107 | |
108 if (focus_) { | |
109 std::vector<gfx::Rect> rects; | |
110 rects.push_back(focus_rect_); | |
111 AccessibilityFocusRingController::GetInstance()->SetFocusRing(rects); | |
112 } | |
113 } | |
114 | |
115 void AccessibilityHighlightManager::OnTextInputStateChanged( | |
116 const ui::TextInputClient* client) { | |
117 if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) { | |
118 caret_point_ = OffscreenPoint(); | |
119 if (caret_) { | |
120 AccessibilityFocusRingController::GetInstance()->SetCaretRing( | |
121 caret_point_); | |
122 } | |
123 } | |
124 } | |
125 | |
126 void AccessibilityHighlightManager::OnCaretBoundsChanged( | |
127 const ui::TextInputClient* client) { | |
128 gfx::Rect caret_bounds = client->GetCaretBounds(); | |
129 if (caret_bounds.width() == 0 && caret_bounds.height() == 0) | |
130 caret_bounds = OffscreenRect(); | |
131 caret_point_ = caret_bounds.CenterPoint(); | |
132 | |
133 if (caret_) | |
134 AccessibilityFocusRingController::GetInstance()->SetCaretRing(caret_point_); | |
135 } | |
136 | |
137 } // namespace chromeos | |
OLD | NEW |