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/test/events_test_utils.h"
19 class UIControlsOzone : public ui_controls::UIControlsAura {
21 UIControlsOzone(WindowTreeHost* host) : host_(host) {}
23 virtual bool SendKeyPress(gfx::NativeWindow window,
28 bool command) override {
29 return SendKeyPressNotifyWhenDone(
30 window, key, control, shift, alt, command, base::Closure());
32 virtual bool SendKeyPressNotifyWhenDone(
33 gfx::NativeWindow window,
39 const base::Closure& closure) override {
40 int flags = button_down_mask_;
43 flags |= ui::EF_CONTROL_DOWN;
44 PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, flags);
48 flags |= ui::EF_SHIFT_DOWN;
49 PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, flags);
53 flags |= ui::EF_ALT_DOWN;
54 PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_MENU, flags);
58 flags |= ui::EF_COMMAND_DOWN;
59 PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_LWIN, flags);
62 PostKeyEvent(ui::ET_KEY_PRESSED, key, flags);
63 PostKeyEvent(ui::ET_KEY_RELEASED, key, flags);
66 flags &= ~ui::EF_ALT_DOWN;
67 PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_MENU, flags);
71 flags &= ~ui::EF_SHIFT_DOWN;
72 PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, flags);
76 flags &= ~ui::EF_CONTROL_DOWN;
77 PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, flags);
81 flags &= ~ui::EF_COMMAND_DOWN;
82 PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_LWIN, flags);
85 RunClosureAfterAllPendingUIEvents(closure);
89 virtual bool SendMouseMove(long screen_x, long screen_y) override {
90 return SendMouseMoveNotifyWhenDone(screen_x, screen_y, base::Closure());
92 virtual bool SendMouseMoveNotifyWhenDone(
95 const base::Closure& closure) override {
96 gfx::Point root_location(screen_x, screen_y);
97 aura::client::ScreenPositionClient* screen_position_client =
98 aura::client::GetScreenPositionClient(host_->window());
99 if (screen_position_client) {
100 screen_position_client->ConvertPointFromScreen(host_->window(),
103 gfx::Point root_current_location =
104 QueryLatestMousePositionRequestInHost(host_);
105 host_->ConvertPointFromHost(&root_current_location);
107 if (button_down_mask_)
108 PostMouseEvent(ui::ET_MOUSE_DRAGGED, root_location, 0, 0);
110 PostMouseEvent(ui::ET_MOUSE_MOVED, root_location, 0, 0);
112 RunClosureAfterAllPendingUIEvents(closure);
115 virtual bool SendMouseEvents(ui_controls::MouseButton type,
116 int state) override {
117 return SendMouseEventsNotifyWhenDone(type, state, base::Closure());
119 virtual bool SendMouseEventsNotifyWhenDone(
120 ui_controls::MouseButton type,
122 const base::Closure& closure) override {
123 gfx::Point loc = aura::Env::GetInstance()->last_mouse_location();
124 aura::client::ScreenPositionClient* screen_position_client =
125 aura::client::GetScreenPositionClient(host_->window());
126 if (screen_position_client) {
127 screen_position_client->ConvertPointFromScreen(host_->window(), &loc);
132 case ui_controls::LEFT:
133 flag = ui::EF_LEFT_MOUSE_BUTTON;
135 case ui_controls::MIDDLE:
136 flag = ui::EF_MIDDLE_MOUSE_BUTTON;
138 case ui_controls::RIGHT:
139 flag = ui::EF_RIGHT_MOUSE_BUTTON;
146 if (state & ui_controls::DOWN) {
147 button_down_mask_ |= flag;
148 PostMouseEvent(ui::ET_MOUSE_PRESSED, loc, button_down_mask_ | flag, flag);
150 if (state & ui_controls::UP) {
151 button_down_mask_ &= ~flag;
153 ui::ET_MOUSE_RELEASED, loc, button_down_mask_ | flag, flag);
156 RunClosureAfterAllPendingUIEvents(closure);
159 virtual bool SendMouseClick(ui_controls::MouseButton type) override {
160 return SendMouseEvents(type, ui_controls::UP | ui_controls::DOWN);
162 virtual void RunClosureAfterAllPendingUIEvents(
163 const base::Closure& closure) override {
164 if (!closure.is_null())
165 base::MessageLoop::current()->PostTask(FROM_HERE, closure);
169 void SendEventToProcessor(ui::Event* event) {
170 ui::EventSourceTestApi event_source_test(host_->GetEventSource());
171 ui::EventDispatchDetails details =
172 event_source_test.SendEventToProcessor(event);
173 if (details.dispatcher_destroyed)
177 void PostKeyEvent(ui::EventType type, ui::KeyboardCode key_code, int flags) {
178 base::MessageLoop::current()->PostTask(
180 base::Bind(&UIControlsOzone::PostKeyEventTask,
181 base::Unretained(this),
187 void PostKeyEventTask(ui::EventType type,
188 ui::KeyboardCode key_code,
190 // Do not rewrite injected events. See crbug.com/136465.
191 flags |= ui::EF_FINAL;
193 ui::KeyEvent key_event(type, key_code, flags);
194 SendEventToProcessor(&key_event);
197 void PostMouseEvent(ui::EventType type,
198 const gfx::PointF& location,
200 int changed_button_flags) {
201 base::MessageLoop::current()->PostTask(
203 base::Bind(&UIControlsOzone::PostMouseEventTask,
204 base::Unretained(this),
208 changed_button_flags));
211 void PostMouseEventTask(ui::EventType type,
212 const gfx::PointF& location,
214 int changed_button_flags) {
215 ui::MouseEvent mouse_event(
216 type, location, location, flags, changed_button_flags);
218 // This hack is necessary to set the repeat count for clicks.
219 ui::MouseEvent mouse_event2(&mouse_event);
221 SendEventToProcessor(&mouse_event2);
224 WindowTreeHost* host_;
226 // Mask of the mouse buttons currently down.
227 unsigned button_down_mask_ = 0;
229 DISALLOW_COPY_AND_ASSIGN(UIControlsOzone);
234 ui_controls::UIControlsAura* CreateUIControlsAura(WindowTreeHost* host) {
235 return new UIControlsOzone(host);