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