native_widget_aura.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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/native_widget_aura.h"
6
7#include "base/bind.h"
8#include "base/strings/string_util.h"
9#include "third_party/skia/include/core/SkRegion.h"
10#include "ui/aura/client/activation_client.h"
11#include "ui/aura/client/aura_constants.h"
12#include "ui/aura/client/cursor_client.h"
13#include "ui/aura/client/drag_drop_client.h"
14#include "ui/aura/client/focus_client.h"
15#include "ui/aura/client/screen_position_client.h"
16#include "ui/aura/client/window_move_client.h"
17#include "ui/aura/client/window_tree_client.h"
18#include "ui/aura/client/window_types.h"
19#include "ui/aura/env.h"
20#include "ui/aura/root_window.h"
21#include "ui/aura/window.h"
22#include "ui/aura/window_observer.h"
23#include "ui/base/dragdrop/os_exchange_data.h"
24#include "ui/base/ui_base_types.h"
25#include "ui/compositor/layer.h"
26#include "ui/events/event.h"
27#include "ui/gfx/canvas.h"
28#include "ui/gfx/font.h"
29#include "ui/gfx/screen.h"
30#include "ui/native_theme/native_theme_aura.h"
31#include "ui/views/drag_utils.h"
32#include "ui/views/ime/input_method_bridge.h"
33#include "ui/views/views_delegate.h"
34#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
35#include "ui/views/widget/drop_helper.h"
36#include "ui/views/widget/native_widget_delegate.h"
37#include "ui/views/widget/root_view.h"
38#include "ui/views/widget/tooltip_manager_aura.h"
39#include "ui/views/widget/widget_aura_utils.h"
40#include "ui/views/widget/widget_delegate.h"
41#include "ui/views/widget/window_reorderer.h"
42
43#if defined(OS_WIN)
44#include "base/win/scoped_gdi_object.h"
45#include "base/win/win_util.h"
46#include "ui/base/l10n/l10n_util_win.h"
47#include "ui/views/widget/desktop_aura/desktop_root_window_host_win.h"
48#endif
49
50#if defined(USE_X11) && !defined(OS_CHROMEOS)
51#include "ui/views/widget/desktop_aura/desktop_root_window_host_x11.h"
52#endif
53
54#if !defined(OS_CHROMEOS)
55#include "ui/views/widget/desktop_aura/desktop_root_window_host.h"
56#endif
57
58namespace views {
59
60namespace {
61
62void SetRestoreBounds(aura::Window* window, const gfx::Rect& bounds) {
63  window->SetProperty(aura::client::kRestoreBoundsKey, new gfx::Rect(bounds));
64}
65
66}  // namespace
67
68////////////////////////////////////////////////////////////////////////////////
69// NativeWidgetAura, public:
70
71NativeWidgetAura::NativeWidgetAura(internal::NativeWidgetDelegate* delegate)
72    : delegate_(delegate),
73      window_(new aura::Window(this)),
74      ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
75      close_widget_factory_(this),
76      can_activate_(true),
77      destroying_(false),
78      cursor_(gfx::kNullCursor),
79      saved_window_state_(ui::SHOW_STATE_DEFAULT) {
80  aura::client::SetFocusChangeObserver(window_, this);
81  aura::client::SetActivationChangeObserver(window_, this);
82}
83
84// static
85gfx::Font NativeWidgetAura::GetWindowTitleFont() {
86#if defined(OS_WIN)
87  NONCLIENTMETRICS ncm;
88  base::win::GetNonClientMetrics(&ncm);
89  l10n_util::AdjustUIFont(&(ncm.lfCaptionFont));
90  base::win::ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont)));
91  return gfx::Font(caption_font);
92#else
93  return gfx::Font();
94#endif
95}
96
97// static
98void NativeWidgetAura::RegisterNativeWidgetForWindow(
99      internal::NativeWidgetPrivate* native_widget,
100      aura::Window* window) {
101  window->set_user_data(native_widget);
102}
103
104////////////////////////////////////////////////////////////////////////////////
105// NativeWidgetAura, internal::NativeWidgetPrivate implementation:
106
107void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) {
108  // Aura needs to know which desktop (Ash or regular) will manage this widget.
109  // See Widget::InitParams::context for details.
110  DCHECK(params.parent || params.context);
111
112  ownership_ = params.ownership;
113
114  RegisterNativeWidgetForWindow(this, window_);
115  window_->SetType(GetAuraWindowTypeForWidgetType(params.type));
116  window_->SetProperty(aura::client::kShowStateKey, params.show_state);
117  if (params.type == Widget::InitParams::TYPE_BUBBLE)
118    aura::client::SetHideOnDeactivate(window_, true);
119  window_->SetTransparent(
120      params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW);
121  window_->Init(params.layer_type);
122  if (params.type == Widget::InitParams::TYPE_CONTROL)
123    window_->Show();
124
125  delegate_->OnNativeWidgetCreated(false);
126
127  gfx::Rect window_bounds = params.bounds;
128  gfx::NativeView parent = params.parent;
129  gfx::NativeView context = params.context;
130  if (!params.child) {
131    // Set up the transient child before the window is added. This way the
132    // LayoutManager knows the window has a transient parent.
133    if (parent && parent->type() != aura::client::WINDOW_TYPE_UNKNOWN) {
134      parent->AddTransientChild(window_);
135      if (!context)
136        context = parent;
137      parent = NULL;
138    }
139    // SetAlwaysOnTop before SetParent so that always-on-top container is used.
140    SetAlwaysOnTop(params.keep_on_top);
141    // Make sure we have a real |window_bounds|.
142    if (parent && window_bounds == gfx::Rect()) {
143      // If a parent is specified but no bounds are given,
144      // use the origin of the parent's display so that the widget
145      // will be added to the same display as the parent.
146      gfx::Rect bounds = gfx::Screen::GetScreenFor(parent)->
147          GetDisplayNearestWindow(parent).bounds();
148      window_bounds.set_origin(bounds.origin());
149    }
150  }
151
152  if (parent) {
153    parent->AddChild(window_);
154  } else {
155    aura::client::ParentWindowWithContext(
156        window_, context->GetRootWindow(), window_bounds);
157  }
158
159  // Wait to set the bounds until we have a parent. That way we can know our
160  // true state/bounds (the LayoutManager may enforce a particular
161  // state/bounds).
162  if (IsMaximized())
163    SetRestoreBounds(window_, window_bounds);
164  else
165    SetBounds(window_bounds);
166  window_->set_ignore_events(!params.accept_events);
167  can_activate_ = params.can_activate &&
168      params.type != Widget::InitParams::TYPE_CONTROL &&
169      params.type != Widget::InitParams::TYPE_TOOLTIP;
170  DCHECK(GetWidget()->GetRootView());
171  if (params.type != Widget::InitParams::TYPE_TOOLTIP)
172    tooltip_manager_.reset(new views::TooltipManagerAura(GetWidget()));
173
174  drop_helper_.reset(new DropHelper(GetWidget()->GetRootView()));
175  if (params.type != Widget::InitParams::TYPE_TOOLTIP &&
176      params.type != Widget::InitParams::TYPE_POPUP) {
177    aura::client::SetDragDropDelegate(window_, this);
178  }
179
180  aura::client::SetActivationDelegate(window_, this);
181
182  window_->SetProperty(aura::client::kCanMaximizeKey,
183                       GetWidget()->widget_delegate()->CanMaximize());
184  window_->SetProperty(aura::client::kCanResizeKey,
185                       GetWidget()->widget_delegate()->CanResize());
186
187  window_reorderer_.reset(new WindowReorderer(window_,
188      GetWidget()->GetRootView()));
189}
190
191NonClientFrameView* NativeWidgetAura::CreateNonClientFrameView() {
192  return NULL;
193}
194
195bool NativeWidgetAura::ShouldUseNativeFrame() const {
196  // There is only one frame type for aura.
197  return false;
198}
199
200void NativeWidgetAura::FrameTypeChanged() {
201  // This is called when the Theme has changed; forward the event to the root
202  // widget.
203  GetWidget()->ThemeChanged();
204  GetWidget()->GetRootView()->SchedulePaint();
205}
206
207Widget* NativeWidgetAura::GetWidget() {
208  return delegate_->AsWidget();
209}
210
211const Widget* NativeWidgetAura::GetWidget() const {
212  return delegate_->AsWidget();
213}
214
215gfx::NativeView NativeWidgetAura::GetNativeView() const {
216  return window_;
217}
218
219gfx::NativeWindow NativeWidgetAura::GetNativeWindow() const {
220  return window_;
221}
222
223Widget* NativeWidgetAura::GetTopLevelWidget() {
224  NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView());
225  return native_widget ? native_widget->GetWidget() : NULL;
226}
227
228const ui::Compositor* NativeWidgetAura::GetCompositor() const {
229  return window_ ? window_->layer()->GetCompositor() : NULL;
230}
231
232ui::Compositor* NativeWidgetAura::GetCompositor() {
233  return window_ ? window_->layer()->GetCompositor() : NULL;
234}
235
236ui::Layer* NativeWidgetAura::GetLayer() {
237  return window_ ? window_->layer() : NULL;
238}
239
240void NativeWidgetAura::ReorderNativeViews() {
241  window_reorderer_->ReorderChildWindows();
242}
243
244void NativeWidgetAura::ViewRemoved(View* view) {
245  DCHECK(drop_helper_.get() != NULL);
246  drop_helper_->ResetTargetViewIfEquals(view);
247}
248
249void NativeWidgetAura::SetNativeWindowProperty(const char* name, void* value) {
250  if (window_)
251    window_->SetNativeWindowProperty(name, value);
252}
253
254void* NativeWidgetAura::GetNativeWindowProperty(const char* name) const {
255  return window_ ? window_->GetNativeWindowProperty(name) : NULL;
256}
257
258TooltipManager* NativeWidgetAura::GetTooltipManager() const {
259  return tooltip_manager_.get();
260}
261
262void NativeWidgetAura::SetCapture() {
263  if (window_)
264    window_->SetCapture();
265}
266
267void NativeWidgetAura::ReleaseCapture() {
268  if (window_)
269    window_->ReleaseCapture();
270}
271
272bool NativeWidgetAura::HasCapture() const {
273  return window_ && window_->HasCapture();
274}
275
276InputMethod* NativeWidgetAura::CreateInputMethod() {
277  if (!window_)
278    return NULL;
279  aura::Window* root_window = window_->GetRootWindow();
280  ui::InputMethod* host =
281      root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
282  return new InputMethodBridge(this, host, true);
283}
284
285internal::InputMethodDelegate* NativeWidgetAura::GetInputMethodDelegate() {
286  return this;
287}
288
289void NativeWidgetAura::CenterWindow(const gfx::Size& size) {
290  if (!window_)
291    return;
292
293  gfx::Rect parent_bounds(window_->parent()->GetBoundsInRootWindow());
294  // When centering window, we take the intersection of the host and
295  // the parent. We assume the root window represents the visible
296  // rect of a single screen.
297  gfx::Rect work_area = gfx::Screen::GetScreenFor(window_)->
298      GetDisplayNearestWindow(window_).work_area();
299
300  aura::client::ScreenPositionClient* screen_position_client =
301      aura::client::GetScreenPositionClient(window_->GetRootWindow());
302  if (screen_position_client) {
303    gfx::Point origin = work_area.origin();
304    screen_position_client->ConvertPointFromScreen(window_->GetRootWindow(),
305                                                   &origin);
306    work_area.set_origin(origin);
307  }
308
309  parent_bounds.Intersect(work_area);
310
311  // If |window_|'s transient parent's bounds are big enough to fit it, then we
312  // center it with respect to the transient parent.
313  if (window_->transient_parent()) {
314    gfx::Rect transient_parent_rect = window_->transient_parent()->
315        GetBoundsInRootWindow();
316    transient_parent_rect.Intersect(work_area);
317    if (transient_parent_rect.height() >= size.height() &&
318        transient_parent_rect.width() >= size.width())
319      parent_bounds = transient_parent_rect;
320  }
321
322  gfx::Rect window_bounds(
323      parent_bounds.x() + (parent_bounds.width() - size.width()) / 2,
324      parent_bounds.y() + (parent_bounds.height() - size.height()) / 2,
325      size.width(),
326      size.height());
327  // Don't size the window bigger than the parent, otherwise the user may not be
328  // able to close or move it.
329  window_bounds.AdjustToFit(parent_bounds);
330
331  // Convert the bounds back relative to the parent.
332  gfx::Point origin = window_bounds.origin();
333  aura::Window::ConvertPointToTarget(window_->GetRootWindow(),
334      window_->parent(), &origin);
335  window_bounds.set_origin(origin);
336  window_->SetBounds(window_bounds);
337}
338
339void NativeWidgetAura::GetWindowPlacement(
340    gfx::Rect* bounds,
341    ui::WindowShowState* show_state) const {
342  // The interface specifies returning restored bounds, not current bounds.
343  *bounds = GetRestoredBounds();
344  *show_state = window_ ? window_->GetProperty(aura::client::kShowStateKey) :
345      ui::SHOW_STATE_DEFAULT;
346}
347
348void NativeWidgetAura::SetWindowTitle(const string16& title) {
349  if (window_)
350    window_->set_title(title);
351}
352
353void NativeWidgetAura::SetWindowIcons(const gfx::ImageSkia& window_icon,
354                                      const gfx::ImageSkia& app_icon) {
355  // Aura doesn't have window icons.
356}
357
358void NativeWidgetAura::InitModalType(ui::ModalType modal_type) {
359  if (modal_type != ui::MODAL_TYPE_NONE)
360    window_->SetProperty(aura::client::kModalKey, modal_type);
361}
362
363gfx::Rect NativeWidgetAura::GetWindowBoundsInScreen() const {
364  return window_ ? window_->GetBoundsInScreen() : gfx::Rect();
365}
366
367gfx::Rect NativeWidgetAura::GetClientAreaBoundsInScreen() const {
368  // View-to-screen coordinate system transformations depend on this returning
369  // the full window bounds, for example View::ConvertPointToScreen().
370  return window_ ? window_->GetBoundsInScreen() : gfx::Rect();
371}
372
373gfx::Rect NativeWidgetAura::GetRestoredBounds() const {
374  if (!window_)
375    return gfx::Rect();
376
377  // Restored bounds should only be relevant if the window is minimized or
378  // maximized. However, in some places the code expects GetRestoredBounds()
379  // to return the current window bounds if the window is not in either state.
380  if (IsMinimized() || IsMaximized() || IsFullscreen()) {
381    // Restore bounds are in screen coordinates, no need to convert.
382    gfx::Rect* restore_bounds =
383        window_->GetProperty(aura::client::kRestoreBoundsKey);
384    if (restore_bounds)
385      return *restore_bounds;
386  }
387  return window_->GetBoundsInScreen();
388}
389
390void NativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
391  if (!window_)
392    return;
393
394  aura::Window* root = window_->GetRootWindow();
395  if (root) {
396    aura::client::ScreenPositionClient* screen_position_client =
397        aura::client::GetScreenPositionClient(root);
398    if (screen_position_client) {
399      gfx::Display dst_display =
400          gfx::Screen::GetScreenFor(window_)->GetDisplayMatching(bounds);
401      screen_position_client->SetBounds(window_, bounds, dst_display);
402      return;
403    }
404  }
405  window_->SetBounds(bounds);
406}
407
408void NativeWidgetAura::SetSize(const gfx::Size& size) {
409  if (window_)
410    window_->SetBounds(gfx::Rect(window_->bounds().origin(), size));
411}
412
413void NativeWidgetAura::StackAbove(gfx::NativeView native_view) {
414  if (window_ && window_->parent() &&
415      window_->parent() == native_view->parent())
416    window_->parent()->StackChildAbove(window_, native_view);
417}
418
419void NativeWidgetAura::StackAtTop() {
420  if (window_)
421    window_->parent()->StackChildAtTop(window_);
422}
423
424void NativeWidgetAura::StackBelow(gfx::NativeView native_view) {
425  if (window_ && window_->parent() &&
426      window_->parent() == native_view->parent())
427    window_->parent()->StackChildBelow(window_, native_view);
428}
429
430void NativeWidgetAura::SetShape(gfx::NativeRegion region) {
431  // No need for this. Just delete and ignore.
432  delete region;
433}
434
435void NativeWidgetAura::Close() {
436  // |window_| may already be deleted by parent window. This can happen
437  // when this widget is child widget or has transient parent
438  // and ownership is WIDGET_OWNS_NATIVE_WIDGET.
439  DCHECK(window_ ||
440         ownership_ == Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET);
441  if (window_) {
442    window_->SuppressPaint();
443    Hide();
444    window_->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_NONE);
445  }
446
447  if (!close_widget_factory_.HasWeakPtrs()) {
448    base::MessageLoop::current()->PostTask(
449        FROM_HERE,
450        base::Bind(&NativeWidgetAura::CloseNow,
451                   close_widget_factory_.GetWeakPtr()));
452  }
453}
454
455void NativeWidgetAura::CloseNow() {
456  delete window_;
457}
458
459void NativeWidgetAura::Show() {
460  ShowWithWindowState(ui::SHOW_STATE_INACTIVE);
461}
462
463void NativeWidgetAura::Hide() {
464  if (window_)
465    window_->Hide();
466}
467
468void NativeWidgetAura::ShowMaximizedWithBounds(
469    const gfx::Rect& restored_bounds) {
470  SetRestoreBounds(window_, restored_bounds);
471  ShowWithWindowState(ui::SHOW_STATE_MAXIMIZED);
472}
473
474void NativeWidgetAura::ShowWithWindowState(ui::WindowShowState state) {
475  if (!window_)
476    return;
477
478  if (state == ui::SHOW_STATE_MAXIMIZED || state == ui::SHOW_STATE_FULLSCREEN)
479    window_->SetProperty(aura::client::kShowStateKey, state);
480  window_->Show();
481  if (can_activate_) {
482    if (state != ui::SHOW_STATE_INACTIVE)
483      Activate();
484    // SetInitialFocus() should be always be called, even for
485    // SHOW_STATE_INACTIVE. When a frameless modal dialog is created by
486    // a widget of TYPE_WINDOW_FRAMELESS, Widget::Show() will call into
487    // this function with the window state SHOW_STATE_INACTIVE,
488    // SetInitialFoucs() has to be called so that the dialog can get focus.
489    // This also matches NativeWidgetWin which invokes SetInitialFocus
490    // regardless of show state.
491    SetInitialFocus();
492  }
493}
494
495bool NativeWidgetAura::IsVisible() const {
496  return window_ && window_->IsVisible();
497}
498
499void NativeWidgetAura::Activate() {
500  if (!window_)
501    return;
502
503  // We don't necessarily have a root window yet. This can happen with
504  // constrained windows.
505  if (window_->GetRootWindow()) {
506    aura::client::GetActivationClient(window_->GetRootWindow())->ActivateWindow(
507        window_);
508  }
509  if (window_->GetProperty(aura::client::kDrawAttentionKey))
510    window_->SetProperty(aura::client::kDrawAttentionKey, false);
511}
512
513void NativeWidgetAura::Deactivate() {
514  if (!window_)
515    return;
516  aura::client::GetActivationClient(window_->GetRootWindow())->DeactivateWindow(
517      window_);
518}
519
520bool NativeWidgetAura::IsActive() const {
521  if (!window_)
522    return false;
523
524  // We may up here during destruction of the root, in which case
525  // GetRootWindow() returns NULL (~RootWindow() has run and we're in ~Window).
526  aura::Window* root = window_->GetRootWindow();
527  return root &&
528      aura::client::GetActivationClient(root)->GetActiveWindow() == window_;
529}
530
531void NativeWidgetAura::SetAlwaysOnTop(bool on_top) {
532  if (window_)
533    window_->SetProperty(aura::client::kAlwaysOnTopKey, on_top);
534}
535
536bool NativeWidgetAura::IsAlwaysOnTop() const {
537  return window_ && window_->GetProperty(aura::client::kAlwaysOnTopKey);
538}
539
540void NativeWidgetAura::Maximize() {
541  if (window_)
542    window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
543}
544
545void NativeWidgetAura::Minimize() {
546  if (window_)
547    window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
548}
549
550bool NativeWidgetAura::IsMaximized() const {
551  return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
552      ui::SHOW_STATE_MAXIMIZED;
553}
554
555bool NativeWidgetAura::IsMinimized() const {
556  return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
557      ui::SHOW_STATE_MINIMIZED;
558}
559
560void NativeWidgetAura::Restore() {
561  if (window_)
562    window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
563}
564
565void NativeWidgetAura::SetFullscreen(bool fullscreen) {
566  if (!window_ || IsFullscreen() == fullscreen)
567    return;  // Nothing to do.
568
569  // Save window state before entering full screen so that it could restored
570  // when exiting full screen.
571  if (fullscreen)
572    saved_window_state_ = window_->GetProperty(aura::client::kShowStateKey);
573
574  window_->SetProperty(
575      aura::client::kShowStateKey,
576      fullscreen ? ui::SHOW_STATE_FULLSCREEN : saved_window_state_);
577}
578
579bool NativeWidgetAura::IsFullscreen() const {
580  return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
581      ui::SHOW_STATE_FULLSCREEN;
582}
583
584void NativeWidgetAura::SetOpacity(unsigned char opacity) {
585  if (window_)
586    window_->layer()->SetOpacity(opacity / 255.0);
587}
588
589void NativeWidgetAura::SetUseDragFrame(bool use_drag_frame) {
590  NOTIMPLEMENTED();
591}
592
593void NativeWidgetAura::FlashFrame(bool flash) {
594  if (window_)
595    window_->SetProperty(aura::client::kDrawAttentionKey, flash);
596}
597
598void NativeWidgetAura::RunShellDrag(View* view,
599                                    const ui::OSExchangeData& data,
600                                    const gfx::Point& location,
601                                    int operation,
602                                    ui::DragDropTypes::DragEventSource source) {
603  if (window_)
604    views::RunShellDrag(window_, data, location, operation, source);
605}
606
607void NativeWidgetAura::SchedulePaintInRect(const gfx::Rect& rect) {
608  if (window_)
609    window_->SchedulePaintInRect(rect);
610}
611
612void NativeWidgetAura::SetCursor(gfx::NativeCursor cursor) {
613  cursor_ = cursor;
614  aura::client::CursorClient* cursor_client =
615      aura::client::GetCursorClient(window_->GetRootWindow());
616  if (cursor_client)
617    cursor_client->SetCursor(cursor);
618}
619
620bool NativeWidgetAura::IsMouseEventsEnabled() const {
621  if (!window_)
622    return false;
623  aura::client::CursorClient* cursor_client =
624      aura::client::GetCursorClient(window_->GetRootWindow());
625  return cursor_client ? cursor_client->IsMouseEventsEnabled() : true;
626}
627
628void NativeWidgetAura::ClearNativeFocus() {
629  aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
630  if (window_ && client && window_->Contains(client->GetFocusedWindow()))
631    client->ResetFocusWithinActiveWindow(window_);
632}
633
634gfx::Rect NativeWidgetAura::GetWorkAreaBoundsInScreen() const {
635  if (!window_)
636    return gfx::Rect();
637  return gfx::Screen::GetScreenFor(window_)->
638      GetDisplayNearestWindow(window_).work_area();
639}
640
641Widget::MoveLoopResult NativeWidgetAura::RunMoveLoop(
642    const gfx::Vector2d& drag_offset,
643    Widget::MoveLoopSource source,
644    Widget::MoveLoopEscapeBehavior escape_behavior) {
645  // |escape_behavior| is only needed on windows when running the native message
646  // loop.
647  if (window_ && window_->parent() &&
648      aura::client::GetWindowMoveClient(window_->parent())) {
649    SetCapture();
650    aura::client::WindowMoveSource window_move_source =
651        source == Widget::MOVE_LOOP_SOURCE_MOUSE ?
652        aura::client::WINDOW_MOVE_SOURCE_MOUSE :
653        aura::client::WINDOW_MOVE_SOURCE_TOUCH;
654    if (aura::client::GetWindowMoveClient(window_->parent())->RunMoveLoop(
655            window_, drag_offset, window_move_source) ==
656        aura::client::MOVE_SUCCESSFUL) {
657      return Widget::MOVE_LOOP_SUCCESSFUL;
658    }
659  }
660  return Widget::MOVE_LOOP_CANCELED;
661}
662
663void NativeWidgetAura::EndMoveLoop() {
664  if (window_ && window_->parent() &&
665      aura::client::GetWindowMoveClient(window_->parent())) {
666    aura::client::GetWindowMoveClient(window_->parent())->EndMoveLoop();
667  }
668}
669
670void NativeWidgetAura::SetVisibilityChangedAnimationsEnabled(bool value) {
671  if (window_)
672    window_->SetProperty(aura::client::kAnimationsDisabledKey, !value);
673}
674
675ui::NativeTheme* NativeWidgetAura::GetNativeTheme() const {
676#if !defined(OS_CHROMEOS)
677  return DesktopRootWindowHost::GetNativeTheme(window_);
678#else
679  return ui::NativeThemeAura::instance();
680#endif
681}
682
683void NativeWidgetAura::OnRootViewLayout() const {
684}
685
686////////////////////////////////////////////////////////////////////////////////
687// NativeWidgetAura, views::InputMethodDelegate implementation:
688
689void NativeWidgetAura::DispatchKeyEventPostIME(const ui::KeyEvent& key) {
690  FocusManager* focus_manager = GetWidget()->GetFocusManager();
691  delegate_->OnKeyEvent(const_cast<ui::KeyEvent*>(&key));
692  if (key.handled() || !focus_manager)
693    return;
694  focus_manager->OnKeyEvent(key);
695}
696
697////////////////////////////////////////////////////////////////////////////////
698// NativeWidgetAura, aura::WindowDelegate implementation:
699
700gfx::Size NativeWidgetAura::GetMinimumSize() const {
701  return delegate_->GetMinimumSize();
702}
703
704gfx::Size NativeWidgetAura::GetMaximumSize() const {
705  return delegate_->GetMaximumSize();
706}
707
708void NativeWidgetAura::OnBoundsChanged(const gfx::Rect& old_bounds,
709                                       const gfx::Rect& new_bounds) {
710  if (old_bounds.origin() != new_bounds.origin())
711    delegate_->OnNativeWidgetMove();
712  if (old_bounds.size() != new_bounds.size())
713    delegate_->OnNativeWidgetSizeChanged(new_bounds.size());
714}
715
716gfx::NativeCursor NativeWidgetAura::GetCursor(const gfx::Point& point) {
717  return cursor_;
718}
719
720int NativeWidgetAura::GetNonClientComponent(const gfx::Point& point) const {
721  return delegate_->GetNonClientComponent(point);
722}
723
724bool NativeWidgetAura::ShouldDescendIntoChildForEventHandling(
725      aura::Window* child,
726      const gfx::Point& location) {
727  views::WidgetDelegate* widget_delegate = GetWidget()->widget_delegate();
728  if (widget_delegate &&
729      !widget_delegate->ShouldDescendIntoChildForEventHandling(child, location))
730    return false;
731
732  // Don't descend into |child| if there is a view with a Layer that contains
733  // the point and is stacked above |child|s layer.
734  typedef std::vector<ui::Layer*> Layers;
735  const Layers& root_layers(delegate_->GetRootLayers());
736  if (root_layers.empty())
737    return true;
738
739  Layers::const_iterator child_layer_iter(
740      std::find(window_->layer()->children().begin(),
741                window_->layer()->children().end(), child->layer()));
742  if (child_layer_iter == window_->layer()->children().end())
743    return true;
744
745  for (std::vector<ui::Layer*>::const_reverse_iterator i = root_layers.rbegin();
746       i != root_layers.rend(); ++i) {
747    ui::Layer* layer = *i;
748    if (layer->visible() && layer->bounds().Contains(location)) {
749      Layers::const_iterator root_layer_iter(
750          std::find(window_->layer()->children().begin(),
751                    window_->layer()->children().end(), layer));
752      if (root_layer_iter > child_layer_iter)
753        return false;
754    }
755  }
756  return true;
757}
758
759bool NativeWidgetAura::CanFocus() {
760  return can_activate_;
761}
762
763void NativeWidgetAura::OnCaptureLost() {
764  delegate_->OnMouseCaptureLost();
765}
766
767void NativeWidgetAura::OnPaint(gfx::Canvas* canvas) {
768  delegate_->OnNativeWidgetPaint(canvas);
769}
770
771void NativeWidgetAura::OnDeviceScaleFactorChanged(float device_scale_factor) {
772  // Repainting with new scale factor will paint the content at the right scale.
773}
774
775void NativeWidgetAura::OnWindowDestroying() {
776  delegate_->OnNativeWidgetDestroying();
777
778  // If the aura::Window is destroyed, we can no longer show tooltips.
779  tooltip_manager_.reset();
780}
781
782void NativeWidgetAura::OnWindowDestroyed() {
783  window_ = NULL;
784  delegate_->OnNativeWidgetDestroyed();
785  if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
786    delete this;
787}
788
789void NativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible) {
790  delegate_->OnNativeWidgetVisibilityChanged(visible);
791}
792
793bool NativeWidgetAura::HasHitTestMask() const {
794  return delegate_->HasHitTestMask();
795}
796
797void NativeWidgetAura::GetHitTestMask(gfx::Path* mask) const {
798  DCHECK(mask);
799  delegate_->GetHitTestMask(mask);
800}
801
802void NativeWidgetAura::DidRecreateLayer(ui::Layer *old_layer,
803                                        ui::Layer *new_layer) {
804}
805
806////////////////////////////////////////////////////////////////////////////////
807// NativeWidgetAura, ui::EventHandler implementation:
808
809void NativeWidgetAura::OnKeyEvent(ui::KeyEvent* event) {
810  DCHECK(window_);
811  if (event->is_char()) {
812    // If a ui::InputMethod object is attached to the root window, character
813    // events are handled inside the object and are not passed to this function.
814    // If such object is not attached, character events might be sent (e.g. on
815    // Windows). In this case, we just skip these.
816    return;
817  }
818  // Renderer may send a key event back to us if the key event wasn't handled,
819  // and the window may be invisible by that time.
820  if (!window_->IsVisible())
821    return;
822  GetWidget()->GetInputMethod()->DispatchKeyEvent(*event);
823  event->SetHandled();
824}
825
826void NativeWidgetAura::OnMouseEvent(ui::MouseEvent* event) {
827  DCHECK(window_);
828  DCHECK(window_->IsVisible());
829  if (event->type() == ui::ET_MOUSEWHEEL) {
830    delegate_->OnMouseEvent(event);
831    if (event->handled())
832      return;
833  }
834
835  if (tooltip_manager_.get())
836    tooltip_manager_->UpdateTooltip();
837  TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget());
838  delegate_->OnMouseEvent(event);
839}
840
841void NativeWidgetAura::OnScrollEvent(ui::ScrollEvent* event) {
842  delegate_->OnScrollEvent(event);
843}
844
845void NativeWidgetAura::OnTouchEvent(ui::TouchEvent* event) {
846  DCHECK(window_);
847  DCHECK(window_->IsVisible());
848  delegate_->OnTouchEvent(event);
849}
850
851void NativeWidgetAura::OnGestureEvent(ui::GestureEvent* event) {
852  DCHECK(window_);
853  DCHECK(window_->IsVisible());
854  delegate_->OnGestureEvent(event);
855}
856
857////////////////////////////////////////////////////////////////////////////////
858// NativeWidgetAura, aura::client::ActivationDelegate implementation:
859
860bool NativeWidgetAura::ShouldActivate() const {
861  return can_activate_ && delegate_->CanActivate();
862}
863
864////////////////////////////////////////////////////////////////////////////////
865// NativeWidgetAura, aura::client::ActivationChangeObserver implementation:
866
867void NativeWidgetAura::OnWindowActivated(aura::Window* gained_active,
868                                         aura::Window* lost_active) {
869  DCHECK(window_ == gained_active || window_ == lost_active);
870  if (GetWidget()->GetFocusManager()) {
871    if (window_ == gained_active)
872      GetWidget()->GetFocusManager()->RestoreFocusedView();
873    else if (window_ == lost_active)
874      GetWidget()->GetFocusManager()->StoreFocusedView(true);
875  }
876  delegate_->OnNativeWidgetActivationChanged(window_ == gained_active);
877  if (IsVisible() && GetWidget()->non_client_view())
878    GetWidget()->non_client_view()->SchedulePaint();
879}
880
881////////////////////////////////////////////////////////////////////////////////
882// NativeWidgetAura, aura::client::FocusChangeObserver:
883
884void NativeWidgetAura::OnWindowFocused(aura::Window* gained_focus,
885                                       aura::Window* lost_focus) {
886  if (window_ == gained_focus) {
887    // In aura, it is possible for child native widgets to take input and focus,
888    // this differs from the behavior on windows.
889    if (GetWidget()->GetInputMethod())  // Null in tests.
890      GetWidget()->GetInputMethod()->OnFocus();
891    delegate_->OnNativeFocus(lost_focus);
892  } else if (window_ == lost_focus) {
893    // GetInputMethod() recreates the input method if it's previously been
894    // destroyed.  If we get called during destruction, the input method will be
895    // gone, and creating a new one and telling it that we lost the focus will
896    // trigger a DCHECK (the new input method doesn't think that we have the
897    // focus and doesn't expect a blur).  OnBlur() shouldn't be called during
898    // destruction unless WIDGET_OWNS_NATIVE_WIDGET is set (which is just the
899    // case in tests).
900    if (!destroying_) {
901      if (GetWidget()->GetInputMethod())
902        GetWidget()->GetInputMethod()->OnBlur();
903    } else {
904      DCHECK_EQ(ownership_, Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET);
905    }
906
907    aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
908    if (client)  // NULL during destruction of aura::Window.
909      delegate_->OnNativeBlur(client->GetFocusedWindow());
910  }
911}
912
913////////////////////////////////////////////////////////////////////////////////
914// NativeWidgetAura, aura::WindowDragDropDelegate implementation:
915
916void NativeWidgetAura::OnDragEntered(const ui::DropTargetEvent& event) {
917  DCHECK(drop_helper_.get() != NULL);
918  last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
919      event.location(), event.source_operations());
920}
921
922int NativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent& event) {
923  DCHECK(drop_helper_.get() != NULL);
924  last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
925      event.location(), event.source_operations());
926  return last_drop_operation_;
927}
928
929void NativeWidgetAura::OnDragExited() {
930  DCHECK(drop_helper_.get() != NULL);
931  drop_helper_->OnDragExit();
932}
933
934int NativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent& event) {
935  DCHECK(drop_helper_.get() != NULL);
936  return drop_helper_->OnDrop(event.data(), event.location(),
937      last_drop_operation_);
938}
939
940////////////////////////////////////////////////////////////////////////////////
941// NativeWidgetAura, NativeWidget implementation:
942
943ui::EventHandler* NativeWidgetAura::GetEventHandler() {
944  return this;
945}
946
947////////////////////////////////////////////////////////////////////////////////
948// NativeWidgetAura, protected:
949
950NativeWidgetAura::~NativeWidgetAura() {
951  destroying_ = true;
952  if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
953    delete delegate_;
954  else
955    CloseNow();
956}
957
958////////////////////////////////////////////////////////////////////////////////
959// NativeWidgetAura, private:
960
961void NativeWidgetAura::SetInitialFocus() {
962  // The window does not get keyboard messages unless we focus it.
963  if (!GetWidget()->SetInitialFocus())
964    window_->Focus();
965}
966
967////////////////////////////////////////////////////////////////////////////////
968// Widget, public:
969
970// static
971void Widget::NotifyLocaleChanged() {
972  // Deliberately not implemented.
973}
974
975namespace {
976void CloseWindow(aura::Window* window) {
977  if (window) {
978    Widget* widget = Widget::GetWidgetForNativeView(window);
979    if (widget && widget->is_secondary_widget())
980      // To avoid the delay in shutdown caused by using Close which may wait
981      // for animations, use CloseNow. Because this is only used on secondary
982      // widgets it seems relatively safe to skip the extra processing of
983      // Close.
984      widget->CloseNow();
985  }
986}
987#if defined(OS_WIN)
988BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
989  aura::Window* root_window =
990      DesktopRootWindowHostWin::GetContentWindowForHWND(hwnd);
991  CloseWindow(root_window);
992  return TRUE;
993}
994#endif
995}  // namespace
996
997// static
998void Widget::CloseAllSecondaryWidgets() {
999#if defined(OS_WIN)
1000  EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0);
1001#endif
1002
1003#if defined(USE_X11) && !defined(OS_CHROMEOS)
1004  std::vector<aura::Window*> open_windows =
1005      DesktopRootWindowHostX11::GetAllOpenWindows();
1006  std::for_each(open_windows.begin(), open_windows.end(), CloseWindow);
1007  DesktopRootWindowHostX11::CleanUpWindowList();
1008#endif
1009}
1010
1011bool Widget::ConvertRect(const Widget* source,
1012                         const Widget* target,
1013                         gfx::Rect* rect) {
1014  return false;
1015}
1016
1017namespace internal {
1018
1019////////////////////////////////////////////////////////////////////////////////
1020// internal::NativeWidgetPrivate, public:
1021
1022// static
1023NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget(
1024    internal::NativeWidgetDelegate* delegate) {
1025  return new NativeWidgetAura(delegate);
1026}
1027
1028// static
1029NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView(
1030    gfx::NativeView native_view) {
1031  // Cast must match type supplied to RegisterNativeWidgetForWindow().
1032  return reinterpret_cast<NativeWidgetPrivate*>(native_view->user_data());
1033}
1034
1035// static
1036NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
1037    gfx::NativeWindow native_window) {
1038  // Cast must match type supplied to RegisterNativeWidgetForWindow().
1039  return reinterpret_cast<NativeWidgetPrivate*>(native_window->user_data());
1040}
1041
1042// static
1043NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget(
1044    gfx::NativeView native_view) {
1045  aura::Window* window = native_view;
1046  NativeWidgetPrivate* top_level_native_widget = NULL;
1047  while (window) {
1048    NativeWidgetPrivate* native_widget = GetNativeWidgetForNativeView(window);
1049    if (native_widget)
1050      top_level_native_widget = native_widget;
1051    window = window->parent();
1052  }
1053  return top_level_native_widget;
1054}
1055
1056// static
1057void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view,
1058                                             Widget::Widgets* children) {
1059  {
1060    // Code expects widget for |native_view| to be added to |children|.
1061    NativeWidgetPrivate* native_widget = static_cast<NativeWidgetPrivate*>(
1062        GetNativeWidgetForNativeView(native_view));
1063    if (native_widget && native_widget->GetWidget())
1064      children->insert(native_widget->GetWidget());
1065  }
1066
1067  const aura::Window::Windows& child_windows = native_view->children();
1068  for (aura::Window::Windows::const_iterator i = child_windows.begin();
1069       i != child_windows.end(); ++i) {
1070    GetAllChildWidgets((*i), children);
1071  }
1072}
1073
1074// static
1075void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view,
1076                                             Widget::Widgets* owned) {
1077  const aura::Window::Windows& transient_children =
1078      native_view->transient_children();
1079  for (aura::Window::Windows::const_iterator i = transient_children.begin();
1080       i != transient_children.end(); ++i) {
1081    NativeWidgetPrivate* native_widget = static_cast<NativeWidgetPrivate*>(
1082        GetNativeWidgetForNativeView(*i));
1083    if (native_widget && native_widget->GetWidget())
1084      owned->insert(native_widget->GetWidget());
1085    GetAllOwnedWidgets((*i), owned);
1086  }
1087}
1088
1089// static
1090void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view,
1091                                             gfx::NativeView new_parent) {
1092  DCHECK(native_view != new_parent);
1093
1094  gfx::NativeView previous_parent = native_view->parent();
1095  if (previous_parent == new_parent)
1096    return;
1097
1098  Widget::Widgets widgets;
1099  GetAllChildWidgets(native_view, &widgets);
1100
1101  // First notify all the widgets that they are being disassociated
1102  // from their previous parent.
1103  for (Widget::Widgets::iterator it = widgets.begin();
1104      it != widgets.end(); ++it) {
1105    (*it)->NotifyNativeViewHierarchyWillChange();
1106  }
1107
1108  if (new_parent) {
1109    new_parent->AddChild(native_view);
1110  } else {
1111    // The following looks weird, but it's the equivalent of what aura has
1112    // always done. (The previous behaviour of aura::Window::SetParent() used
1113    // NULL as a special value that meant ask the WindowTreeClient where things
1114    // should go.)
1115    //
1116    // This probably isn't strictly correct, but its an invariant that a Window
1117    // in use will be attached to a RootWindow, so we can't just call
1118    // RemoveChild here. The only possible thing that could assign a RootWindow
1119    // in this case is the stacking client of the current RootWindow. This
1120    // matches our previous behaviour; the global stacking client would almost
1121    // always reattach the window to the same RootWindow.
1122    aura::Window* root_window = native_view->GetRootWindow();
1123    aura::client::ParentWindowWithContext(
1124        native_view, root_window, root_window->GetBoundsInScreen());
1125  }
1126
1127  // And now, notify them that they have a brand new parent.
1128  for (Widget::Widgets::iterator it = widgets.begin();
1129      it != widgets.end(); ++it) {
1130    (*it)->NotifyNativeViewHierarchyChanged();
1131  }
1132}
1133
1134// static
1135bool NativeWidgetPrivate::IsMouseButtonDown() {
1136  return aura::Env::GetInstance()->IsMouseButtonDown();
1137}
1138
1139// static
1140bool NativeWidgetPrivate::IsTouchDown() {
1141  return aura::Env::GetInstance()->is_touch_down();
1142}
1143
1144}  // namespace internal
1145}  // namespace views
1146