1 // Copyright 2014 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.
6 #include "base/logging.h"
7 #include "ui/aura/client/screen_position_client.h"
8 #include "ui/aura/env.h"
9 #include "ui/aura/test/aura_test_utils.h"
10 #include "ui/aura/test/ui_controls_factory_aura.h"
11 #include "ui/aura/window_tree_host.h"
12 #include "ui/base/test/ui_controls_aura.h"
13 #include "ui/events/event_utils.h"
14 #include "ui/events/test/events_test_utils.h"
20 class UIControlsOzone
: public ui_controls::UIControlsAura
{
22 UIControlsOzone(WindowTreeHost
* host
) : host_(host
) {}
24 bool SendKeyPress(gfx::NativeWindow window
,
29 bool command
) override
{
30 return SendKeyPressNotifyWhenDone(
31 window
, key
, control
, shift
, alt
, command
, base::Closure());
33 bool SendKeyPressNotifyWhenDone(
34 gfx::NativeWindow window
,
40 const base::Closure
& closure
) override
{
41 int flags
= button_down_mask_
;
44 flags
|= ui::EF_CONTROL_DOWN
;
45 PostKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, flags
);
49 flags
|= ui::EF_SHIFT_DOWN
;
50 PostKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_SHIFT
, flags
);
54 flags
|= ui::EF_ALT_DOWN
;
55 PostKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_MENU
, flags
);
59 flags
|= ui::EF_COMMAND_DOWN
;
60 PostKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_LWIN
, flags
);
63 PostKeyEvent(ui::ET_KEY_PRESSED
, key
, flags
);
64 PostKeyEvent(ui::ET_KEY_RELEASED
, key
, flags
);
67 flags
&= ~ui::EF_ALT_DOWN
;
68 PostKeyEvent(ui::ET_KEY_RELEASED
, ui::VKEY_MENU
, flags
);
72 flags
&= ~ui::EF_SHIFT_DOWN
;
73 PostKeyEvent(ui::ET_KEY_RELEASED
, ui::VKEY_SHIFT
, flags
);
77 flags
&= ~ui::EF_CONTROL_DOWN
;
78 PostKeyEvent(ui::ET_KEY_RELEASED
, ui::VKEY_CONTROL
, flags
);
82 flags
&= ~ui::EF_COMMAND_DOWN
;
83 PostKeyEvent(ui::ET_KEY_RELEASED
, ui::VKEY_LWIN
, flags
);
86 RunClosureAfterAllPendingUIEvents(closure
);
90 bool SendMouseMove(long screen_x
, long screen_y
) override
{
91 return SendMouseMoveNotifyWhenDone(screen_x
, screen_y
, base::Closure());
93 bool SendMouseMoveNotifyWhenDone(
96 const base::Closure
& closure
) override
{
97 gfx::Point
root_location(screen_x
, screen_y
);
98 aura::client::ScreenPositionClient
* screen_position_client
=
99 aura::client::GetScreenPositionClient(host_
->window());
100 if (screen_position_client
) {
101 screen_position_client
->ConvertPointFromScreen(host_
->window(),
105 gfx::Point host_location
= root_location
;
106 host_
->ConvertPointToHost(&host_location
);
108 ui::EventType event_type
;
110 if (button_down_mask_
)
111 event_type
= ui::ET_MOUSE_DRAGGED
;
113 event_type
= ui::ET_MOUSE_MOVED
;
115 PostMouseEvent(event_type
, host_location
, 0, 0);
117 RunClosureAfterAllPendingUIEvents(closure
);
120 bool SendMouseEvents(ui_controls::MouseButton type
, int state
) override
{
121 return SendMouseEventsNotifyWhenDone(type
, state
, base::Closure());
123 bool SendMouseEventsNotifyWhenDone(
124 ui_controls::MouseButton type
,
126 const base::Closure
& closure
) override
{
127 gfx::Point root_location
= aura::Env::GetInstance()->last_mouse_location();
128 aura::client::ScreenPositionClient
* screen_position_client
=
129 aura::client::GetScreenPositionClient(host_
->window());
130 if (screen_position_client
) {
131 screen_position_client
->ConvertPointFromScreen(host_
->window(),
135 gfx::Point host_location
= root_location
;
136 host_
->ConvertPointToHost(&host_location
);
141 case ui_controls::LEFT
:
142 flag
= ui::EF_LEFT_MOUSE_BUTTON
;
144 case ui_controls::MIDDLE
:
145 flag
= ui::EF_MIDDLE_MOUSE_BUTTON
;
147 case ui_controls::RIGHT
:
148 flag
= ui::EF_RIGHT_MOUSE_BUTTON
;
155 if (state
& ui_controls::DOWN
) {
156 button_down_mask_
|= flag
;
157 PostMouseEvent(ui::ET_MOUSE_PRESSED
, host_location
,
158 button_down_mask_
| flag
, flag
);
160 if (state
& ui_controls::UP
) {
161 button_down_mask_
&= ~flag
;
162 PostMouseEvent(ui::ET_MOUSE_RELEASED
, host_location
,
163 button_down_mask_
| flag
, flag
);
166 RunClosureAfterAllPendingUIEvents(closure
);
169 bool SendMouseClick(ui_controls::MouseButton type
) override
{
170 return SendMouseEvents(type
, ui_controls::UP
| ui_controls::DOWN
);
172 void RunClosureAfterAllPendingUIEvents(
173 const base::Closure
& closure
) override
{
174 if (!closure
.is_null())
175 base::MessageLoop::current()->PostTask(FROM_HERE
, closure
);
179 void SendEventToProcessor(ui::Event
* event
) {
180 ui::EventSourceTestApi
event_source_test(host_
->GetEventSource());
181 ui::EventDispatchDetails details
=
182 event_source_test
.SendEventToProcessor(event
);
183 if (details
.dispatcher_destroyed
)
187 void PostKeyEvent(ui::EventType type
, ui::KeyboardCode key_code
, int flags
) {
188 base::MessageLoop::current()->PostTask(
190 base::Bind(&UIControlsOzone::PostKeyEventTask
,
191 base::Unretained(this),
197 void PostKeyEventTask(ui::EventType type
,
198 ui::KeyboardCode key_code
,
200 // Do not rewrite injected events. See crbug.com/136465.
201 flags
|= ui::EF_FINAL
;
203 ui::KeyEvent
key_event(type
, key_code
, flags
);
204 SendEventToProcessor(&key_event
);
207 void PostMouseEvent(ui::EventType type
,
208 const gfx::PointF
& host_location
,
210 int changed_button_flags
) {
211 base::MessageLoop::current()->PostTask(
213 base::Bind(&UIControlsOzone::PostMouseEventTask
, base::Unretained(this),
214 type
, host_location
, flags
, changed_button_flags
));
217 void PostMouseEventTask(ui::EventType type
,
218 const gfx::PointF
& host_location
,
220 int changed_button_flags
) {
221 ui::MouseEvent
mouse_event(type
, host_location
, host_location
,
222 ui::EventTimeForNow(), flags
,
223 changed_button_flags
);
225 // This hack is necessary to set the repeat count for clicks.
226 ui::MouseEvent
mouse_event2(&mouse_event
);
228 SendEventToProcessor(&mouse_event2
);
231 WindowTreeHost
* host_
;
233 // Mask of the mouse buttons currently down.
234 unsigned button_down_mask_
= 0;
236 DISALLOW_COPY_AND_ASSIGN(UIControlsOzone
);
241 ui_controls::UIControlsAura
* CreateUIControlsAura(WindowTreeHost
* host
) {
242 return new UIControlsOzone(host
);