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
64DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(VIEWS_EXPORT,
65                                      views::DesktopNativeWidgetAura*);
66
67namespace views {
68
69DEFINE_WINDOW_PROPERTY_KEY(DesktopNativeWidgetAura*,
70                           kDesktopNativeWidgetAuraKey, NULL);
71
72namespace {
73
74// This class provides functionality to create a top level widget to host a
75// child window.
76class 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
156class 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
190class 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
213DesktopNativeWidgetAura::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
231DesktopNativeWidgetAura::~DesktopNativeWidgetAura() {
232  if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
233    delete native_widget_delegate_;
234  else
235    CloseNow();
236}
237
238// static
239DesktopNativeWidgetAura* DesktopNativeWidgetAura::ForWindow(
240    aura::Window* window) {
241  return window->GetProperty(kDesktopNativeWidgetAuraKey);
242}
243
244void 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
295void 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
315void 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
349void 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
490NonClientFrameView* DesktopNativeWidgetAura::CreateNonClientFrameView() {
491  return desktop_root_window_host_->CreateNonClientFrameView();
492}
493
494bool DesktopNativeWidgetAura::ShouldUseNativeFrame() const {
495  return desktop_root_window_host_->ShouldUseNativeFrame();
496}
497
498void DesktopNativeWidgetAura::FrameTypeChanged() {
499  desktop_root_window_host_->FrameTypeChanged();
500  UpdateWindowTransparency();
501}
502
503Widget* DesktopNativeWidgetAura::GetWidget() {
504  return native_widget_delegate_->AsWidget();
505}
506
507const Widget* DesktopNativeWidgetAura::GetWidget() const {
508  return native_widget_delegate_->AsWidget();
509}
510
511gfx::NativeView DesktopNativeWidgetAura::GetNativeView() const {
512  return content_window_;
513}
514
515gfx::NativeWindow DesktopNativeWidgetAura::GetNativeWindow() const {
516  return content_window_;
517}
518
519Widget* DesktopNativeWidgetAura::GetTopLevelWidget() {
520  return GetWidget();
521}
522
523const ui::Compositor* DesktopNativeWidgetAura::GetCompositor() const {
524  return content_window_ ? content_window_->layer()->GetCompositor() : NULL;
525}
526
527ui::Compositor* DesktopNativeWidgetAura::GetCompositor() {
528  return const_cast<ui::Compositor*>(
529      const_cast<const DesktopNativeWidgetAura*>(this)->GetCompositor());
530}
531
532ui::Layer* DesktopNativeWidgetAura::GetLayer() {
533  return content_window_ ? content_window_->layer() : NULL;
534}
535
536void DesktopNativeWidgetAura::ReorderNativeViews() {
537  window_reorderer_->ReorderChildWindows();
538}
539
540void DesktopNativeWidgetAura::ViewRemoved(View* view) {
541}
542
543void DesktopNativeWidgetAura::SetNativeWindowProperty(const char* name,
544                                                      void* value) {
545  if (content_window_)
546    content_window_->SetNativeWindowProperty(name, value);
547}
548
549void* DesktopNativeWidgetAura::GetNativeWindowProperty(const char* name) const {
550  return content_window_ ?
551      content_window_->GetNativeWindowProperty(name) : NULL;
552}
553
554TooltipManager* DesktopNativeWidgetAura::GetTooltipManager() const {
555  return tooltip_manager_.get();
556}
557
558void DesktopNativeWidgetAura::SetCapture() {
559  if (!content_window_)
560    return;
561
562  content_window_->SetCapture();
563}
564
565void DesktopNativeWidgetAura::ReleaseCapture() {
566  if (!content_window_)
567    return;
568
569  content_window_->ReleaseCapture();
570}
571
572bool DesktopNativeWidgetAura::HasCapture() const {
573  return content_window_ && content_window_->HasCapture() &&
574      desktop_root_window_host_->HasCapture();
575}
576
577InputMethod* DesktopNativeWidgetAura::CreateInputMethod() {
578  ui::InputMethod* host = input_method_event_filter_->input_method();
579  return new InputMethodBridge(this, host, false);
580}
581
582internal::InputMethodDelegate*
583    DesktopNativeWidgetAura::GetInputMethodDelegate() {
584  return this;
585}
586
587void DesktopNativeWidgetAura::CenterWindow(const gfx::Size& size) {
588  if (content_window_)
589    desktop_root_window_host_->CenterWindow(size);
590}
591
592void 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
599bool DesktopNativeWidgetAura::SetWindowTitle(const string16& title) {
600  if (!content_window_)
601    return false;
602  return desktop_root_window_host_->SetWindowTitle(title);
603}
604
605void 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
611void 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
618gfx::Rect DesktopNativeWidgetAura::GetWindowBoundsInScreen() const {
619  return content_window_ ?
620      desktop_root_window_host_->GetWindowBoundsInScreen() : gfx::Rect();
621}
622
623gfx::Rect DesktopNativeWidgetAura::GetClientAreaBoundsInScreen() const {
624  return content_window_ ?
625      desktop_root_window_host_->GetClientAreaBoundsInScreen() : gfx::Rect();
626}
627
628gfx::Rect DesktopNativeWidgetAura::GetRestoredBounds() const {
629  return content_window_ ?
630      desktop_root_window_host_->GetRestoredBounds() : gfx::Rect();
631}
632
633void 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
652void DesktopNativeWidgetAura::SetSize(const gfx::Size& size) {
653  if (content_window_)
654    desktop_root_window_host_->SetSize(size);
655}
656
657void DesktopNativeWidgetAura::StackAbove(gfx::NativeView native_view) {
658}
659
660void DesktopNativeWidgetAura::StackAtTop() {
661  if (content_window_)
662    desktop_root_window_host_->StackAtTop();
663}
664
665void DesktopNativeWidgetAura::StackBelow(gfx::NativeView native_view) {
666}
667
668void DesktopNativeWidgetAura::SetShape(gfx::NativeRegion shape) {
669  if (content_window_)
670    desktop_root_window_host_->SetShape(shape);
671}
672
673void 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
683void DesktopNativeWidgetAura::CloseNow() {
684  if (content_window_)
685    desktop_root_window_host_->CloseNow();
686}
687
688void DesktopNativeWidgetAura::Show() {
689  if (!content_window_)
690    return;
691  desktop_root_window_host_->AsRootWindowHost()->Show();
692  content_window_->Show();
693}
694
695void DesktopNativeWidgetAura::Hide() {
696  if (!content_window_)
697    return;
698  desktop_root_window_host_->AsRootWindowHost()->Hide();
699  content_window_->Hide();
700}
701
702void 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
710void DesktopNativeWidgetAura::ShowWithWindowState(ui::WindowShowState state) {
711  if (!content_window_)
712    return;
713  desktop_root_window_host_->ShowWindowWithState(state);
714  content_window_->Show();
715}
716
717bool DesktopNativeWidgetAura::IsVisible() const {
718  return content_window_ && desktop_root_window_host_->IsVisible();
719}
720
721void DesktopNativeWidgetAura::Activate() {
722  if (content_window_)
723    desktop_root_window_host_->Activate();
724}
725
726void DesktopNativeWidgetAura::Deactivate() {
727  if (content_window_)
728    desktop_root_window_host_->Deactivate();
729}
730
731bool DesktopNativeWidgetAura::IsActive() const {
732  return content_window_ && desktop_root_window_host_->IsActive();
733}
734
735void DesktopNativeWidgetAura::SetAlwaysOnTop(bool always_on_top) {
736  if (content_window_)
737    desktop_root_window_host_->SetAlwaysOnTop(always_on_top);
738}
739
740bool DesktopNativeWidgetAura::IsAlwaysOnTop() const {
741  return content_window_ && desktop_root_window_host_->IsAlwaysOnTop();
742}
743
744void DesktopNativeWidgetAura::Maximize() {
745  if (content_window_)
746    desktop_root_window_host_->Maximize();
747}
748
749void DesktopNativeWidgetAura::Minimize() {
750  if (content_window_)
751    desktop_root_window_host_->Minimize();
752}
753
754bool DesktopNativeWidgetAura::IsMaximized() const {
755  return content_window_ && desktop_root_window_host_->IsMaximized();
756}
757
758bool DesktopNativeWidgetAura::IsMinimized() const {
759  return content_window_ && desktop_root_window_host_->IsMinimized();
760}
761
762void DesktopNativeWidgetAura::Restore() {
763  if (content_window_)
764    desktop_root_window_host_->Restore();
765}
766
767void DesktopNativeWidgetAura::SetFullscreen(bool fullscreen) {
768  if (content_window_)
769    desktop_root_window_host_->SetFullscreen(fullscreen);
770}
771
772bool DesktopNativeWidgetAura::IsFullscreen() const {
773  return content_window_ && desktop_root_window_host_->IsFullscreen();
774}
775
776void DesktopNativeWidgetAura::SetOpacity(unsigned char opacity) {
777  if (content_window_)
778    desktop_root_window_host_->SetOpacity(opacity);
779}
780
781void DesktopNativeWidgetAura::SetUseDragFrame(bool use_drag_frame) {
782}
783
784void DesktopNativeWidgetAura::FlashFrame(bool flash_frame) {
785  if (content_window_)
786    desktop_root_window_host_->FlashFrame(flash_frame);
787}
788
789void 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
798void DesktopNativeWidgetAura::SchedulePaintInRect(const gfx::Rect& rect) {
799  if (content_window_)
800    content_window_->SchedulePaintInRect(rect);
801}
802
803void 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
811bool 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
819void 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
828gfx::Rect DesktopNativeWidgetAura::GetWorkAreaBoundsInScreen() const {
829  return desktop_root_window_host_ ?
830      desktop_root_window_host_->GetWorkAreaBoundsInScreen() : gfx::Rect();
831}
832
833Widget::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
843void DesktopNativeWidgetAura::EndMoveLoop() {
844  if (content_window_)
845    desktop_root_window_host_->EndMoveLoop();
846}
847
848void DesktopNativeWidgetAura::SetVisibilityChangedAnimationsEnabled(
849    bool value) {
850  if (content_window_)
851    desktop_root_window_host_->SetVisibilityChangedAnimationsEnabled(value);
852}
853
854ui::NativeTheme* DesktopNativeWidgetAura::GetNativeTheme() const {
855  return DesktopRootWindowHost::GetNativeTheme(content_window_);
856}
857
858void DesktopNativeWidgetAura::OnRootViewLayout() const {
859  if (content_window_)
860    desktop_root_window_host_->OnRootViewLayout();
861}
862
863////////////////////////////////////////////////////////////////////////////////
864// DesktopNativeWidgetAura, aura::WindowDelegate implementation:
865
866gfx::Size DesktopNativeWidgetAura::GetMinimumSize() const {
867  return native_widget_delegate_->GetMinimumSize();
868}
869
870gfx::Size DesktopNativeWidgetAura::GetMaximumSize() const {
871  return native_widget_delegate_->GetMaximumSize();
872}
873
874gfx::NativeCursor DesktopNativeWidgetAura::GetCursor(const gfx::Point& point) {
875  return cursor_;
876}
877
878int DesktopNativeWidgetAura::GetNonClientComponent(
879    const gfx::Point& point) const {
880  return native_widget_delegate_->GetNonClientComponent(point);
881}
882
883bool 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
891bool DesktopNativeWidgetAura::CanFocus() {
892  return true;
893}
894
895void DesktopNativeWidgetAura::OnCaptureLost() {
896  native_widget_delegate_->OnMouseCaptureLost();
897}
898
899void DesktopNativeWidgetAura::OnPaint(gfx::Canvas* canvas) {
900  native_widget_delegate_->OnNativeWidgetPaint(canvas);
901}
902
903void DesktopNativeWidgetAura::OnDeviceScaleFactorChanged(
904    float device_scale_factor) {
905}
906
907void DesktopNativeWidgetAura::OnWindowDestroying() {
908  // Cleanup happens in OnHostClosed().
909}
910
911void 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
917void DesktopNativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible) {
918}
919
920bool DesktopNativeWidgetAura::HasHitTestMask() const {
921  return native_widget_delegate_->HasHitTestMask();
922}
923
924void DesktopNativeWidgetAura::GetHitTestMask(gfx::Path* mask) const {
925  native_widget_delegate_->GetHitTestMask(mask);
926}
927
928void DesktopNativeWidgetAura::DidRecreateLayer(ui::Layer* old_layer,
929                                               ui::Layer* new_layer) {}
930
931////////////////////////////////////////////////////////////////////////////////
932// DesktopNativeWidgetAura, ui::EventHandler implementation:
933
934void 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
956void 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
965void 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
981void DesktopNativeWidgetAura::OnTouchEvent(ui::TouchEvent* event) {
982  native_widget_delegate_->OnTouchEvent(event);
983}
984
985void DesktopNativeWidgetAura::OnGestureEvent(ui::GestureEvent* event) {
986  native_widget_delegate_->OnGestureEvent(event);
987}
988
989////////////////////////////////////////////////////////////////////////////////
990// DesktopNativeWidgetAura, aura::client::ActivationDelegate implementation:
991
992bool DesktopNativeWidgetAura::ShouldActivate() const {
993  return can_activate_ && native_widget_delegate_->CanActivate();
994}
995
996////////////////////////////////////////////////////////////////////////////////
997// DesktopNativeWidgetAura, aura::client::ActivationChangeObserver
998//    implementation:
999
1000void 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
1021void 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
1043void 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
1055void 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
1061int 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
1068void DesktopNativeWidgetAura::OnDragExited() {
1069  DCHECK(drop_helper_.get() != NULL);
1070  drop_helper_->OnDragExit();
1071}
1072
1073int 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
1083void DesktopNativeWidgetAura::OnRootWindowHostCloseRequested(
1084    const aura::RootWindow* root) {
1085  Close();
1086}
1087
1088void 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
1104void 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
1116ui::EventHandler* DesktopNativeWidgetAura::GetEventHandler() {
1117  return this;
1118}
1119
1120void 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
1130void DesktopNativeWidgetAura::UpdateWindowTransparency() {
1131  content_window_->SetTransparent(ShouldUseNativeFrame());
1132}
1133
1134}  // namespace views
1135