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