| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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 "ui/views/widget/android/native_widget_android.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/macros.h" | |
| 9 #include "base/run_loop.h" | |
| 10 #include "base/strings/string_util.h" | |
| 11 #include "third_party/skia/include/core/SkRegion.h" | |
| 12 #include "ui/aura/client/aura_constants.h" | |
| 13 #include "ui/aura/client/cursor_client.h" | |
| 14 #include "ui/aura/client/default_capture_client.h" | |
| 15 #include "ui/aura/client/focus_client.h" | |
| 16 #include "ui/aura/client/screen_position_client.h" | |
| 17 #include "ui/aura/client/window_tree_client.h" | |
| 18 #include "ui/aura/env.h" | |
| 19 #include "ui/aura/window.h" | |
| 20 #include "ui/aura/window_event_dispatcher.h" | |
| 21 #include "ui/aura/window_observer.h" | |
| 22 #include "ui/aura/window_tree_host.h" | |
| 23 #include "ui/base/dragdrop/os_exchange_data.h" | |
| 24 #include "ui/base/ui_base_types.h" | |
| 25 #include "ui/compositor/layer.h" | |
| 26 #include "ui/events/event.h" | |
| 27 #include "ui/gfx/canvas.h" | |
| 28 #include "ui/gfx/font_list.h" | |
| 29 #include "ui/gfx/screen.h" | |
| 30 #include "ui/native_theme/native_theme_aura.h" | |
| 31 #include "ui/views/drag_utils.h" | |
| 32 #include "ui/views/views_delegate.h" | |
| 33 #include "ui/views/widget/android/android_focus_rules.h" | |
| 34 #include "ui/views/widget/native_widget_aura.h" | |
| 35 #include "ui/views/widget/native_widget_delegate.h" | |
| 36 #include "ui/views/widget/root_view.h" | |
| 37 #include "ui/views/widget/tooltip_manager_aura.h" | |
| 38 #include "ui/views/widget/widget_aura_utils.h" | |
| 39 #include "ui/views/widget/widget_delegate.h" | |
| 40 #include "ui/views/widget/window_reorderer.h" | |
| 41 #include "ui/wm/core/default_activation_client.h" | |
| 42 #include "ui/wm/core/default_screen_position_client.h" | |
| 43 #include "ui/wm/core/focus_controller.h" | |
| 44 #include "ui/wm/core/shadow_types.h" | |
| 45 #include "ui/wm/core/window_animations.h" | |
| 46 #include "ui/wm/core/window_util.h" | |
| 47 #include "ui/wm/public/activation_client.h" | |
| 48 #include "ui/wm/public/dispatcher_client.h" | |
| 49 #include "ui/wm/public/drag_drop_client.h" | |
| 50 #include "ui/wm/public/window_move_client.h" | |
| 51 #include "ui/wm/public/window_types.h" | |
| 52 | |
| 53 // TODO(bshe): Most of the code is copied from NativeWidgetAura or | |
| 54 // DesktopNativeWidgetAura. Share more code instead of duplicate code when | |
| 55 // possible. crbug.com/554961. | |
| 56 namespace { | |
| 57 | |
| 58 class WindowTreeClientImpl : public aura::client::WindowTreeClient { | |
| 59 public: | |
| 60 explicit WindowTreeClientImpl(aura::Window* root_window) | |
| 61 : root_window_(root_window) { | |
| 62 aura::client::SetWindowTreeClient(root_window_, this); | |
| 63 } | |
| 64 ~WindowTreeClientImpl() override { | |
| 65 aura::client::SetWindowTreeClient(root_window_, nullptr); | |
| 66 } | |
| 67 | |
| 68 // Overridden from client::WindowTreeClient: | |
| 69 aura::Window* GetDefaultParent(aura::Window* context, | |
| 70 aura::Window* window, | |
| 71 const gfx::Rect& bounds) override { | |
| 72 return root_window_; | |
| 73 } | |
| 74 | |
| 75 private: | |
| 76 aura::Window* root_window_; | |
| 77 | |
| 78 DISALLOW_COPY_AND_ASSIGN(WindowTreeClientImpl); | |
| 79 }; | |
| 80 | |
| 81 // TODO(bshe|jonross): Get rid of nested message loop once crbug.com/523680 is | |
| 82 // fixed. | |
| 83 class AndroidDispatcherClient : public aura::client::DispatcherClient { | |
| 84 public: | |
| 85 AndroidDispatcherClient() {} | |
| 86 ~AndroidDispatcherClient() override {} | |
| 87 | |
| 88 // aura::client::DispatcherClient: | |
| 89 void PrepareNestedLoopClosures(base::MessagePumpDispatcher* dispatcher, | |
| 90 base::Closure* run_closure, | |
| 91 base::Closure* quit_closure) override { | |
| 92 scoped_ptr<base::RunLoop> run_loop(new base::RunLoop()); | |
| 93 *quit_closure = run_loop->QuitClosure(); | |
| 94 *run_closure = | |
| 95 base::Bind(&AndroidDispatcherClient::RunNestedDispatcher, | |
| 96 base::Unretained(this), base::Passed(&run_loop), dispatcher); | |
| 97 } | |
| 98 | |
| 99 private: | |
| 100 void RunNestedDispatcher(scoped_ptr<base::RunLoop> run_loop, | |
| 101 base::MessagePumpDispatcher* dispatcher) { | |
| 102 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); | |
| 103 base::MessageLoop::ScopedNestableTaskAllower allow(loop); | |
| 104 run_loop->Run(); | |
| 105 } | |
| 106 | |
| 107 DISALLOW_COPY_AND_ASSIGN(AndroidDispatcherClient); | |
| 108 }; | |
| 109 | |
| 110 } // namespace | |
| 111 | |
| 112 namespace views { | |
| 113 | |
| 114 //////////////////////////////////////////////////////////////////////////////// | |
| 115 // NativeWidgetAndroid, public | |
| 116 | |
| 117 NativeWidgetAndroid::NativeWidgetAndroid( | |
| 118 internal::NativeWidgetDelegate* delegate) | |
| 119 : delegate_(delegate), | |
| 120 window_(new aura::Window(this)), | |
| 121 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), | |
| 122 destroying_(false), | |
| 123 cursor_(gfx::kNullCursor), | |
| 124 saved_window_state_(ui::SHOW_STATE_DEFAULT), | |
| 125 close_widget_factory_(this) { | |
| 126 aura::client::SetFocusChangeObserver(window_, this); | |
| 127 aura::client::SetActivationChangeObserver(window_, this); | |
| 128 } | |
| 129 | |
| 130 //////////////////////////////////////////////////////////////////////////////// | |
| 131 // NativeWidgetAndroid, internal::NativeWidgetPrivate implementation: | |
| 132 | |
| 133 void NativeWidgetAndroid::InitNativeWidget(const Widget::InitParams& params) { | |
| 134 ownership_ = params.ownership; | |
| 135 NativeWidgetAura::RegisterNativeWidgetForWindow(this, window_); | |
| 136 | |
| 137 window_->SetType(GetAuraWindowTypeForWidgetType(params.type)); | |
| 138 window_->Init(params.layer_type); | |
| 139 wm::SetShadowType(window_, wm::SHADOW_TYPE_NONE); | |
| 140 window_->Show(); | |
| 141 | |
| 142 // TODO(bshe): Get rid of the hard coded size. Tracked in crbug.com/551923. | |
| 143 host_.reset(aura::WindowTreeHost::Create(gfx::Rect(0, 0, 800, 600))); | |
| 144 host_->InitHost(); | |
| 145 host_->AddObserver(this); | |
| 146 | |
| 147 window_tree_client_.reset(new WindowTreeClientImpl(host_->window())); | |
| 148 | |
| 149 focus_client_.reset(new wm::FocusController(new AndroidFocusRules)); | |
| 150 aura::client::SetFocusClient(host_->window(), focus_client_.get()); | |
| 151 host_->window()->AddPreTargetHandler(focus_client_.get()); | |
| 152 | |
| 153 new wm::DefaultActivationClient(host_->window()); | |
| 154 | |
| 155 capture_client_.reset( | |
| 156 new aura::client::DefaultCaptureClient(host_->window())); | |
| 157 | |
| 158 screen_position_client_.reset(new wm::DefaultScreenPositionClient); | |
| 159 aura::client::SetScreenPositionClient(host_->window(), | |
| 160 screen_position_client_.get()); | |
| 161 dispatcher_client_.reset(new AndroidDispatcherClient); | |
| 162 aura::client::SetDispatcherClient(host_->window(), dispatcher_client_.get()); | |
| 163 | |
| 164 delegate_->OnNativeWidgetCreated(false); | |
| 165 | |
| 166 DCHECK(GetWidget()->GetRootView()); | |
| 167 if (params.type != Widget::InitParams::TYPE_TOOLTIP) | |
| 168 tooltip_manager_.reset(new views::TooltipManagerAura(GetWidget())); | |
| 169 | |
| 170 if (params.type != Widget::InitParams::TYPE_TOOLTIP && | |
| 171 params.type != Widget::InitParams::TYPE_POPUP) { | |
| 172 aura::client::SetDragDropDelegate(window_, this); | |
| 173 } | |
| 174 | |
| 175 aura::client::SetActivationDelegate(window_, this); | |
| 176 | |
| 177 host_->window()->AddChild(window_); | |
| 178 window_reorderer_.reset( | |
| 179 new WindowReorderer(window_, GetWidget()->GetRootView())); | |
| 180 | |
| 181 // TODO(bshe): figure out how to add cursor manager, drag drop client and all | |
| 182 // the necessary parts that exists in desktop_native_widget_aura. | |
| 183 } | |
| 184 | |
| 185 void NativeWidgetAndroid::OnWidgetInitDone() {} | |
| 186 | |
| 187 NonClientFrameView* NativeWidgetAndroid::CreateNonClientFrameView() { | |
| 188 NOTIMPLEMENTED(); | |
| 189 return nullptr; | |
| 190 } | |
| 191 | |
| 192 bool NativeWidgetAndroid::ShouldUseNativeFrame() const { | |
| 193 // There is only one frame type for aura. | |
| 194 return false; | |
| 195 } | |
| 196 | |
| 197 bool NativeWidgetAndroid::ShouldWindowContentsBeTransparent() const { | |
| 198 NOTIMPLEMENTED(); | |
| 199 return false; | |
| 200 } | |
| 201 | |
| 202 void NativeWidgetAndroid::FrameTypeChanged() { | |
| 203 NOTIMPLEMENTED(); | |
| 204 } | |
| 205 | |
| 206 Widget* NativeWidgetAndroid::GetWidget() { | |
| 207 return delegate_->AsWidget(); | |
| 208 } | |
| 209 | |
| 210 const Widget* NativeWidgetAndroid::GetWidget() const { | |
| 211 return delegate_->AsWidget(); | |
| 212 } | |
| 213 | |
| 214 gfx::NativeView NativeWidgetAndroid::GetNativeView() const { | |
| 215 return window_; | |
| 216 } | |
| 217 | |
| 218 gfx::NativeWindow NativeWidgetAndroid::GetNativeWindow() const { | |
| 219 return window_; | |
| 220 } | |
| 221 | |
| 222 Widget* NativeWidgetAndroid::GetTopLevelWidget() { | |
| 223 return GetWidget(); | |
| 224 } | |
| 225 | |
| 226 const ui::Compositor* NativeWidgetAndroid::GetCompositor() const { | |
| 227 return host_->compositor(); | |
| 228 } | |
| 229 | |
| 230 const ui::Layer* NativeWidgetAndroid::GetLayer() const { | |
| 231 return GetNativeWindow()->layer(); | |
| 232 } | |
| 233 | |
| 234 void NativeWidgetAndroid::ReorderNativeViews() { | |
| 235 window_reorderer_->ReorderChildWindows(); | |
| 236 } | |
| 237 | |
| 238 void NativeWidgetAndroid::ViewRemoved(View* view) { | |
| 239 // TODO(bshe): Implement drag and drop. crbug.com/554029. | |
| 240 NOTIMPLEMENTED(); | |
| 241 } | |
| 242 | |
| 243 void NativeWidgetAndroid::SetNativeWindowProperty(const char* name, | |
| 244 void* value) { | |
| 245 GetNativeWindow()->SetNativeWindowProperty(name, value); | |
| 246 } | |
| 247 | |
| 248 void* NativeWidgetAndroid::GetNativeWindowProperty(const char* name) const { | |
| 249 return GetNativeWindow()->GetNativeWindowProperty(name); | |
| 250 } | |
| 251 | |
| 252 TooltipManager* NativeWidgetAndroid::GetTooltipManager() const { | |
| 253 return tooltip_manager_.get(); | |
| 254 } | |
| 255 | |
| 256 void NativeWidgetAndroid::SetCapture() { | |
| 257 GetNativeWindow()->SetCapture(); | |
| 258 } | |
| 259 | |
| 260 void NativeWidgetAndroid::ReleaseCapture() { | |
| 261 GetNativeWindow()->ReleaseCapture(); | |
| 262 } | |
| 263 | |
| 264 bool NativeWidgetAndroid::HasCapture() const { | |
| 265 return GetNativeWindow()->HasCapture(); | |
| 266 } | |
| 267 | |
| 268 ui::InputMethod* NativeWidgetAndroid::GetInputMethod() { | |
| 269 return host_->GetInputMethod(); | |
| 270 } | |
| 271 | |
| 272 void NativeWidgetAndroid::CenterWindow(const gfx::Size& size) { | |
| 273 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 274 NOTIMPLEMENTED(); | |
| 275 } | |
| 276 | |
| 277 void NativeWidgetAndroid::GetWindowPlacement( | |
| 278 gfx::Rect* bounds, | |
| 279 ui::WindowShowState* show_state) const { | |
| 280 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 281 NOTIMPLEMENTED(); | |
| 282 } | |
| 283 | |
| 284 bool NativeWidgetAndroid::SetWindowTitle(const base::string16& title) { | |
| 285 if (GetNativeWindow()->title() == title) | |
| 286 return false; | |
| 287 GetNativeWindow()->SetTitle(title); | |
| 288 return true; | |
| 289 } | |
| 290 | |
| 291 void NativeWidgetAndroid::SetWindowIcons(const gfx::ImageSkia& window_icon, | |
| 292 const gfx::ImageSkia& app_icon) { | |
| 293 // TODO(bshe): Implement this. See crbug.com/554953. | |
| 294 NOTIMPLEMENTED(); | |
| 295 } | |
| 296 | |
| 297 void NativeWidgetAndroid::InitModalType(ui::ModalType modal_type) { | |
| 298 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 299 NOTIMPLEMENTED(); | |
| 300 } | |
| 301 | |
| 302 gfx::Rect NativeWidgetAndroid::GetWindowBoundsInScreen() const { | |
| 303 return GetNativeWindow()->GetBoundsInScreen(); | |
| 304 } | |
| 305 | |
| 306 gfx::Rect NativeWidgetAndroid::GetClientAreaBoundsInScreen() const { | |
| 307 // View-to-screen coordinate system transformations depend on this returning | |
| 308 // the full window bounds, for example View::ConvertPointToScreen(). | |
| 309 return GetNativeWindow()->GetBoundsInScreen(); | |
| 310 } | |
| 311 | |
| 312 gfx::Rect NativeWidgetAndroid::GetRestoredBounds() const { | |
| 313 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 314 NOTIMPLEMENTED(); | |
| 315 return gfx::Rect(); | |
| 316 } | |
| 317 | |
| 318 void NativeWidgetAndroid::SetBounds(const gfx::Rect& bounds) { | |
| 319 // TODO(bshe): This may not work. We may need to resize SurfaceView too. See | |
| 320 // crbug.com/554952. | |
| 321 host_->SetBounds(bounds); | |
| 322 } | |
| 323 | |
| 324 void NativeWidgetAndroid::SetSize(const gfx::Size& size) { | |
| 325 gfx::Rect bounds = host_->GetBounds(); | |
| 326 SetBounds(gfx::Rect(bounds.origin(), size)); | |
| 327 } | |
| 328 | |
| 329 void NativeWidgetAndroid::StackAbove(gfx::NativeView native_view) { | |
| 330 // TODO(bshe): Implements window stacking logic. See crbug.com/554047 | |
| 331 NOTIMPLEMENTED(); | |
| 332 } | |
| 333 | |
| 334 void NativeWidgetAndroid::StackAtTop() { | |
| 335 // TODO(bshe): Implements window stacking logic. See crbug.com/554047 | |
| 336 NOTIMPLEMENTED(); | |
| 337 } | |
| 338 | |
| 339 void NativeWidgetAndroid::StackBelow(gfx::NativeView native_view) { | |
| 340 // TODO(bshe): Implements window stacking logic. See crbug.com/554047 | |
| 341 NOTIMPLEMENTED(); | |
| 342 } | |
| 343 | |
| 344 void NativeWidgetAndroid::SetShape(SkRegion* region) { | |
| 345 GetNativeWindow()->layer()->SetAlphaShape(make_scoped_ptr(region)); | |
| 346 } | |
| 347 | |
| 348 void NativeWidgetAndroid::Close() { | |
| 349 // TODO(bshe): This might not be right. See crbug.com/554259. | |
| 350 DCHECK(ownership_ == Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET); | |
| 351 GetNativeWindow()->SuppressPaint(); | |
| 352 Hide(); | |
| 353 GetNativeWindow()->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_NONE); | |
| 354 | |
| 355 if (!close_widget_factory_.HasWeakPtrs()) { | |
| 356 base::MessageLoop::current()->PostTask( | |
| 357 FROM_HERE, base::Bind(&NativeWidgetAndroid::CloseNow, | |
| 358 close_widget_factory_.GetWeakPtr())); | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 void NativeWidgetAndroid::CloseNow() { | |
| 363 // TODO(bshe): This might not be right. See crbug.com/554259. | |
| 364 host_->RemoveObserver(this); | |
| 365 host_.reset(); | |
| 366 delete window_; | |
| 367 } | |
| 368 | |
| 369 void NativeWidgetAndroid::Show() { | |
| 370 host_->Show(); | |
| 371 GetNativeWindow()->Show(); | |
| 372 } | |
| 373 | |
| 374 void NativeWidgetAndroid::Hide() { | |
| 375 host_->Hide(); | |
| 376 GetNativeWindow()->Hide(); | |
| 377 } | |
| 378 | |
| 379 void NativeWidgetAndroid::ShowMaximizedWithBounds( | |
| 380 const gfx::Rect& restored_bounds) { | |
| 381 NOTIMPLEMENTED(); | |
| 382 } | |
| 383 | |
| 384 void NativeWidgetAndroid::ShowWithWindowState(ui::WindowShowState state) { | |
| 385 NOTIMPLEMENTED(); | |
| 386 } | |
| 387 | |
| 388 bool NativeWidgetAndroid::IsVisible() const { | |
| 389 return GetNativeWindow()->IsVisible(); | |
| 390 } | |
| 391 | |
| 392 void NativeWidgetAndroid::Activate() { | |
| 393 aura::client::GetActivationClient(host_->window()) | |
| 394 ->ActivateWindow(GetNativeWindow()); | |
| 395 } | |
| 396 | |
| 397 void NativeWidgetAndroid::Deactivate() { | |
| 398 aura::client::GetActivationClient(host_->window()) | |
| 399 ->DeactivateWindow(GetNativeWindow()); | |
| 400 } | |
| 401 | |
| 402 bool NativeWidgetAndroid::IsActive() const { | |
| 403 return wm::IsActiveWindow(GetNativeWindow()); | |
| 404 } | |
| 405 | |
| 406 void NativeWidgetAndroid::SetAlwaysOnTop(bool on_top) { | |
| 407 GetNativeWindow()->SetProperty(aura::client::kAlwaysOnTopKey, on_top); | |
| 408 } | |
| 409 | |
| 410 bool NativeWidgetAndroid::IsAlwaysOnTop() const { | |
| 411 return GetNativeWindow()->GetProperty(aura::client::kAlwaysOnTopKey); | |
| 412 } | |
| 413 | |
| 414 void NativeWidgetAndroid::SetVisibleOnAllWorkspaces(bool always_visible) { | |
| 415 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 416 NOTIMPLEMENTED(); | |
| 417 } | |
| 418 | |
| 419 void NativeWidgetAndroid::Maximize() { | |
| 420 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 421 NOTIMPLEMENTED(); | |
| 422 } | |
| 423 | |
| 424 void NativeWidgetAndroid::Minimize() { | |
| 425 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 426 NOTIMPLEMENTED(); | |
| 427 } | |
| 428 | |
| 429 bool NativeWidgetAndroid::IsMaximized() const { | |
| 430 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 431 NOTIMPLEMENTED(); | |
| 432 return false; | |
| 433 } | |
| 434 | |
| 435 bool NativeWidgetAndroid::IsMinimized() const { | |
| 436 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 437 NOTIMPLEMENTED(); | |
| 438 return false; | |
| 439 } | |
| 440 | |
| 441 void NativeWidgetAndroid::Restore() { | |
| 442 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 443 NOTIMPLEMENTED(); | |
| 444 } | |
| 445 | |
| 446 void NativeWidgetAndroid::SetFullscreen(bool fullscreen) { | |
| 447 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 448 NOTIMPLEMENTED(); | |
| 449 } | |
| 450 | |
| 451 bool NativeWidgetAndroid::IsFullscreen() const { | |
| 452 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 453 NOTIMPLEMENTED(); | |
| 454 return false; | |
| 455 } | |
| 456 | |
| 457 void NativeWidgetAndroid::SetOpacity(unsigned char opacity) { | |
| 458 GetNativeWindow()->layer()->SetOpacity(opacity / 255.0); | |
| 459 } | |
| 460 | |
| 461 void NativeWidgetAndroid::SetUseDragFrame(bool use_drag_frame) { | |
| 462 NOTIMPLEMENTED(); | |
| 463 } | |
| 464 | |
| 465 void NativeWidgetAndroid::FlashFrame(bool flash) { | |
| 466 NOTIMPLEMENTED(); | |
| 467 } | |
| 468 | |
| 469 void NativeWidgetAndroid::RunShellDrag( | |
| 470 View* view, | |
| 471 const ui::OSExchangeData& data, | |
| 472 const gfx::Point& location, | |
| 473 int operation, | |
| 474 ui::DragDropTypes::DragEventSource source) { | |
| 475 NOTIMPLEMENTED(); | |
| 476 } | |
| 477 | |
| 478 void NativeWidgetAndroid::SchedulePaintInRect(const gfx::Rect& rect) { | |
| 479 GetNativeWindow()->SchedulePaintInRect(rect); | |
| 480 } | |
| 481 | |
| 482 void NativeWidgetAndroid::SetCursor(gfx::NativeCursor cursor) { | |
| 483 cursor_ = cursor; | |
| 484 aura::client::CursorClient* cursor_client = | |
| 485 aura::client::GetCursorClient(host_->window()); | |
| 486 if (cursor_client) | |
| 487 cursor_client->SetCursor(cursor); | |
| 488 } | |
| 489 | |
| 490 bool NativeWidgetAndroid::IsMouseEventsEnabled() const { | |
| 491 aura::client::CursorClient* cursor_client = | |
| 492 aura::client::GetCursorClient(host_->window()); | |
| 493 return cursor_client ? cursor_client->IsMouseEventsEnabled() : true; | |
| 494 } | |
| 495 | |
| 496 void NativeWidgetAndroid::ClearNativeFocus() { | |
| 497 aura::client::FocusClient* client = aura::client::GetFocusClient(window_); | |
| 498 if (client && window_->Contains(client->GetFocusedWindow())) | |
| 499 client->ResetFocusWithinActiveWindow(window_); | |
| 500 } | |
| 501 | |
| 502 gfx::Rect NativeWidgetAndroid::GetWorkAreaBoundsInScreen() const { | |
| 503 return gfx::Screen::GetScreenFor(window_) | |
| 504 ->GetDisplayNearestWindow(window_) | |
| 505 .work_area(); | |
| 506 } | |
| 507 | |
| 508 Widget::MoveLoopResult NativeWidgetAndroid::RunMoveLoop( | |
| 509 const gfx::Vector2d& drag_offset, | |
| 510 Widget::MoveLoopSource source, | |
| 511 Widget::MoveLoopEscapeBehavior escape_behavior) { | |
| 512 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 513 NOTIMPLEMENTED(); | |
| 514 return Widget::MOVE_LOOP_SUCCESSFUL; | |
| 515 } | |
| 516 | |
| 517 void NativeWidgetAndroid::EndMoveLoop() { | |
| 518 // TODO(bshe): Implement this. See crbug.com/554208. | |
| 519 NOTIMPLEMENTED(); | |
| 520 } | |
| 521 | |
| 522 void NativeWidgetAndroid::SetVisibilityChangedAnimationsEnabled(bool value) { | |
| 523 GetNativeWindow()->SetProperty(aura::client::kAnimationsDisabledKey, !value); | |
| 524 } | |
| 525 | |
| 526 void NativeWidgetAndroid::SetVisibilityAnimationDuration( | |
| 527 const base::TimeDelta& duration) { | |
| 528 wm::SetWindowVisibilityAnimationDuration(GetNativeWindow(), duration); | |
| 529 } | |
| 530 | |
| 531 void NativeWidgetAndroid::SetVisibilityAnimationTransition( | |
| 532 Widget::VisibilityTransition transition) { | |
| 533 wm::WindowVisibilityAnimationTransition wm_transition = wm::ANIMATE_NONE; | |
| 534 switch (transition) { | |
| 535 case Widget::ANIMATE_SHOW: | |
| 536 wm_transition = wm::ANIMATE_SHOW; | |
| 537 break; | |
| 538 case Widget::ANIMATE_HIDE: | |
| 539 wm_transition = wm::ANIMATE_HIDE; | |
| 540 break; | |
| 541 case Widget::ANIMATE_BOTH: | |
| 542 wm_transition = wm::ANIMATE_BOTH; | |
| 543 break; | |
| 544 case Widget::ANIMATE_NONE: | |
| 545 wm_transition = wm::ANIMATE_NONE; | |
| 546 break; | |
| 547 } | |
| 548 wm::SetWindowVisibilityAnimationTransition(GetNativeWindow(), wm_transition); | |
| 549 } | |
| 550 | |
| 551 ui::NativeTheme* NativeWidgetAndroid::GetNativeTheme() const { | |
| 552 return ui::NativeThemeAura::instance(); | |
| 553 } | |
| 554 | |
| 555 void NativeWidgetAndroid::OnRootViewLayout() { | |
| 556 NOTIMPLEMENTED(); | |
| 557 } | |
| 558 | |
| 559 bool NativeWidgetAndroid::IsTranslucentWindowOpacitySupported() const { | |
| 560 return true; | |
| 561 } | |
| 562 | |
| 563 void NativeWidgetAndroid::OnSizeConstraintsChanged() { | |
| 564 window_->SetProperty(aura::client::kCanMaximizeKey, | |
| 565 GetWidget()->widget_delegate()->CanMaximize()); | |
| 566 window_->SetProperty(aura::client::kCanMinimizeKey, | |
| 567 GetWidget()->widget_delegate()->CanMinimize()); | |
| 568 window_->SetProperty(aura::client::kCanResizeKey, | |
| 569 GetWidget()->widget_delegate()->CanResize()); | |
| 570 } | |
| 571 | |
| 572 void NativeWidgetAndroid::RepostNativeEvent(gfx::NativeEvent native_event) { | |
| 573 OnEvent(native_event); | |
| 574 } | |
| 575 | |
| 576 //////////////////////////////////////////////////////////////////////////////// | |
| 577 // NativeWidgetAndroid, aura::WindowDelegate implementation: | |
| 578 | |
| 579 gfx::Size NativeWidgetAndroid::GetMinimumSize() const { | |
| 580 return delegate_->GetMinimumSize(); | |
| 581 } | |
| 582 | |
| 583 gfx::Size NativeWidgetAndroid::GetMaximumSize() const { | |
| 584 // If a window have a maximum size, the window should not be | |
| 585 // maximizable. | |
| 586 DCHECK(delegate_->GetMaximumSize().IsEmpty() || | |
| 587 !window_->GetProperty(aura::client::kCanMaximizeKey)); | |
| 588 return delegate_->GetMaximumSize(); | |
| 589 } | |
| 590 | |
| 591 void NativeWidgetAndroid::OnBoundsChanged(const gfx::Rect& old_bounds, | |
| 592 const gfx::Rect& new_bounds) { | |
| 593 // Assume that if the old bounds was completely empty a move happened. This | |
| 594 // handles the case of a maximize animation acquiring the layer (acquiring a | |
| 595 // layer results in clearing the bounds). | |
| 596 if (old_bounds.origin() != new_bounds.origin() || | |
| 597 (old_bounds == gfx::Rect(0, 0, 0, 0) && !new_bounds.IsEmpty())) { | |
| 598 delegate_->OnNativeWidgetMove(); | |
| 599 } | |
| 600 if (old_bounds.size() != new_bounds.size()) | |
| 601 delegate_->OnNativeWidgetSizeChanged(new_bounds.size()); | |
| 602 } | |
| 603 | |
| 604 gfx::NativeCursor NativeWidgetAndroid::GetCursor(const gfx::Point& point) { | |
| 605 return cursor_; | |
| 606 } | |
| 607 | |
| 608 int NativeWidgetAndroid::GetNonClientComponent(const gfx::Point& point) const { | |
| 609 return delegate_->GetNonClientComponent(point); | |
| 610 } | |
| 611 | |
| 612 bool NativeWidgetAndroid::ShouldDescendIntoChildForEventHandling( | |
| 613 aura::Window* child, | |
| 614 const gfx::Point& location) { | |
| 615 views::WidgetDelegate* widget_delegate = GetWidget()->widget_delegate(); | |
| 616 if (widget_delegate && | |
| 617 !widget_delegate->ShouldDescendIntoChildForEventHandling(child, location)) | |
| 618 return false; | |
| 619 | |
| 620 // Don't descend into |child| if there is a view with a Layer that contains | |
| 621 // the point and is stacked above |child|s layer. | |
| 622 typedef std::vector<ui::Layer*> Layers; | |
| 623 const Layers& root_layers(delegate_->GetRootLayers()); | |
| 624 if (root_layers.empty()) | |
| 625 return true; | |
| 626 | |
| 627 Layers::const_iterator child_layer_iter( | |
| 628 std::find(window_->layer()->children().begin(), | |
| 629 window_->layer()->children().end(), child->layer())); | |
| 630 if (child_layer_iter == window_->layer()->children().end()) | |
| 631 return true; | |
| 632 | |
| 633 for (std::vector<ui::Layer*>::const_reverse_iterator i = root_layers.rbegin(); | |
| 634 i != root_layers.rend(); ++i) { | |
| 635 ui::Layer* layer = *i; | |
| 636 if (layer->visible() && layer->bounds().Contains(location)) { | |
| 637 Layers::const_iterator root_layer_iter( | |
| 638 std::find(window_->layer()->children().begin(), | |
| 639 window_->layer()->children().end(), layer)); | |
| 640 if (root_layer_iter > child_layer_iter) | |
| 641 return false; | |
| 642 } | |
| 643 } | |
| 644 return true; | |
| 645 } | |
| 646 | |
| 647 bool NativeWidgetAndroid::CanFocus() { | |
| 648 return ShouldActivate(); | |
| 649 } | |
| 650 | |
| 651 void NativeWidgetAndroid::OnCaptureLost() { | |
| 652 delegate_->OnMouseCaptureLost(); | |
| 653 } | |
| 654 | |
| 655 void NativeWidgetAndroid::OnPaint(const ui::PaintContext& context) { | |
| 656 delegate_->OnNativeWidgetPaint(context); | |
| 657 } | |
| 658 | |
| 659 void NativeWidgetAndroid::OnDeviceScaleFactorChanged( | |
| 660 float device_scale_factor) { | |
| 661 GetWidget()->DeviceScaleFactorChanged(device_scale_factor); | |
| 662 } | |
| 663 | |
| 664 void NativeWidgetAndroid::OnWindowDestroying(aura::Window* window) { | |
| 665 delegate_->OnNativeWidgetDestroying(); | |
| 666 | |
| 667 // If the aura::Window is destroyed, we can no longer show tooltips. | |
| 668 tooltip_manager_.reset(); | |
| 669 } | |
| 670 | |
| 671 void NativeWidgetAndroid::OnWindowDestroyed(aura::Window* window) { | |
| 672 window_ = nullptr; | |
| 673 delegate_->OnNativeWidgetDestroyed(); | |
| 674 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) | |
| 675 delete this; | |
| 676 } | |
| 677 | |
| 678 void NativeWidgetAndroid::OnWindowTargetVisibilityChanged(bool visible) { | |
| 679 delegate_->OnNativeWidgetVisibilityChanged(visible); | |
| 680 } | |
| 681 | |
| 682 bool NativeWidgetAndroid::HasHitTestMask() const { | |
| 683 return delegate_->HasHitTestMask(); | |
| 684 } | |
| 685 | |
| 686 void NativeWidgetAndroid::GetHitTestMask(gfx::Path* mask) const { | |
| 687 DCHECK(mask); | |
| 688 delegate_->GetHitTestMask(mask); | |
| 689 } | |
| 690 | |
| 691 //////////////////////////////////////////////////////////////////////////////// | |
| 692 // NativeWidgetAndroid, ui::EventHandler implementation: | |
| 693 | |
| 694 void NativeWidgetAndroid::OnKeyEvent(ui::KeyEvent* event) { | |
| 695 DCHECK(window_); | |
| 696 // Renderer may send a key event back to us if the key event wasn't handled, | |
| 697 // and the window may be invisible by that time. | |
| 698 if (!window_->IsVisible()) | |
| 699 return; | |
| 700 | |
| 701 FocusManager* focus_manager = GetWidget()->GetFocusManager(); | |
| 702 delegate_->OnKeyEvent(event); | |
| 703 if (!event->handled() && focus_manager) | |
| 704 focus_manager->OnKeyEvent(*event); | |
| 705 event->SetHandled(); | |
| 706 } | |
| 707 | |
| 708 void NativeWidgetAndroid::OnMouseEvent(ui::MouseEvent* event) { | |
| 709 DCHECK(window_); | |
| 710 DCHECK(window_->IsVisible()); | |
| 711 if (event->type() == ui::ET_MOUSEWHEEL) { | |
| 712 delegate_->OnMouseEvent(event); | |
| 713 if (event->handled()) | |
| 714 return; | |
| 715 } | |
| 716 | |
| 717 if (tooltip_manager_.get()) | |
| 718 tooltip_manager_->UpdateTooltip(); | |
| 719 TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget()); | |
| 720 delegate_->OnMouseEvent(event); | |
| 721 } | |
| 722 | |
| 723 void NativeWidgetAndroid::OnScrollEvent(ui::ScrollEvent* event) { | |
| 724 delegate_->OnScrollEvent(event); | |
| 725 } | |
| 726 | |
| 727 void NativeWidgetAndroid::OnGestureEvent(ui::GestureEvent* event) { | |
| 728 DCHECK(window_); | |
| 729 DCHECK(window_->IsVisible() || event->IsEndingEvent()); | |
| 730 delegate_->OnGestureEvent(event); | |
| 731 } | |
| 732 | |
| 733 //////////////////////////////////////////////////////////////////////////////// | |
| 734 // NativeWidgetAndroid, aura::client::ActivationDelegate implementation: | |
| 735 | |
| 736 bool NativeWidgetAndroid::ShouldActivate() const { | |
| 737 return delegate_->CanActivate(); | |
| 738 } | |
| 739 | |
| 740 //////////////////////////////////////////////////////////////////////////////// | |
| 741 // NativeWidgetAndroid, aura::client::ActivationChangeObserver | |
| 742 // implementation: | |
| 743 | |
| 744 void NativeWidgetAndroid::OnWindowActivated( | |
| 745 aura::client::ActivationChangeObserver::ActivationReason, | |
| 746 aura::Window* gained_active, | |
| 747 aura::Window* lost_active) { | |
| 748 DCHECK(window_ == gained_active || window_ == lost_active); | |
| 749 if (GetWidget()->GetFocusManager()) { | |
| 750 if (window_ == gained_active) | |
| 751 GetWidget()->GetFocusManager()->RestoreFocusedView(); | |
| 752 else if (window_ == lost_active) | |
| 753 GetWidget()->GetFocusManager()->StoreFocusedView(true); | |
| 754 } | |
| 755 delegate_->OnNativeWidgetActivationChanged(window_ == gained_active); | |
| 756 } | |
| 757 | |
| 758 //////////////////////////////////////////////////////////////////////////////// | |
| 759 // NativeWidgetAndroid, aura::client::FocusChangeObserver: | |
| 760 | |
| 761 void NativeWidgetAndroid::OnWindowFocused(aura::Window* gained_focus, | |
| 762 aura::Window* lost_focus) { | |
| 763 if (window_ == gained_focus) | |
| 764 delegate_->OnNativeFocus(); | |
| 765 else if (window_ == lost_focus) | |
| 766 delegate_->OnNativeBlur(); | |
| 767 } | |
| 768 | |
| 769 //////////////////////////////////////////////////////////////////////////////// | |
| 770 // NativeWidgetAndroid, aura::WindowDragDropDelegate implementation: | |
| 771 | |
| 772 void NativeWidgetAndroid::OnDragEntered(const ui::DropTargetEvent& event) { | |
| 773 // TODO: Implement drag and drop. crbug.com/554029. | |
| 774 NOTIMPLEMENTED(); | |
| 775 } | |
| 776 | |
| 777 int NativeWidgetAndroid::OnDragUpdated(const ui::DropTargetEvent& event) { | |
| 778 // TODO: Implement drag and drop. crbug.com/554029. | |
| 779 NOTIMPLEMENTED(); | |
| 780 return 0; | |
| 781 } | |
| 782 | |
| 783 void NativeWidgetAndroid::OnDragExited() { | |
| 784 // TODO: Implement drag and drop. crbug.com/554029. | |
| 785 NOTIMPLEMENTED(); | |
| 786 } | |
| 787 | |
| 788 int NativeWidgetAndroid::OnPerformDrop(const ui::DropTargetEvent& event) { | |
| 789 // TODO: Implement drag and drop. crbug.com/554029. | |
| 790 NOTIMPLEMENTED(); | |
| 791 return 0; | |
| 792 } | |
| 793 | |
| 794 //////////////////////////////////////////////////////////////////////////////// | |
| 795 // NativeWidgetAndroid, aura::WindowTreeHostObserver implementation: | |
| 796 | |
| 797 void NativeWidgetAndroid::OnHostCloseRequested( | |
| 798 const aura::WindowTreeHost* host) { | |
| 799 GetWidget()->Close(); | |
| 800 } | |
| 801 | |
| 802 void NativeWidgetAndroid::OnHostResized(const aura::WindowTreeHost* host) { | |
| 803 gfx::Rect new_bounds = gfx::Rect(host_->window()->bounds().size()); | |
| 804 GetNativeWindow()->SetBounds(new_bounds); | |
| 805 delegate_->OnNativeWidgetSizeChanged(new_bounds.size()); | |
| 806 } | |
| 807 | |
| 808 void NativeWidgetAndroid::OnHostMoved(const aura::WindowTreeHost* host, | |
| 809 const gfx::Point& new_origin) { | |
| 810 TRACE_EVENT1("views", "NativeWidgetAndroid::OnHostMoved", "new_origin", | |
| 811 new_origin.ToString()); | |
| 812 | |
| 813 delegate_->OnNativeWidgetMove(); | |
| 814 } | |
| 815 | |
| 816 //////////////////////////////////////////////////////////////////////////////// | |
| 817 // NativeWidgetAndroid, protected: | |
| 818 | |
| 819 NativeWidgetAndroid::~NativeWidgetAndroid() { | |
| 820 destroying_ = true; | |
| 821 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) | |
| 822 delete delegate_; | |
| 823 else | |
| 824 CloseNow(); | |
| 825 } | |
| 826 | |
| 827 //////////////////////////////////////////////////////////////////////////////// | |
| 828 // NativeWidgetAndroid, private: | |
| 829 | |
| 830 bool NativeWidgetAndroid::IsDocked() const { | |
| 831 NOTIMPLEMENTED(); | |
| 832 return false; | |
| 833 } | |
| 834 | |
| 835 void NativeWidgetAndroid::SetInitialFocus(ui::WindowShowState show_state) { | |
| 836 // The window does not get keyboard messages unless we focus it. | |
| 837 if (!GetWidget()->SetInitialFocus(show_state)) | |
| 838 window_->Focus(); | |
| 839 } | |
| 840 | |
| 841 } // namespace views | |
| OLD | NEW |