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