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

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

Powered by Google App Engine
This is Rietveld 408576698