ui_controls_factory_ozone.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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. 4 5#include "base/bind.h" 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 14namespace aura { 15namespace test { 16namespace { 17 18class UIControlsOzone : public ui_controls::UIControlsAura { 19 public: 20 UIControlsOzone(WindowTreeHost* host) : host_(host) {} 21 22 virtual bool SendKeyPress(gfx::NativeWindow window, 23 ui::KeyboardCode key, 24 bool control, 25 bool shift, 26 bool alt, 27 bool command) OVERRIDE { 28 return SendKeyPressNotifyWhenDone( 29 window, key, control, shift, alt, command, base::Closure()); 30 } 31 virtual bool SendKeyPressNotifyWhenDone( 32 gfx::NativeWindow window, 33 ui::KeyboardCode key, 34 bool control, 35 bool shift, 36 bool alt, 37 bool command, 38 const base::Closure& closure) OVERRIDE { 39 DCHECK(!command); // No command key on Aura 40 41 int flags = button_down_mask_; 42 43 if (control) { 44 flags |= ui::EF_CONTROL_DOWN; 45 PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, flags); 46 } 47 48 if (shift) { 49 flags |= ui::EF_SHIFT_DOWN; 50 PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, flags); 51 } 52 53 if (alt) { 54 flags |= ui::EF_ALT_DOWN; 55 PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_MENU, flags); 56 } 57 58 PostKeyEvent(ui::ET_KEY_PRESSED, key, flags); 59 PostKeyEvent(ui::ET_KEY_RELEASED, key, flags); 60 61 if (alt) { 62 flags &= ~ui::EF_ALT_DOWN; 63 PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_MENU, flags); 64 } 65 66 if (shift) { 67 flags &= ~ui::EF_SHIFT_DOWN; 68 PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, flags); 69 } 70 71 if (control) { 72 flags &= ~ui::EF_CONTROL_DOWN; 73 PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, flags); 74 } 75 76 RunClosureAfterAllPendingUIEvents(closure); 77 return true; 78 } 79 80 virtual bool SendMouseMove(long screen_x, long screen_y) OVERRIDE { 81 return SendMouseMoveNotifyWhenDone(screen_x, screen_y, base::Closure()); 82 } 83 virtual bool SendMouseMoveNotifyWhenDone( 84 long screen_x, 85 long screen_y, 86 const base::Closure& closure) OVERRIDE { 87 gfx::Point root_location(screen_x, screen_y); 88 aura::client::ScreenPositionClient* screen_position_client = 89 aura::client::GetScreenPositionClient(host_->window()); 90 if (screen_position_client) { 91 screen_position_client->ConvertPointFromScreen(host_->window(), 92 &root_location); 93 } 94 gfx::Point root_current_location = 95 QueryLatestMousePositionRequestInHost(host_); 96 host_->ConvertPointFromHost(&root_current_location); 97 98 if (button_down_mask_) 99 PostMouseEvent(ui::ET_MOUSE_DRAGGED, root_location, 0, 0); 100 else 101 PostMouseEvent(ui::ET_MOUSE_MOVED, root_location, 0, 0); 102 103 RunClosureAfterAllPendingUIEvents(closure); 104 return true; 105 } 106 virtual bool SendMouseEvents(ui_controls::MouseButton type, 107 int state) OVERRIDE { 108 return SendMouseEventsNotifyWhenDone(type, state, base::Closure()); 109 } 110 virtual bool SendMouseEventsNotifyWhenDone( 111 ui_controls::MouseButton type, 112 int state, 113 const base::Closure& closure) OVERRIDE { 114 gfx::Point loc = aura::Env::GetInstance()->last_mouse_location(); 115 aura::client::ScreenPositionClient* screen_position_client = 116 aura::client::GetScreenPositionClient(host_->window()); 117 if (screen_position_client) { 118 screen_position_client->ConvertPointFromScreen(host_->window(), &loc); 119 } 120 int flag = 0; 121 122 switch (type) { 123 case ui_controls::LEFT: 124 flag = ui::EF_LEFT_MOUSE_BUTTON; 125 break; 126 case ui_controls::MIDDLE: 127 flag = ui::EF_MIDDLE_MOUSE_BUTTON; 128 break; 129 case ui_controls::RIGHT: 130 flag = ui::EF_RIGHT_MOUSE_BUTTON; 131 break; 132 default: 133 NOTREACHED(); 134 break; 135 } 136 137 if (state & ui_controls::DOWN) { 138 button_down_mask_ |= flag; 139 PostMouseEvent(ui::ET_MOUSE_PRESSED, loc, button_down_mask_ | flag, flag); 140 } 141 if (state & ui_controls::UP) { 142 button_down_mask_ &= ~flag; 143 PostMouseEvent( 144 ui::ET_MOUSE_RELEASED, loc, button_down_mask_ | flag, flag); 145 } 146 147 RunClosureAfterAllPendingUIEvents(closure); 148 return true; 149 } 150 virtual bool SendMouseClick(ui_controls::MouseButton type) OVERRIDE { 151 return SendMouseEvents(type, ui_controls::UP | ui_controls::DOWN); 152 } 153 virtual void RunClosureAfterAllPendingUIEvents( 154 const base::Closure& closure) OVERRIDE { 155 if (!closure.is_null()) 156 base::MessageLoop::current()->PostTask(FROM_HERE, closure); 157 } 158 159 private: 160 void PostKeyEvent(ui::EventType type, ui::KeyboardCode key_code, int flags) { 161 base::MessageLoop::current()->PostTask( 162 FROM_HERE, 163 base::Bind(&UIControlsOzone::PostKeyEventTask, 164 base::Unretained(this), 165 type, 166 key_code, 167 flags)); 168 } 169 170 void PostKeyEventTask(ui::EventType type, 171 ui::KeyboardCode key_code, 172 int flags) { 173 // Do not rewrite injected events. See crbug.com/136465. 174 flags |= ui::EF_FINAL; 175 176 ui::KeyEvent key_event(type, key_code, flags); 177 host_->PostNativeEvent(&key_event); 178 } 179 180 void PostMouseEvent(ui::EventType type, 181 const gfx::PointF& location, 182 int flags, 183 int changed_button_flags) { 184 base::MessageLoop::current()->PostTask( 185 FROM_HERE, 186 base::Bind(&UIControlsOzone::PostMouseEventTask, 187 base::Unretained(this), 188 type, 189 location, 190 flags, 191 changed_button_flags)); 192 } 193 194 void PostMouseEventTask(ui::EventType type, 195 const gfx::PointF& location, 196 int flags, 197 int changed_button_flags) { 198 ui::MouseEvent mouse_event( 199 type, location, location, flags, changed_button_flags); 200 201 // This hack is necessary to set the repeat count for clicks. 202 ui::MouseEvent mouse_event2(&mouse_event); 203 204 host_->PostNativeEvent(&mouse_event2); 205 } 206 207 WindowTreeHost* host_; 208 209 // Mask of the mouse buttons currently down. 210 unsigned button_down_mask_ = 0; 211 212 DISALLOW_COPY_AND_ASSIGN(UIControlsOzone); 213}; 214 215} // namespace 216 217ui_controls::UIControlsAura* CreateUIControlsAura(WindowTreeHost* host) { 218 return new UIControlsOzone(host); 219} 220 221} // namespace test 222} // namespace aura 223