1 // Copyright (c) 2012 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/desktop_aura/desktop_native_widget_aura.h" 6 7 #include "base/bind.h" 8 #include "base/debug/trace_event.h" 9 #include "ui/aura/client/activation_client.h" 10 #include "ui/aura/client/aura_constants.h" 11 #include "ui/aura/client/cursor_client.h" 12 #include "ui/aura/client/drag_drop_client.h" 13 #include "ui/aura/client/focus_client.h" 14 #include "ui/aura/client/window_tree_client.h" 15 #include "ui/aura/root_window.h" 16 #include "ui/aura/window.h" 17 #include "ui/aura/window_observer.h" 18 #include "ui/aura/window_property.h" 19 #include "ui/aura/window_tree_host.h" 20 #include "ui/base/hit_test.h" 21 #include "ui/compositor/layer.h" 22 #include "ui/gfx/canvas.h" 23 #include "ui/gfx/display.h" 24 #include "ui/gfx/point_conversions.h" 25 #include "ui/gfx/screen.h" 26 #include "ui/gfx/size_conversions.h" 27 #include "ui/native_theme/native_theme.h" 28 #include "ui/views/corewm/compound_event_filter.h" 29 #include "ui/views/corewm/corewm_switches.h" 30 #include "ui/views/corewm/cursor_manager.h" 31 #include "ui/views/corewm/focus_controller.h" 32 #include "ui/views/corewm/input_method_event_filter.h" 33 #include "ui/views/corewm/native_cursor_manager.h" 34 #include "ui/views/corewm/shadow_controller.h" 35 #include "ui/views/corewm/shadow_types.h" 36 #include "ui/views/corewm/tooltip.h" 37 #include "ui/views/corewm/tooltip_controller.h" 38 #include "ui/views/corewm/visibility_controller.h" 39 #include "ui/views/corewm/window_modality_controller.h" 40 #include "ui/views/drag_utils.h" 41 #include "ui/views/ime/input_method.h" 42 #include "ui/views/ime/input_method_bridge.h" 43 #include "ui/views/widget/desktop_aura/desktop_capture_client.h" 44 #include "ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h" 45 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h" 46 #include "ui/views/widget/desktop_aura/desktop_event_client.h" 47 #include "ui/views/widget/desktop_aura/desktop_focus_rules.h" 48 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" 49 #include "ui/views/widget/desktop_aura/desktop_root_window_host.h" 50 #include "ui/views/widget/desktop_aura/desktop_screen_position_client.h" 51 #include "ui/views/widget/drop_helper.h" 52 #include "ui/views/widget/native_widget_aura.h" 53 #include "ui/views/widget/root_view.h" 54 #include "ui/views/widget/tooltip_manager_aura.h" 55 #include "ui/views/widget/widget.h" 56 #include "ui/views/widget/widget_aura_utils.h" 57 #include "ui/views/widget/widget_delegate.h" 58 #include "ui/views/widget/window_reorderer.h" 59 60 #if defined(OS_WIN) 61 #include "ui/gfx/win/dpi.h" 62 #endif 63 64 DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(VIEWS_EXPORT, 65 views::DesktopNativeWidgetAura*); 66 67 namespace views { 68 69 DEFINE_WINDOW_PROPERTY_KEY(DesktopNativeWidgetAura*, 70 kDesktopNativeWidgetAuraKey, NULL); 71 72 namespace { 73 74 // This class provides functionality to create a top level widget to host a 75 // child window. 76 class DesktopNativeWidgetTopLevelHandler : public aura::WindowObserver { 77 public: 78 // This function creates a widget with the bounds passed in which eventually 79 // becomes the parent of the child window passed in. 80 static aura::Window* CreateParentWindow(aura::Window* child_window, 81 const gfx::Rect& bounds, 82 bool full_screen) { 83 // This instance will get deleted when the widget is destroyed. 84 DesktopNativeWidgetTopLevelHandler* top_level_handler = 85 new DesktopNativeWidgetTopLevelHandler; 86 87 child_window->SetBounds(gfx::Rect(bounds.size())); 88 89 Widget::InitParams init_params; 90 init_params.type = full_screen ? Widget::InitParams::TYPE_WINDOW : 91 Widget::InitParams::TYPE_POPUP; 92 init_params.bounds = bounds; 93 init_params.ownership = Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET; 94 init_params.layer_type = ui::LAYER_NOT_DRAWN; 95 init_params.can_activate = full_screen; 96 // This widget instance will get deleted when the window is 97 // destroyed. 98 top_level_handler->top_level_widget_ = new Widget(); 99 top_level_handler->top_level_widget_->Init(init_params); 100 101 top_level_handler->top_level_widget_->SetFullscreen(full_screen); 102 top_level_handler->top_level_widget_->Show(); 103 104 aura::Window* native_window = 105 top_level_handler->top_level_widget_->GetNativeView(); 106 child_window->AddObserver(top_level_handler); 107 native_window->AddObserver(top_level_handler); 108 top_level_handler->child_window_ = child_window; 109 return native_window; 110 } 111 112 // aura::WindowObserver overrides 113 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { 114 window->RemoveObserver(this); 115 116 // If the widget is being destroyed by the OS then we should not try and 117 // destroy it again. 118 if (top_level_widget_ && 119 window == top_level_widget_->GetNativeView()) { 120 top_level_widget_ = NULL; 121 return; 122 } 123 124 if (top_level_widget_) { 125 DCHECK(top_level_widget_->GetNativeView()); 126 top_level_widget_->GetNativeView()->RemoveObserver(this); 127 // When we receive a notification that the child of the window created 128 // above is being destroyed we go ahead and initiate the destruction of 129 // the corresponding widget. 130 top_level_widget_->Close(); 131 top_level_widget_ = NULL; 132 } 133 delete this; 134 } 135 136 virtual void OnWindowBoundsChanged(aura::Window* window, 137 const gfx::Rect& old_bounds, 138 const gfx::Rect& new_bounds) OVERRIDE { 139 if (top_level_widget_ && window == child_window_) 140 top_level_widget_->SetSize(new_bounds.size()); 141 } 142 143 private: 144 DesktopNativeWidgetTopLevelHandler() 145 : top_level_widget_(NULL), 146 child_window_(NULL) {} 147 148 virtual ~DesktopNativeWidgetTopLevelHandler() {} 149 150 Widget* top_level_widget_; 151 aura::Window* child_window_; 152 153 DISALLOW_COPY_AND_ASSIGN(DesktopNativeWidgetTopLevelHandler); 154 }; 155 156 class DesktopNativeWidgetAuraWindowTreeClient : 157 public aura::client::WindowTreeClient { 158 public: 159 explicit DesktopNativeWidgetAuraWindowTreeClient( 160 aura::Window* root_window) 161 : root_window_(root_window) { 162 aura::client::SetWindowTreeClient(root_window_, this); 163 } 164 virtual ~DesktopNativeWidgetAuraWindowTreeClient() { 165 aura::client::SetWindowTreeClient(root_window_, NULL); 166 } 167 168 // Overridden from client::WindowTreeClient: 169 virtual aura::Window* GetDefaultParent(aura::Window* context, 170 aura::Window* window, 171 const gfx::Rect& bounds) OVERRIDE { 172 bool is_fullscreen = window->GetProperty(aura::client::kShowStateKey) == 173 ui::SHOW_STATE_FULLSCREEN; 174 bool is_menu = window->type() == aura::client::WINDOW_TYPE_MENU; 175 if (is_fullscreen || is_menu) { 176 return DesktopNativeWidgetTopLevelHandler::CreateParentWindow( 177 window, bounds, is_fullscreen); 178 } 179 return root_window_; 180 } 181 182 private: 183 aura::Window* root_window_; 184 185 DISALLOW_COPY_AND_ASSIGN(DesktopNativeWidgetAuraWindowTreeClient); 186 }; 187 188 } // namespace 189 190 class FocusManagerEventHandler : public ui::EventHandler { 191 public: 192 FocusManagerEventHandler(DesktopNativeWidgetAura* desktop_native_widget_aura) 193 : desktop_native_widget_aura_(desktop_native_widget_aura) {} 194 195 // Implementation of ui::EventHandler: 196 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE { 197 Widget* widget = desktop_native_widget_aura_->GetWidget(); 198 if (widget && widget->GetFocusManager()->GetFocusedView() && 199 !widget->GetFocusManager()->OnKeyEvent(*event)) { 200 event->SetHandled(); 201 } 202 } 203 204 private: 205 DesktopNativeWidgetAura* desktop_native_widget_aura_; 206 207 DISALLOW_COPY_AND_ASSIGN(FocusManagerEventHandler); 208 }; 209 210 //////////////////////////////////////////////////////////////////////////////// 211 // DesktopNativeWidgetAura, public: 212 213 DesktopNativeWidgetAura::DesktopNativeWidgetAura( 214 internal::NativeWidgetDelegate* delegate) 215 : ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), 216 close_widget_factory_(this), 217 can_activate_(true), 218 desktop_root_window_host_(NULL), 219 content_window_container_(NULL), 220 content_window_(new aura::Window(this)), 221 native_widget_delegate_(delegate), 222 last_drop_operation_(ui::DragDropTypes::DRAG_NONE), 223 restore_focus_on_activate_(false), 224 cursor_(gfx::kNullCursor), 225 widget_type_(Widget::InitParams::TYPE_WINDOW) { 226 content_window_->SetProperty(kDesktopNativeWidgetAuraKey, this); 227 aura::client::SetFocusChangeObserver(content_window_, this); 228 aura::client::SetActivationChangeObserver(content_window_, this); 229 } 230 231 DesktopNativeWidgetAura::~DesktopNativeWidgetAura() { 232 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) 233 delete native_widget_delegate_; 234 else 235 CloseNow(); 236 } 237 238 // static 239 DesktopNativeWidgetAura* DesktopNativeWidgetAura::ForWindow( 240 aura::Window* window) { 241 return window->GetProperty(kDesktopNativeWidgetAuraKey); 242 } 243 244 void DesktopNativeWidgetAura::OnHostClosed() { 245 // Don't invoke Widget::OnNativeWidgetDestroying(), its done by 246 // DesktopRootWindowHost. 247 248 // The WindowModalityController is at the front of the event pretarget 249 // handler list. We destroy it first to preserve order symantics. 250 if (window_modality_controller_) 251 window_modality_controller_.reset(); 252 253 // Make sure we don't have capture. Otherwise CaptureController and RootWindow 254 // are left referencing a deleted Window. 255 { 256 aura::Window* capture_window = capture_client_->GetCaptureWindow(); 257 if (capture_window && root_window_->window()->Contains(capture_window)) 258 capture_window->ReleaseCapture(); 259 } 260 261 // DesktopRootWindowHost owns the ActivationController which ShadowController 262 // references. Make sure we destroy ShadowController early on. 263 shadow_controller_.reset(); 264 tooltip_manager_.reset(); 265 root_window_->window()->RemovePreTargetHandler(tooltip_controller_.get()); 266 aura::client::SetTooltipClient(root_window_->window(), NULL); 267 tooltip_controller_.reset(); 268 269 root_window_event_filter_->RemoveHandler(input_method_event_filter_.get()); 270 271 window_tree_client_.reset(); // Uses root_window_ at destruction. 272 273 capture_client_.reset(); // Uses root_window_ at destruction. 274 275 // FocusController uses |content_window_|. Destroy it now so that we don't 276 // have to worry about the possibility of FocusController attempting to use 277 // |content_window_| after it's been destroyed but before all child windows 278 // have been destroyed. 279 root_window_->window()->RemovePreTargetHandler(focus_client_.get()); 280 aura::client::SetFocusClient(root_window_->window(), NULL); 281 aura::client::SetActivationClient(root_window_->window(), NULL); 282 focus_client_.reset(); 283 284 root_window_->RemoveRootWindowObserver(this); 285 root_window_.reset(); // Uses input_method_event_filter_ at destruction. 286 // RootWindow owns |desktop_root_window_host_|. 287 desktop_root_window_host_ = NULL; 288 content_window_ = NULL; 289 290 native_widget_delegate_->OnNativeWidgetDestroyed(); 291 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) 292 delete this; 293 } 294 295 void DesktopNativeWidgetAura::OnDesktopRootWindowHostDestroyed( 296 aura::RootWindow* root) { 297 // |root_window_| is still valid, but DesktopRootWindowHost is nearly 298 // destroyed. Do cleanup here of members DesktopRootWindowHost may also use. 299 aura::client::SetDispatcherClient(root->window(), NULL); 300 dispatcher_client_.reset(); 301 302 aura::client::SetCursorClient(root->window(), NULL); 303 cursor_client_.reset(); 304 305 aura::client::SetScreenPositionClient(root->window(), NULL); 306 position_client_.reset(); 307 308 aura::client::SetDragDropClient(root->window(), NULL); 309 drag_drop_client_.reset(); 310 311 aura::client::SetEventClient(root->window(), NULL); 312 event_client_.reset(); 313 } 314 315 void DesktopNativeWidgetAura::HandleActivationChanged(bool active) { 316 native_widget_delegate_->OnNativeWidgetActivationChanged(active); 317 aura::client::ActivationClient* activation_client = 318 aura::client::GetActivationClient(root_window_->window()); 319 if (!activation_client) 320 return; 321 if (active) { 322 if (GetWidget()->HasFocusManager()) { 323 // This function can be called before the focus manager has had a 324 // chance to set the focused view. In which case we should get the 325 // last focused view. 326 View* view_for_activation = 327 GetWidget()->GetFocusManager()->GetFocusedView() ? 328 GetWidget()->GetFocusManager()->GetFocusedView() : 329 GetWidget()->GetFocusManager()->GetStoredFocusView(); 330 if (!view_for_activation) 331 view_for_activation = GetWidget()->GetRootView(); 332 activation_client->ActivateWindow( 333 view_for_activation->GetWidget()->GetNativeView()); 334 } 335 } else { 336 // If we're not active we need to deactivate the corresponding 337 // aura::Window. This way if a child widget is active it gets correctly 338 // deactivated (child widgets don't get native desktop activation changes, 339 // only aura activation changes). 340 aura::Window* active_window = activation_client->GetActiveWindow(); 341 if (active_window) 342 activation_client->DeactivateWindow(active_window); 343 } 344 } 345 346 //////////////////////////////////////////////////////////////////////////////// 347 // DesktopNativeWidgetAura, internal::NativeWidgetPrivate implementation: 348 349 void DesktopNativeWidgetAura::InitNativeWidget( 350 const Widget::InitParams& params) { 351 ownership_ = params.ownership; 352 widget_type_ = params.type; 353 354 NativeWidgetAura::RegisterNativeWidgetForWindow(this, content_window_); 355 // Animations on TYPE_WINDOW are handled by the OS. Additionally if we animate 356 // these windows the size of the window gets augmented, effecting restore 357 // bounds and maximized windows in bad ways. 358 if (params.type == Widget::InitParams::TYPE_WINDOW && 359 !params.remove_standard_frame) { 360 content_window_->SetProperty(aura::client::kAnimationsDisabledKey, true); 361 } 362 content_window_->SetType(GetAuraWindowTypeForWidgetType(params.type)); 363 content_window_->Init(params.layer_type); 364 corewm::SetShadowType(content_window_, corewm::SHADOW_TYPE_NONE); 365 366 content_window_container_ = new aura::Window(NULL); 367 content_window_container_->Init(ui::LAYER_NOT_DRAWN); 368 content_window_container_->Show(); 369 content_window_container_->AddChild(content_window_); 370 371 desktop_root_window_host_ = params.desktop_root_window_host ? 372 params.desktop_root_window_host : 373 DesktopRootWindowHost::Create(native_widget_delegate_, this); 374 aura::RootWindow::CreateParams rw_params(params.bounds); 375 desktop_root_window_host_->Init(content_window_, params, &rw_params); 376 377 root_window_.reset(new aura::RootWindow(rw_params)); 378 root_window_->Init(); 379 root_window_->window()->AddChild(content_window_container_); 380 381 // The WindowsModalityController event filter should be at the head of the 382 // pre target handlers list. This ensures that it handles input events first 383 // when modal windows are at the top of the Zorder. 384 if (widget_type_ == Widget::InitParams::TYPE_WINDOW) 385 window_modality_controller_.reset( 386 new views::corewm::WindowModalityController(root_window_->window())); 387 388 // |root_window_event_filter_| must be created before 389 // OnRootWindowHostCreated() is invoked. 390 391 // CEF sets focus to the window the user clicks down on. 392 // TODO(beng): see if we can't do this some other way. CEF seems a heavy- 393 // handed way of accomplishing focus. 394 // No event filter for aura::Env. Create CompoundEvnetFilter per RootWindow. 395 root_window_event_filter_ = new corewm::CompoundEventFilter; 396 // Pass ownership of the filter to the root_window. 397 root_window_->window()->SetEventFilter(root_window_event_filter_); 398 399 desktop_root_window_host_->OnRootWindowCreated(root_window_.get(), params); 400 401 UpdateWindowTransparency(); 402 403 capture_client_.reset(new DesktopCaptureClient(root_window_->window())); 404 405 corewm::FocusController* focus_controller = 406 new corewm::FocusController(new DesktopFocusRules(content_window_)); 407 focus_client_.reset(focus_controller); 408 aura::client::SetFocusClient(root_window_->window(), focus_controller); 409 aura::client::SetActivationClient(root_window_->window(), focus_controller); 410 root_window_->window()->AddPreTargetHandler(focus_controller); 411 412 dispatcher_client_.reset(new DesktopDispatcherClient); 413 aura::client::SetDispatcherClient(root_window_->window(), 414 dispatcher_client_.get()); 415 416 DesktopNativeCursorManager* desktop_native_cursor_manager = 417 new views::DesktopNativeCursorManager( 418 root_window_.get(), 419 DesktopCursorLoaderUpdater::Create()); 420 cursor_client_.reset( 421 new views::corewm::CursorManager( 422 scoped_ptr<corewm::NativeCursorManager>( 423 desktop_native_cursor_manager))); 424 aura::client::SetCursorClient(root_window_->window(), cursor_client_.get()); 425 426 position_client_.reset(new DesktopScreenPositionClient()); 427 aura::client::SetScreenPositionClient(root_window_->window(), 428 position_client_.get()); 429 430 InstallInputMethodEventFilter(); 431 432 drag_drop_client_ = desktop_root_window_host_->CreateDragDropClient( 433 desktop_native_cursor_manager); 434 aura::client::SetDragDropClient(root_window_->window(), 435 drag_drop_client_.get()); 436 437 static_cast<aura::client::FocusClient*>(focus_client_.get())-> 438 FocusWindow(content_window_); 439 440 OnRootWindowHostResized(root_window_.get()); 441 442 root_window_->AddRootWindowObserver(this); 443 444 window_tree_client_.reset( 445 new DesktopNativeWidgetAuraWindowTreeClient(root_window_->window())); 446 drop_helper_.reset(new DropHelper( 447 static_cast<internal::RootView*>(GetWidget()->GetRootView()))); 448 aura::client::SetDragDropDelegate(content_window_, this); 449 450 tooltip_manager_.reset(new TooltipManagerAura(GetWidget())); 451 452 tooltip_controller_.reset( 453 new corewm::TooltipController( 454 desktop_root_window_host_->CreateTooltip())); 455 aura::client::SetTooltipClient(root_window_->window(), 456 tooltip_controller_.get()); 457 root_window_->window()->AddPreTargetHandler(tooltip_controller_.get()); 458 459 if (params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW) { 460 visibility_controller_.reset(new views::corewm::VisibilityController); 461 aura::client::SetVisibilityClient(root_window_->window(), 462 visibility_controller_.get()); 463 views::corewm::SetChildWindowVisibilityChangesAnimated( 464 root_window_->window()); 465 views::corewm::SetChildWindowVisibilityChangesAnimated( 466 content_window_container_); 467 } 468 469 if (params.type == Widget::InitParams::TYPE_WINDOW) { 470 focus_manager_event_handler_.reset(new FocusManagerEventHandler(this)); 471 root_window_->window()->AddPreTargetHandler( 472 focus_manager_event_handler_.get()); 473 } 474 475 event_client_.reset(new DesktopEventClient); 476 aura::client::SetEventClient(root_window_->window(), event_client_.get()); 477 478 aura::client::GetFocusClient(content_window_)->FocusWindow(content_window_); 479 480 aura::client::SetActivationDelegate(content_window_, this); 481 482 shadow_controller_.reset( 483 new corewm::ShadowController( 484 aura::client::GetActivationClient(root_window_->window()))); 485 486 window_reorderer_.reset(new WindowReorderer(content_window_, 487 GetWidget()->GetRootView())); 488 } 489 490 NonClientFrameView* DesktopNativeWidgetAura::CreateNonClientFrameView() { 491 return desktop_root_window_host_->CreateNonClientFrameView(); 492 } 493 494 bool DesktopNativeWidgetAura::ShouldUseNativeFrame() const { 495 return desktop_root_window_host_->ShouldUseNativeFrame(); 496 } 497 498 void DesktopNativeWidgetAura::FrameTypeChanged() { 499 desktop_root_window_host_->FrameTypeChanged(); 500 UpdateWindowTransparency(); 501 } 502 503 Widget* DesktopNativeWidgetAura::GetWidget() { 504 return native_widget_delegate_->AsWidget(); 505 } 506 507 const Widget* DesktopNativeWidgetAura::GetWidget() const { 508 return native_widget_delegate_->AsWidget(); 509 } 510 511 gfx::NativeView DesktopNativeWidgetAura::GetNativeView() const { 512 return content_window_; 513 } 514 515 gfx::NativeWindow DesktopNativeWidgetAura::GetNativeWindow() const { 516 return content_window_; 517 } 518 519 Widget* DesktopNativeWidgetAura::GetTopLevelWidget() { 520 return GetWidget(); 521 } 522 523 const ui::Compositor* DesktopNativeWidgetAura::GetCompositor() const { 524 return content_window_ ? content_window_->layer()->GetCompositor() : NULL; 525 } 526 527 ui::Compositor* DesktopNativeWidgetAura::GetCompositor() { 528 return const_cast<ui::Compositor*>( 529 const_cast<const DesktopNativeWidgetAura*>(this)->GetCompositor()); 530 } 531 532 ui::Layer* DesktopNativeWidgetAura::GetLayer() { 533 return content_window_ ? content_window_->layer() : NULL; 534 } 535 536 void DesktopNativeWidgetAura::ReorderNativeViews() { 537 window_reorderer_->ReorderChildWindows(); 538 } 539 540 void DesktopNativeWidgetAura::ViewRemoved(View* view) { 541 } 542 543 void DesktopNativeWidgetAura::SetNativeWindowProperty(const char* name, 544 void* value) { 545 if (content_window_) 546 content_window_->SetNativeWindowProperty(name, value); 547 } 548 549 void* DesktopNativeWidgetAura::GetNativeWindowProperty(const char* name) const { 550 return content_window_ ? 551 content_window_->GetNativeWindowProperty(name) : NULL; 552 } 553 554 TooltipManager* DesktopNativeWidgetAura::GetTooltipManager() const { 555 return tooltip_manager_.get(); 556 } 557 558 void DesktopNativeWidgetAura::SetCapture() { 559 if (!content_window_) 560 return; 561 562 content_window_->SetCapture(); 563 } 564 565 void DesktopNativeWidgetAura::ReleaseCapture() { 566 if (!content_window_) 567 return; 568 569 content_window_->ReleaseCapture(); 570 } 571 572 bool DesktopNativeWidgetAura::HasCapture() const { 573 return content_window_ && content_window_->HasCapture() && 574 desktop_root_window_host_->HasCapture(); 575 } 576 577 InputMethod* DesktopNativeWidgetAura::CreateInputMethod() { 578 ui::InputMethod* host = input_method_event_filter_->input_method(); 579 return new InputMethodBridge(this, host, false); 580 } 581 582 internal::InputMethodDelegate* 583 DesktopNativeWidgetAura::GetInputMethodDelegate() { 584 return this; 585 } 586 587 void DesktopNativeWidgetAura::CenterWindow(const gfx::Size& size) { 588 if (content_window_) 589 desktop_root_window_host_->CenterWindow(size); 590 } 591 592 void DesktopNativeWidgetAura::GetWindowPlacement( 593 gfx::Rect* bounds, 594 ui::WindowShowState* maximized) const { 595 if (content_window_) 596 desktop_root_window_host_->GetWindowPlacement(bounds, maximized); 597 } 598 599 bool DesktopNativeWidgetAura::SetWindowTitle(const string16& title) { 600 if (!content_window_) 601 return false; 602 return desktop_root_window_host_->SetWindowTitle(title); 603 } 604 605 void DesktopNativeWidgetAura::SetWindowIcons(const gfx::ImageSkia& window_icon, 606 const gfx::ImageSkia& app_icon) { 607 if (content_window_) 608 desktop_root_window_host_->SetWindowIcons(window_icon, app_icon); 609 } 610 611 void DesktopNativeWidgetAura::InitModalType(ui::ModalType modal_type) { 612 // 99% of the time, we should not be asked to create a 613 // DesktopNativeWidgetAura that is modal. We only support window modal 614 // dialogs on the same lines as non AURA. 615 desktop_root_window_host_->InitModalType(modal_type); 616 } 617 618 gfx::Rect DesktopNativeWidgetAura::GetWindowBoundsInScreen() const { 619 return content_window_ ? 620 desktop_root_window_host_->GetWindowBoundsInScreen() : gfx::Rect(); 621 } 622 623 gfx::Rect DesktopNativeWidgetAura::GetClientAreaBoundsInScreen() const { 624 return content_window_ ? 625 desktop_root_window_host_->GetClientAreaBoundsInScreen() : gfx::Rect(); 626 } 627 628 gfx::Rect DesktopNativeWidgetAura::GetRestoredBounds() const { 629 return content_window_ ? 630 desktop_root_window_host_->GetRestoredBounds() : gfx::Rect(); 631 } 632 633 void DesktopNativeWidgetAura::SetBounds(const gfx::Rect& bounds) { 634 if (!content_window_) 635 return; 636 // TODO(ananta) 637 // This code by default scales the bounds rectangle by 1. 638 // We could probably get rid of this and similar logic from 639 // the DesktopNativeWidgetAura::OnRootWindowHostResized function. 640 float scale = 1; 641 aura::Window* root = root_window_->window(); 642 if (root) { 643 scale = gfx::Screen::GetScreenFor(root)-> 644 GetDisplayNearestWindow(root).device_scale_factor(); 645 } 646 gfx::Rect bounds_in_pixels( 647 gfx::ToCeiledPoint(gfx::ScalePoint(bounds.origin(), scale)), 648 gfx::ToFlooredSize(gfx::ScaleSize(bounds.size(), scale))); 649 desktop_root_window_host_->AsRootWindowHost()->SetBounds(bounds_in_pixels); 650 } 651 652 void DesktopNativeWidgetAura::SetSize(const gfx::Size& size) { 653 if (content_window_) 654 desktop_root_window_host_->SetSize(size); 655 } 656 657 void DesktopNativeWidgetAura::StackAbove(gfx::NativeView native_view) { 658 } 659 660 void DesktopNativeWidgetAura::StackAtTop() { 661 if (content_window_) 662 desktop_root_window_host_->StackAtTop(); 663 } 664 665 void DesktopNativeWidgetAura::StackBelow(gfx::NativeView native_view) { 666 } 667 668 void DesktopNativeWidgetAura::SetShape(gfx::NativeRegion shape) { 669 if (content_window_) 670 desktop_root_window_host_->SetShape(shape); 671 } 672 673 void DesktopNativeWidgetAura::Close() { 674 if (!content_window_) 675 return; 676 677 content_window_->SuppressPaint(); 678 content_window_->Hide(); 679 680 desktop_root_window_host_->Close(); 681 } 682 683 void DesktopNativeWidgetAura::CloseNow() { 684 if (content_window_) 685 desktop_root_window_host_->CloseNow(); 686 } 687 688 void DesktopNativeWidgetAura::Show() { 689 if (!content_window_) 690 return; 691 desktop_root_window_host_->AsRootWindowHost()->Show(); 692 content_window_->Show(); 693 } 694 695 void DesktopNativeWidgetAura::Hide() { 696 if (!content_window_) 697 return; 698 desktop_root_window_host_->AsRootWindowHost()->Hide(); 699 content_window_->Hide(); 700 } 701 702 void DesktopNativeWidgetAura::ShowMaximizedWithBounds( 703 const gfx::Rect& restored_bounds) { 704 if (!content_window_) 705 return; 706 desktop_root_window_host_->ShowMaximizedWithBounds(restored_bounds); 707 content_window_->Show(); 708 } 709 710 void DesktopNativeWidgetAura::ShowWithWindowState(ui::WindowShowState state) { 711 if (!content_window_) 712 return; 713 desktop_root_window_host_->ShowWindowWithState(state); 714 content_window_->Show(); 715 } 716 717 bool DesktopNativeWidgetAura::IsVisible() const { 718 return content_window_ && desktop_root_window_host_->IsVisible(); 719 } 720 721 void DesktopNativeWidgetAura::Activate() { 722 if (content_window_) 723 desktop_root_window_host_->Activate(); 724 } 725 726 void DesktopNativeWidgetAura::Deactivate() { 727 if (content_window_) 728 desktop_root_window_host_->Deactivate(); 729 } 730 731 bool DesktopNativeWidgetAura::IsActive() const { 732 return content_window_ && desktop_root_window_host_->IsActive(); 733 } 734 735 void DesktopNativeWidgetAura::SetAlwaysOnTop(bool always_on_top) { 736 if (content_window_) 737 desktop_root_window_host_->SetAlwaysOnTop(always_on_top); 738 } 739 740 bool DesktopNativeWidgetAura::IsAlwaysOnTop() const { 741 return content_window_ && desktop_root_window_host_->IsAlwaysOnTop(); 742 } 743 744 void DesktopNativeWidgetAura::Maximize() { 745 if (content_window_) 746 desktop_root_window_host_->Maximize(); 747 } 748 749 void DesktopNativeWidgetAura::Minimize() { 750 if (content_window_) 751 desktop_root_window_host_->Minimize(); 752 } 753 754 bool DesktopNativeWidgetAura::IsMaximized() const { 755 return content_window_ && desktop_root_window_host_->IsMaximized(); 756 } 757 758 bool DesktopNativeWidgetAura::IsMinimized() const { 759 return content_window_ && desktop_root_window_host_->IsMinimized(); 760 } 761 762 void DesktopNativeWidgetAura::Restore() { 763 if (content_window_) 764 desktop_root_window_host_->Restore(); 765 } 766 767 void DesktopNativeWidgetAura::SetFullscreen(bool fullscreen) { 768 if (content_window_) 769 desktop_root_window_host_->SetFullscreen(fullscreen); 770 } 771 772 bool DesktopNativeWidgetAura::IsFullscreen() const { 773 return content_window_ && desktop_root_window_host_->IsFullscreen(); 774 } 775 776 void DesktopNativeWidgetAura::SetOpacity(unsigned char opacity) { 777 if (content_window_) 778 desktop_root_window_host_->SetOpacity(opacity); 779 } 780 781 void DesktopNativeWidgetAura::SetUseDragFrame(bool use_drag_frame) { 782 } 783 784 void DesktopNativeWidgetAura::FlashFrame(bool flash_frame) { 785 if (content_window_) 786 desktop_root_window_host_->FlashFrame(flash_frame); 787 } 788 789 void DesktopNativeWidgetAura::RunShellDrag( 790 View* view, 791 const ui::OSExchangeData& data, 792 const gfx::Point& location, 793 int operation, 794 ui::DragDropTypes::DragEventSource source) { 795 views::RunShellDrag(content_window_, data, location, operation, source); 796 } 797 798 void DesktopNativeWidgetAura::SchedulePaintInRect(const gfx::Rect& rect) { 799 if (content_window_) 800 content_window_->SchedulePaintInRect(rect); 801 } 802 803 void DesktopNativeWidgetAura::SetCursor(gfx::NativeCursor cursor) { 804 cursor_ = cursor; 805 aura::client::CursorClient* cursor_client = 806 aura::client::GetCursorClient(root_window_->window()); 807 if (cursor_client) 808 cursor_client->SetCursor(cursor); 809 } 810 811 bool DesktopNativeWidgetAura::IsMouseEventsEnabled() const { 812 if (!content_window_) 813 return false; 814 aura::client::CursorClient* cursor_client = 815 aura::client::GetCursorClient(root_window_->window()); 816 return cursor_client ? cursor_client->IsMouseEventsEnabled() : true; 817 } 818 819 void DesktopNativeWidgetAura::ClearNativeFocus() { 820 desktop_root_window_host_->ClearNativeFocus(); 821 822 if (ShouldActivate()) { 823 aura::client::GetFocusClient(content_window_)-> 824 ResetFocusWithinActiveWindow(content_window_); 825 } 826 } 827 828 gfx::Rect DesktopNativeWidgetAura::GetWorkAreaBoundsInScreen() const { 829 return desktop_root_window_host_ ? 830 desktop_root_window_host_->GetWorkAreaBoundsInScreen() : gfx::Rect(); 831 } 832 833 Widget::MoveLoopResult DesktopNativeWidgetAura::RunMoveLoop( 834 const gfx::Vector2d& drag_offset, 835 Widget::MoveLoopSource source, 836 Widget::MoveLoopEscapeBehavior escape_behavior) { 837 if (!content_window_) 838 return Widget::MOVE_LOOP_CANCELED; 839 return desktop_root_window_host_->RunMoveLoop(drag_offset, source, 840 escape_behavior); 841 } 842 843 void DesktopNativeWidgetAura::EndMoveLoop() { 844 if (content_window_) 845 desktop_root_window_host_->EndMoveLoop(); 846 } 847 848 void DesktopNativeWidgetAura::SetVisibilityChangedAnimationsEnabled( 849 bool value) { 850 if (content_window_) 851 desktop_root_window_host_->SetVisibilityChangedAnimationsEnabled(value); 852 } 853 854 ui::NativeTheme* DesktopNativeWidgetAura::GetNativeTheme() const { 855 return DesktopRootWindowHost::GetNativeTheme(content_window_); 856 } 857 858 void DesktopNativeWidgetAura::OnRootViewLayout() const { 859 if (content_window_) 860 desktop_root_window_host_->OnRootViewLayout(); 861 } 862 863 //////////////////////////////////////////////////////////////////////////////// 864 // DesktopNativeWidgetAura, aura::WindowDelegate implementation: 865 866 gfx::Size DesktopNativeWidgetAura::GetMinimumSize() const { 867 return native_widget_delegate_->GetMinimumSize(); 868 } 869 870 gfx::Size DesktopNativeWidgetAura::GetMaximumSize() const { 871 return native_widget_delegate_->GetMaximumSize(); 872 } 873 874 gfx::NativeCursor DesktopNativeWidgetAura::GetCursor(const gfx::Point& point) { 875 return cursor_; 876 } 877 878 int DesktopNativeWidgetAura::GetNonClientComponent( 879 const gfx::Point& point) const { 880 return native_widget_delegate_->GetNonClientComponent(point); 881 } 882 883 bool DesktopNativeWidgetAura::ShouldDescendIntoChildForEventHandling( 884 aura::Window* child, 885 const gfx::Point& location) { 886 views::WidgetDelegate* widget_delegate = GetWidget()->widget_delegate(); 887 return !widget_delegate || 888 widget_delegate->ShouldDescendIntoChildForEventHandling(child, location); 889 } 890 891 bool DesktopNativeWidgetAura::CanFocus() { 892 return true; 893 } 894 895 void DesktopNativeWidgetAura::OnCaptureLost() { 896 native_widget_delegate_->OnMouseCaptureLost(); 897 } 898 899 void DesktopNativeWidgetAura::OnPaint(gfx::Canvas* canvas) { 900 native_widget_delegate_->OnNativeWidgetPaint(canvas); 901 } 902 903 void DesktopNativeWidgetAura::OnDeviceScaleFactorChanged( 904 float device_scale_factor) { 905 } 906 907 void DesktopNativeWidgetAura::OnWindowDestroying() { 908 // Cleanup happens in OnHostClosed(). 909 } 910 911 void DesktopNativeWidgetAura::OnWindowDestroyed() { 912 // Cleanup happens in OnHostClosed(). We own |content_window_| (indirectly by 913 // way of |root_window_|) so there should be no need to do any processing 914 // here. 915 } 916 917 void DesktopNativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible) { 918 } 919 920 bool DesktopNativeWidgetAura::HasHitTestMask() const { 921 return native_widget_delegate_->HasHitTestMask(); 922 } 923 924 void DesktopNativeWidgetAura::GetHitTestMask(gfx::Path* mask) const { 925 native_widget_delegate_->GetHitTestMask(mask); 926 } 927 928 void DesktopNativeWidgetAura::DidRecreateLayer(ui::Layer* old_layer, 929 ui::Layer* new_layer) {} 930 931 //////////////////////////////////////////////////////////////////////////////// 932 // DesktopNativeWidgetAura, ui::EventHandler implementation: 933 934 void DesktopNativeWidgetAura::OnKeyEvent(ui::KeyEvent* event) { 935 if (event->is_char()) { 936 // If a ui::InputMethod object is attached to the root window, character 937 // events are handled inside the object and are not passed to this function. 938 // If such object is not attached, character events might be sent (e.g. on 939 // Windows). In this case, we just skip these. 940 return; 941 } 942 // Renderer may send a key event back to us if the key event wasn't handled, 943 // and the window may be invisible by that time. 944 if (!content_window_->IsVisible()) 945 return; 946 947 native_widget_delegate_->OnKeyEvent(event); 948 if (event->handled()) 949 return; 950 951 if (GetWidget()->HasFocusManager() && 952 !GetWidget()->GetFocusManager()->OnKeyEvent(*event)) 953 event->SetHandled(); 954 } 955 956 void DesktopNativeWidgetAura::OnMouseEvent(ui::MouseEvent* event) { 957 DCHECK(content_window_->IsVisible()); 958 if (tooltip_manager_.get()) 959 tooltip_manager_->UpdateTooltip(); 960 TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget()); 961 native_widget_delegate_->OnMouseEvent(event); 962 // WARNING: we may have been deleted. 963 } 964 965 void DesktopNativeWidgetAura::OnScrollEvent(ui::ScrollEvent* event) { 966 if (event->type() == ui::ET_SCROLL) { 967 native_widget_delegate_->OnScrollEvent(event); 968 if (event->handled()) 969 return; 970 971 // Convert unprocessed scroll events into wheel events. 972 ui::MouseWheelEvent mwe(*static_cast<ui::ScrollEvent*>(event)); 973 native_widget_delegate_->OnMouseEvent(&mwe); 974 if (mwe.handled()) 975 event->SetHandled(); 976 } else { 977 native_widget_delegate_->OnScrollEvent(event); 978 } 979 } 980 981 void DesktopNativeWidgetAura::OnTouchEvent(ui::TouchEvent* event) { 982 native_widget_delegate_->OnTouchEvent(event); 983 } 984 985 void DesktopNativeWidgetAura::OnGestureEvent(ui::GestureEvent* event) { 986 native_widget_delegate_->OnGestureEvent(event); 987 } 988 989 //////////////////////////////////////////////////////////////////////////////// 990 // DesktopNativeWidgetAura, aura::client::ActivationDelegate implementation: 991 992 bool DesktopNativeWidgetAura::ShouldActivate() const { 993 return can_activate_ && native_widget_delegate_->CanActivate(); 994 } 995 996 //////////////////////////////////////////////////////////////////////////////// 997 // DesktopNativeWidgetAura, aura::client::ActivationChangeObserver 998 // implementation: 999 1000 void DesktopNativeWidgetAura::OnWindowActivated(aura::Window* gained_active, 1001 aura::Window* lost_active) { 1002 DCHECK(content_window_ == gained_active || content_window_ == lost_active); 1003 if ((content_window_ == gained_active || content_window_ == lost_active) && 1004 IsVisible() && GetWidget()->non_client_view()) { 1005 GetWidget()->non_client_view()->SchedulePaint(); 1006 } 1007 if (gained_active == content_window_ && restore_focus_on_activate_) { 1008 restore_focus_on_activate_ = false; 1009 GetWidget()->GetFocusManager()->RestoreFocusedView(); 1010 } else if (lost_active == content_window_ && GetWidget()->HasFocusManager()) { 1011 DCHECK(!restore_focus_on_activate_); 1012 restore_focus_on_activate_ = true; 1013 // Pass in false so that ClearNativeFocus() isn't invoked. 1014 GetWidget()->GetFocusManager()->StoreFocusedView(false); 1015 } 1016 } 1017 1018 //////////////////////////////////////////////////////////////////////////////// 1019 // DesktopNativeWidgetAura, aura::client::FocusChangeObserver implementation: 1020 1021 void DesktopNativeWidgetAura::OnWindowFocused(aura::Window* gained_focus, 1022 aura::Window* lost_focus) { 1023 if (content_window_ == gained_focus) { 1024 desktop_root_window_host_->OnNativeWidgetFocus(); 1025 native_widget_delegate_->OnNativeFocus(lost_focus); 1026 1027 // If focus is moving from a descendant Window to |content_window_| then 1028 // native activation hasn't changed. We still need to inform the InputMethod 1029 // we've been focused though. 1030 InputMethod* input_method = GetWidget()->GetInputMethod(); 1031 if (input_method) 1032 input_method->OnFocus(); 1033 } else if (content_window_ == lost_focus) { 1034 desktop_root_window_host_->OnNativeWidgetBlur(); 1035 native_widget_delegate_->OnNativeBlur( 1036 aura::client::GetFocusClient(content_window_)->GetFocusedWindow()); 1037 } 1038 } 1039 1040 //////////////////////////////////////////////////////////////////////////////// 1041 // DesktopNativeWidgetAura, views::internal::InputMethodDelegate: 1042 1043 void DesktopNativeWidgetAura::DispatchKeyEventPostIME(const ui::KeyEvent& key) { 1044 FocusManager* focus_manager = 1045 native_widget_delegate_->AsWidget()->GetFocusManager(); 1046 native_widget_delegate_->OnKeyEvent(const_cast<ui::KeyEvent*>(&key)); 1047 if (key.handled() || !focus_manager) 1048 return; 1049 focus_manager->OnKeyEvent(key); 1050 } 1051 1052 //////////////////////////////////////////////////////////////////////////////// 1053 // DesktopNativeWidgetAura, aura::WindowDragDropDelegate implementation: 1054 1055 void DesktopNativeWidgetAura::OnDragEntered(const ui::DropTargetEvent& event) { 1056 DCHECK(drop_helper_.get() != NULL); 1057 last_drop_operation_ = drop_helper_->OnDragOver(event.data(), 1058 event.location(), event.source_operations()); 1059 } 1060 1061 int DesktopNativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent& event) { 1062 DCHECK(drop_helper_.get() != NULL); 1063 last_drop_operation_ = drop_helper_->OnDragOver(event.data(), 1064 event.location(), event.source_operations()); 1065 return last_drop_operation_; 1066 } 1067 1068 void DesktopNativeWidgetAura::OnDragExited() { 1069 DCHECK(drop_helper_.get() != NULL); 1070 drop_helper_->OnDragExit(); 1071 } 1072 1073 int DesktopNativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent& event) { 1074 DCHECK(drop_helper_.get() != NULL); 1075 Activate(); 1076 return drop_helper_->OnDrop(event.data(), event.location(), 1077 last_drop_operation_); 1078 } 1079 1080 //////////////////////////////////////////////////////////////////////////////// 1081 // DesktopNativeWidgetAura, aura::RootWindowObserver implementation: 1082 1083 void DesktopNativeWidgetAura::OnRootWindowHostCloseRequested( 1084 const aura::RootWindow* root) { 1085 Close(); 1086 } 1087 1088 void DesktopNativeWidgetAura::OnRootWindowHostResized( 1089 const aura::RootWindow* root) { 1090 // Don't update the bounds of the child layers when animating closed. If we 1091 // did it would force a paint, which we don't want. We don't want the paint 1092 // as we can't assume any of the children are valid. 1093 if (desktop_root_window_host_->IsAnimatingClosed()) 1094 return; 1095 1096 gfx::Rect new_bounds = gfx::Rect(root->window()->bounds().size()); 1097 content_window_->SetBounds(new_bounds); 1098 // Can be NULL at start. 1099 if (content_window_container_) 1100 content_window_container_->SetBounds(new_bounds); 1101 native_widget_delegate_->OnNativeWidgetSizeChanged(new_bounds.size()); 1102 } 1103 1104 void DesktopNativeWidgetAura::OnRootWindowHostMoved( 1105 const aura::RootWindow* root, 1106 const gfx::Point& new_origin) { 1107 TRACE_EVENT1("views", "DesktopNativeWidgetAura::OnRootWindowHostMoved", 1108 "new_origin", new_origin.ToString()); 1109 1110 native_widget_delegate_->OnNativeWidgetMove(); 1111 } 1112 1113 //////////////////////////////////////////////////////////////////////////////// 1114 // DesktopNativeWidgetAura, NativeWidget implementation: 1115 1116 ui::EventHandler* DesktopNativeWidgetAura::GetEventHandler() { 1117 return this; 1118 } 1119 1120 void DesktopNativeWidgetAura::InstallInputMethodEventFilter() { 1121 DCHECK(!input_method_event_filter_.get()); 1122 1123 input_method_event_filter_.reset(new corewm::InputMethodEventFilter( 1124 root_window_->host()->GetAcceleratedWidget())); 1125 input_method_event_filter_->SetInputMethodPropertyInRootWindow( 1126 root_window_->window()); 1127 root_window_event_filter_->AddHandler(input_method_event_filter_.get()); 1128 } 1129 1130 void DesktopNativeWidgetAura::UpdateWindowTransparency() { 1131 content_window_->SetTransparent(ShouldUseNativeFrame()); 1132 } 1133 1134 } // namespace views 1135