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
3 // found in the LICENSE file.
5 #include "ash/autoclick/autoclick_controller.h"
8 #include "ash/wm/coordinate_conversion.h"
9 #include "base/timer/timer.h"
10 #include "ui/aura/env.h"
11 #include "ui/aura/root_window.h"
12 #include "ui/events/event.h"
13 #include "ui/events/event_constants.h"
14 #include "ui/events/event_handler.h"
15 #include "ui/gfx/point.h"
21 // The default wait time between last mouse movement and sending the autoclick.
22 int kDefaultClickWaitTimeMs
= 500;
26 class AutoclickControllerImpl
: public AutoclickController
,
27 public ui::EventHandler
{
29 AutoclickControllerImpl();
30 virtual ~AutoclickControllerImpl();
33 // AutoclickController overrides:
34 virtual void SetEnabled(bool enabled
) OVERRIDE
;
35 virtual bool IsEnabled() const OVERRIDE
;
36 virtual void SetClickWaitTime(int wait_time_ms
) OVERRIDE
;
37 virtual int GetClickWaitTime() const OVERRIDE
;
39 // ui::EventHandler overrides:
40 virtual void OnMouseEvent(ui::MouseEvent
* event
) OVERRIDE
;
41 virtual void OnKeyEvent(ui::KeyEvent
* event
) OVERRIDE
;
42 virtual void OnTouchEvent(ui::TouchEvent
* event
) OVERRIDE
;
44 void InitClickTimer();
50 int mouse_event_flags_
;
51 scoped_ptr
<base::Timer
> autoclick_timer_
;
53 DISALLOW_COPY_AND_ASSIGN(AutoclickControllerImpl
);
57 AutoclickControllerImpl::AutoclickControllerImpl()
59 wait_time_ms_(kDefaultClickWaitTimeMs
),
60 mouse_event_flags_(ui::EF_NONE
) {
64 AutoclickControllerImpl::~AutoclickControllerImpl() {
67 void AutoclickControllerImpl::SetEnabled(bool enabled
) {
68 if (enabled_
== enabled
)
73 Shell::GetInstance()->AddPreTargetHandler(this);
74 autoclick_timer_
->Stop();
76 Shell::GetInstance()->RemovePreTargetHandler(this);
80 bool AutoclickControllerImpl::IsEnabled() const {
84 void AutoclickControllerImpl::SetClickWaitTime(int wait_time_ms
) {
85 wait_time_ms_
= wait_time_ms
;
89 int AutoclickControllerImpl::GetClickWaitTime() const {
93 void AutoclickControllerImpl::InitClickTimer() {
94 autoclick_timer_
.reset(new base::Timer(
96 base::TimeDelta::FromMilliseconds(wait_time_ms_
),
97 base::Bind(&AutoclickControllerImpl::DoAutoclick
,
98 base::Unretained(this)),
102 void AutoclickControllerImpl::OnMouseEvent(ui::MouseEvent
* event
) {
103 if (event
->type() == ui::ET_MOUSE_MOVED
) {
104 mouse_event_flags_
= event
->flags();
105 autoclick_timer_
->Reset();
106 } else if (event
->type() == ui::ET_MOUSE_PRESSED
) {
107 autoclick_timer_
->Stop();
108 } else if (event
->type() == ui::ET_MOUSEWHEEL
&&
109 autoclick_timer_
->IsRunning()) {
110 autoclick_timer_
->Reset();
114 void AutoclickControllerImpl::OnKeyEvent(ui::KeyEvent
* event
) {
117 ui::EF_CONTROL_DOWN
|
119 ui::EF_COMMAND_DOWN
|
121 int new_modifiers
= event
->flags() & modifier_mask
;
122 mouse_event_flags_
= (mouse_event_flags_
& ~modifier_mask
) | new_modifiers
;
125 void AutoclickControllerImpl::OnTouchEvent(ui::TouchEvent
* event
) {
126 autoclick_timer_
->Stop();
129 void AutoclickControllerImpl::DoAutoclick() {
130 gfx::Point screen_location
=
131 aura::Env::GetInstance()->last_mouse_location();
132 aura::RootWindow
* root_window
= wm::GetRootWindowAt(screen_location
);
133 DCHECK(root_window
) << "Root window not found while attempting autoclick.";
135 gfx::Point
click_location(screen_location
);
136 wm::ConvertPointFromScreen(root_window
, &click_location
);
137 root_window
->ConvertPointToHost(&click_location
);
139 ui::MouseEvent
press_event(ui::ET_MOUSE_PRESSED
,
142 mouse_event_flags_
| ui::EF_LEFT_MOUSE_BUTTON
);
143 ui::MouseEvent
release_event(ui::ET_MOUSE_RELEASED
,
146 mouse_event_flags_
| ui::EF_LEFT_MOUSE_BUTTON
);
148 root_window
->AsRootWindowHostDelegate()->OnHostMouseEvent(&press_event
);
149 root_window
->AsRootWindowHostDelegate()->OnHostMouseEvent(&release_event
);
153 AutoclickController
* AutoclickController::CreateInstance() {
154 return new AutoclickControllerImpl();