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