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

Side by Side Diff: ash/autoclick/autoclick_controller.cc

Issue 2193563002: ash: Refactor autoclick common code to ash/autoclick/common. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ownership; comments; renames etc Created 4 years, 4 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "ash/autoclick/autoclick_controller.h" 5 #include "ash/autoclick/autoclick_controller.h"
6 6
7 #include "ash/aura/wm_window_aura.h" 7 #include "ash/aura/wm_window_aura.h"
8 #include "ash/autoclick/common/autoclick_controller_common.h"
9 #include "ash/common/shell_window_ids.h"
8 #include "ash/common/wm/root_window_finder.h" 10 #include "ash/common/wm/root_window_finder.h"
9 #include "ash/shell.h" 11 #include "ash/shell.h"
10 #include "base/timer/timer.h" 12 #include "base/timer/timer.h"
11 #include "ui/aura/env.h" 13 #include "ui/aura/window_observer.h"
12 #include "ui/aura/window_tree_host.h" 14 #include "ui/aura/window_tree_host.h"
13 #include "ui/events/event.h" 15 #include "ui/events/event.h"
14 #include "ui/events/event_constants.h"
15 #include "ui/events/event_handler.h" 16 #include "ui/events/event_handler.h"
16 #include "ui/events/event_processor.h" 17 #include "ui/events/event_processor.h"
17 #include "ui/events/event_utils.h" 18 #include "ui/events/event_utils.h"
18 #include "ui/gfx/geometry/point.h" 19 #include "ui/views/widget/widget.h"
19 #include "ui/gfx/geometry/vector2d.h"
20 #include "ui/wm/core/coordinate_conversion.h" 20 #include "ui/wm/core/coordinate_conversion.h"
21 21
22 namespace ash { 22 namespace ash {
23 23
24 namespace {
25
26 // The threshold of mouse movement measured in DIP that will
27 // initiate a new autoclick.
28 const int kMovementThreshold = 20;
29
30 bool IsModifierKey(ui::KeyboardCode key_code) {
31 return key_code == ui::VKEY_SHIFT || key_code == ui::VKEY_LSHIFT ||
32 key_code == ui::VKEY_CONTROL || key_code == ui::VKEY_LCONTROL ||
33 key_code == ui::VKEY_RCONTROL || key_code == ui::VKEY_MENU ||
34 key_code == ui::VKEY_LMENU || key_code == ui::VKEY_RMENU;
35 }
36
37 } // namespace
38
39 // static. 24 // static.
40 base::TimeDelta AutoclickController::GetDefaultAutoclickDelay() { 25 base::TimeDelta AutoclickController::GetDefaultAutoclickDelay() {
41 return base::TimeDelta::FromMilliseconds(int64_t{kDefaultAutoclickDelayMs}); 26 return base::TimeDelta::FromMilliseconds(int64_t{kDefaultAutoclickDelayMs});
42 } 27 }
43 28
44 const int AutoclickController::kDefaultAutoclickDelayMs = 1000; 29 const int AutoclickController::kDefaultAutoclickDelayMs = 1000;
45 30
46 class AutoclickControllerImpl : public AutoclickController, 31 class AutoclickControllerImpl : public AutoclickController,
47 public ui::EventHandler { 32 public ui::EventHandler,
33 public AutoclickControllerCommon::Delegate,
34 public aura::WindowObserver {
48 public: 35 public:
49 AutoclickControllerImpl(); 36 AutoclickControllerImpl();
50 ~AutoclickControllerImpl() override; 37 ~AutoclickControllerImpl() override;
51 38
52 private: 39 private:
53 // AutoclickController overrides: 40 // AutoclickController overrides:
54 void SetDelegate(std::unique_ptr<Delegate> delegate) override;
55 void SetEnabled(bool enabled) override; 41 void SetEnabled(bool enabled) override;
56 bool IsEnabled() const override; 42 bool IsEnabled() const override;
57 void SetAutoclickDelay(base::TimeDelta delay) override; 43 void SetAutoclickDelay(base::TimeDelta delay) override;
58 base::TimeDelta GetAutoclickDelay() const override;
59 44
60 // ui::EventHandler overrides: 45 // ui::EventHandler overrides:
61 void OnMouseEvent(ui::MouseEvent* event) override; 46 void OnMouseEvent(ui::MouseEvent* event) override;
62 void OnKeyEvent(ui::KeyEvent* event) override; 47 void OnKeyEvent(ui::KeyEvent* event) override;
63 void OnTouchEvent(ui::TouchEvent* event) override; 48 void OnTouchEvent(ui::TouchEvent* event) override;
64 void OnGestureEvent(ui::GestureEvent* event) override; 49 void OnGestureEvent(ui::GestureEvent* event) override;
65 void OnScrollEvent(ui::ScrollEvent* event) override; 50 void OnScrollEvent(ui::ScrollEvent* event) override;
66 51
67 void StartRingDisplay(); 52 // AutoclickControllerCommon::Delegate overrides:
68 void StopRingDisplay(); 53 std::unique_ptr<views::Widget> CreateAutoclickRingWidget(
69 void ChangeRingDisplayCenter(); 54 const gfx::Point& event_location) override;
55 void UpdateAutoclickRingWidget(views::Widget* widget,
56 const gfx::Point& event_location) override;
57 void DoAutoclick(const gfx::Point& event_location,
58 const int mouse_event_flags) override;
70 59
71 void InitClickTimer(); 60 // aura::WindowObserver overrides:
61 void OnWindowDestroying(aura::Window* window) override;
72 62
73 void DoAutoclick(); 63 void SetTapDownTarget(aura::Window* target);
74 64
75 bool enabled_; 65 bool enabled_;
76 base::TimeDelta delay_; 66 // The target window is observed by AutoclickControllerImpl for the duration
77 int mouse_event_flags_; 67 // of a autoclick gesture.
78 std::unique_ptr<base::Timer> autoclick_timer_; 68 aura::Window* tap_down_target_;
79 std::unique_ptr<Delegate> delegate_; 69 std::unique_ptr<AutoclickControllerCommon> autoclick_controller_common_;
80 // The position in screen coordinates used to determine
81 // the distance the mouse has moved.
82 gfx::Point anchor_location_;
83 gfx::Point current_mouse_location_;
84 70
85 DISALLOW_COPY_AND_ASSIGN(AutoclickControllerImpl); 71 DISALLOW_COPY_AND_ASSIGN(AutoclickControllerImpl);
86 }; 72 };
87 73
88 AutoclickControllerImpl::AutoclickControllerImpl() 74 AutoclickControllerImpl::AutoclickControllerImpl()
89 : enabled_(false), 75 : enabled_(false),
90 delay_(GetDefaultAutoclickDelay()), 76 tap_down_target_(nullptr),
91 mouse_event_flags_(ui::EF_NONE), 77 autoclick_controller_common_(
92 delegate_(nullptr), 78 new AutoclickControllerCommon(GetDefaultAutoclickDelay(), this)) {}
93 anchor_location_(-kMovementThreshold, -kMovementThreshold) {
94 InitClickTimer();
95 }
96 79
97 AutoclickControllerImpl::~AutoclickControllerImpl() {} 80 AutoclickControllerImpl::~AutoclickControllerImpl() {
98 81 SetTapDownTarget(nullptr);
99 void AutoclickControllerImpl::SetDelegate(std::unique_ptr<Delegate> delegate) {
100 delegate_ = std::move(delegate);
101 } 82 }
102 83
103 void AutoclickControllerImpl::SetEnabled(bool enabled) { 84 void AutoclickControllerImpl::SetEnabled(bool enabled) {
104 if (enabled_ == enabled) 85 if (enabled_ == enabled)
105 return; 86 return;
106 enabled_ = enabled; 87 enabled_ = enabled;
107 88
108 if (enabled_) { 89 if (enabled_) {
109 Shell::GetInstance()->AddPreTargetHandler(this); 90 Shell::GetInstance()->AddPreTargetHandler(this);
110 autoclick_timer_->Stop(); 91 autoclick_controller_common_->StopAutoclickTimer();
111 } else { 92 } else {
112 Shell::GetInstance()->RemovePreTargetHandler(this); 93 Shell::GetInstance()->RemovePreTargetHandler(this);
113 } 94 }
114 } 95 }
115 96
116 bool AutoclickControllerImpl::IsEnabled() const { 97 bool AutoclickControllerImpl::IsEnabled() const {
117 return enabled_; 98 return enabled_;
118 } 99 }
119 100
120 void AutoclickControllerImpl::SetAutoclickDelay(base::TimeDelta delay) { 101 void AutoclickControllerImpl::SetAutoclickDelay(base::TimeDelta delay) {
121 delay_ = delay; 102 autoclick_controller_common_->SetAutoclickDelay(delay);
122 InitClickTimer();
123 }
124
125 base::TimeDelta AutoclickControllerImpl::GetAutoclickDelay() const {
126 return delay_;
127 }
128
129 void AutoclickControllerImpl::StartRingDisplay() {
130 if (delegate_)
131 delegate_->StartGesture(delay_, anchor_location_);
132 }
133
134 void AutoclickControllerImpl::StopRingDisplay() {
135 if (delegate_)
136 delegate_->StopGesture();
137 }
138
139 void AutoclickControllerImpl::ChangeRingDisplayCenter() {
140 if (delegate_)
141 delegate_->SetGestureCenter(current_mouse_location_);
142 }
143
144 void AutoclickControllerImpl::InitClickTimer() {
145 autoclick_timer_.reset(new base::Timer(
146 FROM_HERE, delay_,
147 base::Bind(&AutoclickControllerImpl::DoAutoclick, base::Unretained(this)),
148 false));
149 } 103 }
150 104
151 void AutoclickControllerImpl::OnMouseEvent(ui::MouseEvent* event) { 105 void AutoclickControllerImpl::OnMouseEvent(ui::MouseEvent* event) {
152 if (event->type() == ui::ET_MOUSE_MOVED && 106 if (event->type() == ui::ET_MOUSE_PRESSED)
153 !(event->flags() & ui::EF_IS_SYNTHESIZED)) { 107 SetTapDownTarget(nullptr);
154 mouse_event_flags_ = event->flags(); 108 autoclick_controller_common_->HandleMouseEvent(*event);
109 }
155 110
156 gfx::Point mouse_location = event->location(); 111 void AutoclickControllerImpl::OnKeyEvent(ui::KeyEvent* event) {
157 ::wm::ConvertPointToScreen(static_cast<aura::Window*>(event->target()), 112 if (!autoclick_controller_common_->IsModifierKey(event->key_code()))
158 &mouse_location); 113 SetTapDownTarget(nullptr);
114 autoclick_controller_common_->HandleKeyEvent(*event);
115 }
159 116
160 // The distance between the mouse location and the anchor location 117 void AutoclickControllerImpl::OnTouchEvent(ui::TouchEvent* event) {
161 // must exceed a certain threshold to initiate a new autoclick countdown. 118 SetTapDownTarget(nullptr);
162 // This ensures that mouse jitter caused by poor motor control does not 119 autoclick_controller_common_->HandleTouchEvent(*event);
163 // 1. initiate an unwanted autoclick from rest 120 }
164 // 2. prevent the autoclick from ever occuring when the mouse 121
165 // arrives at the target. 122 void AutoclickControllerImpl::OnGestureEvent(ui::GestureEvent* event) {
166 gfx::Vector2d delta = mouse_location - anchor_location_; 123 SetTapDownTarget(nullptr);
167 if (delta.LengthSquared() >= kMovementThreshold * kMovementThreshold) { 124 autoclick_controller_common_->HandleGestureEvent(*event);
168 anchor_location_ = mouse_location; 125 }
169 autoclick_timer_->Reset(); 126
170 StartRingDisplay(); 127 void AutoclickControllerImpl::OnScrollEvent(ui::ScrollEvent* event) {
171 } else if (autoclick_timer_->IsRunning()) { 128 SetTapDownTarget(nullptr);
172 current_mouse_location_ = mouse_location; 129 autoclick_controller_common_->HandleScrollEvent(*event);
173 ChangeRingDisplayCenter(); 130 }
174 } 131
175 } else if (event->type() == ui::ET_MOUSE_PRESSED) { 132 std::unique_ptr<views::Widget>
176 autoclick_timer_->Stop(); 133 AutoclickControllerImpl::CreateAutoclickRingWidget(
177 StopRingDisplay(); 134 const gfx::Point& event_location) {
178 } else if (event->type() == ui::ET_MOUSEWHEEL && 135 aura::Window* target =
179 autoclick_timer_->IsRunning()) { 136 WmWindowAura::GetAuraWindow(ash::wm::GetRootWindowAt(event_location));
180 autoclick_timer_->Reset(); 137 SetTapDownTarget(target);
181 StartRingDisplay(); 138 aura::Window* root_window = target->GetRootWindow();
139 std::unique_ptr<views::Widget> widget(new views::Widget);
140 views::Widget::InitParams params;
141 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
142 params.accept_events = false;
143 params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
144 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
145 params.context = root_window;
146 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
147 params.parent =
148 Shell::GetContainer(root_window, kShellWindowId_OverlayContainer);
149 widget->Init(params);
150 widget->SetOpacity(1.f);
151 return widget;
152 }
153
154 void AutoclickControllerImpl::UpdateAutoclickRingWidget(
155 views::Widget* widget,
156 const gfx::Point& event_location) {
157 aura::Window* target =
158 WmWindowAura::GetAuraWindow(ash::wm::GetRootWindowAt(event_location));
159 SetTapDownTarget(target);
160 aura::Window* root_window = target->GetRootWindow();
161 if (widget->GetNativeView()->GetRootWindow() != root_window) {
162 views::Widget::ReparentNativeView(
163 widget->GetNativeView(),
164 Shell::GetContainer(root_window, kShellWindowId_OverlayContainer));
182 } 165 }
183 } 166 }
184 167
185 void AutoclickControllerImpl::OnKeyEvent(ui::KeyEvent* event) { 168 void AutoclickControllerImpl::DoAutoclick(const gfx::Point& event_location,
186 int modifier_mask = ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | 169 const int mouse_event_flags) {
187 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN |
188 ui::EF_IS_EXTENDED_KEY;
189 int new_modifiers = event->flags() & modifier_mask;
190 mouse_event_flags_ = (mouse_event_flags_ & ~modifier_mask) | new_modifiers;
191
192 if (!IsModifierKey(event->key_code())) {
193 autoclick_timer_->Stop();
194 StopRingDisplay();
195 }
196 }
197
198 void AutoclickControllerImpl::OnTouchEvent(ui::TouchEvent* event) {
199 autoclick_timer_->Stop();
200 StopRingDisplay();
201 }
202
203 void AutoclickControllerImpl::OnGestureEvent(ui::GestureEvent* event) {
204 autoclick_timer_->Stop();
205 StopRingDisplay();
206 }
207
208 void AutoclickControllerImpl::OnScrollEvent(ui::ScrollEvent* event) {
209 autoclick_timer_->Stop();
210 StopRingDisplay();
211 }
212
213 void AutoclickControllerImpl::DoAutoclick() {
214 gfx::Point screen_location = aura::Env::GetInstance()->last_mouse_location();
215 aura::Window* root_window = 170 aura::Window* root_window =
216 WmWindowAura::GetAuraWindow(wm::GetRootWindowAt(screen_location)); 171 WmWindowAura::GetAuraWindow(wm::GetRootWindowAt(event_location));
217 DCHECK(root_window) << "Root window not found while attempting autoclick."; 172 DCHECK(root_window) << "Root window not found while attempting autoclick.";
218 173
219 gfx::Point click_location(screen_location); 174 gfx::Point click_location(event_location);
220 anchor_location_ = click_location;
221
222 ::wm::ConvertPointFromScreen(root_window, &click_location); 175 ::wm::ConvertPointFromScreen(root_window, &click_location);
223 aura::WindowTreeHost* host = root_window->GetHost(); 176 aura::WindowTreeHost* host = root_window->GetHost();
224 host->ConvertPointToHost(&click_location); 177 host->ConvertPointToHost(&click_location);
225 178
226 ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, click_location, 179 ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, click_location,
227 click_location, ui::EventTimeForNow(), 180 click_location, ui::EventTimeForNow(),
228 mouse_event_flags_ | ui::EF_LEFT_MOUSE_BUTTON, 181 mouse_event_flags | ui::EF_LEFT_MOUSE_BUTTON,
229 ui::EF_LEFT_MOUSE_BUTTON); 182 ui::EF_LEFT_MOUSE_BUTTON);
230 ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, click_location, 183 ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, click_location,
231 click_location, ui::EventTimeForNow(), 184 click_location, ui::EventTimeForNow(),
232 mouse_event_flags_ | ui::EF_LEFT_MOUSE_BUTTON, 185 mouse_event_flags | ui::EF_LEFT_MOUSE_BUTTON,
233 ui::EF_LEFT_MOUSE_BUTTON); 186 ui::EF_LEFT_MOUSE_BUTTON);
234 187
235 ui::EventDispatchDetails details = 188 ui::EventDispatchDetails details =
236 host->event_processor()->OnEventFromSource(&press_event); 189 host->event_processor()->OnEventFromSource(&press_event);
237 if (!details.dispatcher_destroyed) 190 if (!details.dispatcher_destroyed)
238 details = host->event_processor()->OnEventFromSource(&release_event); 191 details = host->event_processor()->OnEventFromSource(&release_event);
239 if (details.dispatcher_destroyed) 192 if (details.dispatcher_destroyed)
240 return; 193 return;
241 } 194 }
242 195
196 void AutoclickControllerImpl::OnWindowDestroying(aura::Window* window) {
197 DCHECK_EQ(tap_down_target_, window);
198 autoclick_controller_common_->StopGesture();
199 SetTapDownTarget(nullptr);
200 }
201
202 void AutoclickControllerImpl::SetTapDownTarget(aura::Window* target) {
203 if (tap_down_target_ == target)
204 return;
205
206 if (tap_down_target_)
207 tap_down_target_->RemoveObserver(this);
208 tap_down_target_ = target;
209 if (tap_down_target_)
210 tap_down_target_->AddObserver(this);
211 }
212
243 // static. 213 // static.
244 AutoclickController* AutoclickController::CreateInstance() { 214 AutoclickController* AutoclickController::CreateInstance() {
245 return new AutoclickControllerImpl(); 215 return new AutoclickControllerImpl();
246 } 216 }
247 217
248 } // namespace ash 218 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698