Home | History | Annotate | Download | only in desktop_aura
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/views/widget/desktop_aura/desktop_root_window_host_win.h"
      6 
      7 #include "base/win/metro.h"
      8 #include "third_party/skia/include/core/SkPath.h"
      9 #include "third_party/skia/include/core/SkRegion.h"
     10 #include "ui/aura/client/aura_constants.h"
     11 #include "ui/aura/client/cursor_client.h"
     12 #include "ui/aura/client/focus_client.h"
     13 #include "ui/aura/root_window.h"
     14 #include "ui/aura/window_property.h"
     15 #include "ui/base/cursor/cursor_loader_win.h"
     16 #include "ui/base/ime/input_method.h"
     17 #include "ui/base/ime/win/tsf_bridge.h"
     18 #include "ui/base/win/shell.h"
     19 #include "ui/compositor/compositor_constants.h"
     20 #include "ui/gfx/insets.h"
     21 #include "ui/gfx/native_widget_types.h"
     22 #include "ui/gfx/path.h"
     23 #include "ui/gfx/path_win.h"
     24 #include "ui/gfx/vector2d.h"
     25 #include "ui/gfx/win/dpi.h"
     26 #include "ui/native_theme/native_theme_aura.h"
     27 #include "ui/native_theme/native_theme_win.h"
     28 #include "ui/views/corewm/compound_event_filter.h"
     29 #include "ui/views/corewm/corewm_switches.h"
     30 #include "ui/views/corewm/input_method_event_filter.h"
     31 #include "ui/views/corewm/tooltip_win.h"
     32 #include "ui/views/corewm/window_animations.h"
     33 #include "ui/views/ime/input_method_bridge.h"
     34 #include "ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h"
     35 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h"
     36 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
     37 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
     38 #include "ui/views/widget/root_view.h"
     39 #include "ui/views/widget/widget_delegate.h"
     40 #include "ui/views/widget/widget_hwnd_utils.h"
     41 #include "ui/views/win/fullscreen_handler.h"
     42 #include "ui/views/win/hwnd_message_handler.h"
     43 #include "ui/views/window/native_frame_view.h"
     44 
     45 namespace views {
     46 
     47 namespace {
     48 
     49 gfx::Size GetExpandedWindowSize(DWORD window_style, gfx::Size size) {
     50   if (!(window_style & WS_EX_COMPOSITED) || !ui::win::IsAeroGlassEnabled())
     51     return size;
     52 
     53   // Some AMD drivers can't display windows that are less than 64x64 pixels,
     54   // so expand them to be at least that size. http://crbug.com/286609
     55   gfx::Size expanded(std::max(size.width(), 64), std::max(size.height(), 64));
     56   return expanded;
     57 }
     58 
     59 void InsetBottomRight(gfx::Rect* rect, gfx::Vector2d vector) {
     60   rect->Inset(0, 0, vector.x(), vector.y());
     61 }
     62 
     63 }  // namespace
     64 
     65 DEFINE_WINDOW_PROPERTY_KEY(aura::Window*, kContentWindowForRootWindow, NULL);
     66 
     67 // Identifies the DesktopRootWindowHostWin associated with the RootWindow.
     68 DEFINE_WINDOW_PROPERTY_KEY(DesktopRootWindowHostWin*, kDesktopRootWindowHostKey,
     69                            NULL);
     70 
     71 ////////////////////////////////////////////////////////////////////////////////
     72 // DesktopRootWindowHostWin, public:
     73 
     74 DesktopRootWindowHostWin::DesktopRootWindowHostWin(
     75     internal::NativeWidgetDelegate* native_widget_delegate,
     76     DesktopNativeWidgetAura* desktop_native_widget_aura)
     77     : root_window_(NULL),
     78       message_handler_(new HWNDMessageHandler(this)),
     79       native_widget_delegate_(native_widget_delegate),
     80       desktop_native_widget_aura_(desktop_native_widget_aura),
     81       content_window_(NULL),
     82       drag_drop_client_(NULL),
     83       should_animate_window_close_(false),
     84       pending_close_(false),
     85       has_non_client_view_(false),
     86       tooltip_(NULL),
     87       is_cursor_visible_(true) {
     88 }
     89 
     90 DesktopRootWindowHostWin::~DesktopRootWindowHostWin() {
     91   // WARNING: |content_window_| has been destroyed by the time we get here.
     92   desktop_native_widget_aura_->OnDesktopRootWindowHostDestroyed(
     93       root_window_);
     94 }
     95 
     96 // static
     97 aura::Window* DesktopRootWindowHostWin::GetContentWindowForHWND(HWND hwnd) {
     98   aura::RootWindow* root = aura::RootWindow::GetForAcceleratedWidget(hwnd);
     99   return root ? root->window()->GetProperty(kContentWindowForRootWindow) : NULL;
    100 }
    101 
    102 // static
    103 ui::NativeTheme* DesktopRootWindowHost::GetNativeTheme(aura::Window* window) {
    104   // Use NativeThemeWin for windows shown on the desktop, those not on the
    105   // desktop come from Ash and get NativeThemeAura.
    106   aura::WindowEventDispatcher* dispatcher =
    107       window ? window->GetDispatcher() : NULL;
    108   if (dispatcher) {
    109     HWND host_hwnd = dispatcher->host()->GetAcceleratedWidget();
    110     if (host_hwnd &&
    111         DesktopRootWindowHostWin::GetContentWindowForHWND(host_hwnd)) {
    112       return ui::NativeThemeWin::instance();
    113     }
    114   }
    115   return ui::NativeThemeAura::instance();
    116 }
    117 
    118 ////////////////////////////////////////////////////////////////////////////////
    119 // DesktopRootWindowHostWin, DesktopRootWindowHost implementation:
    120 
    121 void DesktopRootWindowHostWin::Init(
    122     aura::Window* content_window,
    123     const Widget::InitParams& params,
    124     aura::RootWindow::CreateParams* rw_create_params) {
    125   // TODO(beng): SetInitParams().
    126   content_window_ = content_window;
    127 
    128   aura::client::SetAnimationHost(content_window_, this);
    129 
    130   ConfigureWindowStyles(message_handler_.get(), params,
    131                         GetWidget()->widget_delegate(),
    132                         native_widget_delegate_);
    133 
    134   HWND parent_hwnd = NULL;
    135   if (params.parent && params.parent->GetDispatcher()) {
    136     parent_hwnd =
    137         params.parent->GetDispatcher()->host()->GetAcceleratedWidget();
    138   }
    139 
    140   message_handler_->set_remove_standard_frame(params.remove_standard_frame);
    141 
    142   has_non_client_view_ = Widget::RequiresNonClientView(params.type);
    143 
    144   if (params.type == Widget::InitParams::TYPE_MENU) {
    145     ::SetProp(GetAcceleratedWidget(),
    146               kForceSoftwareCompositor,
    147               reinterpret_cast<HANDLE>(true));
    148   }
    149 
    150   gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(params.bounds);
    151   message_handler_->Init(parent_hwnd, pixel_bounds);
    152 
    153   rw_create_params->host = this;
    154 }
    155 
    156 void DesktopRootWindowHostWin::OnRootWindowCreated(
    157     aura::RootWindow* root,
    158     const Widget::InitParams& params) {
    159   root_window_ = root;
    160 
    161   root_window_->window()->SetProperty(kContentWindowForRootWindow,
    162                                       content_window_);
    163   root_window_->window()->SetProperty(kDesktopRootWindowHostKey, this);
    164 
    165   should_animate_window_close_ =
    166       content_window_->type() != aura::client::WINDOW_TYPE_NORMAL &&
    167       !views::corewm::WindowAnimationsDisabled(content_window_);
    168 
    169 // TODO this is not invoked *after* Init(), but should be ok.
    170   SetWindowTransparency();
    171 }
    172 
    173 scoped_ptr<corewm::Tooltip> DesktopRootWindowHostWin::CreateTooltip() {
    174   DCHECK(!tooltip_);
    175   tooltip_ = new corewm::TooltipWin(GetAcceleratedWidget());
    176   return scoped_ptr<corewm::Tooltip>(tooltip_);
    177 }
    178 
    179 scoped_ptr<aura::client::DragDropClient>
    180 DesktopRootWindowHostWin::CreateDragDropClient(
    181     DesktopNativeCursorManager* cursor_manager) {
    182   drag_drop_client_ = new DesktopDragDropClientWin(root_window_->window(),
    183                                                    GetHWND());
    184   return scoped_ptr<aura::client::DragDropClient>(drag_drop_client_).Pass();
    185 }
    186 
    187 void DesktopRootWindowHostWin::Close() {
    188   // TODO(beng): Move this entire branch to DNWA so it can be shared with X11.
    189   if (should_animate_window_close_) {
    190     pending_close_ = true;
    191     const bool is_animating =
    192         content_window_->layer()->GetAnimator()->IsAnimatingProperty(
    193             ui::LayerAnimationElement::VISIBILITY);
    194     // Animation may not start for a number of reasons.
    195     if (!is_animating)
    196       message_handler_->Close();
    197     // else case, OnWindowHidingAnimationCompleted does the actual Close.
    198   } else {
    199     message_handler_->Close();
    200   }
    201 }
    202 
    203 void DesktopRootWindowHostWin::CloseNow() {
    204   message_handler_->CloseNow();
    205 }
    206 
    207 aura::RootWindowHost* DesktopRootWindowHostWin::AsRootWindowHost() {
    208   return this;
    209 }
    210 
    211 void DesktopRootWindowHostWin::ShowWindowWithState(
    212     ui::WindowShowState show_state) {
    213   message_handler_->ShowWindowWithState(show_state);
    214 }
    215 
    216 void DesktopRootWindowHostWin::ShowMaximizedWithBounds(
    217     const gfx::Rect& restored_bounds) {
    218   gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(restored_bounds);
    219   message_handler_->ShowMaximizedWithBounds(pixel_bounds);
    220 }
    221 
    222 bool DesktopRootWindowHostWin::IsVisible() const {
    223   return message_handler_->IsVisible();
    224 }
    225 
    226 void DesktopRootWindowHostWin::SetSize(const gfx::Size& size) {
    227   gfx::Size size_in_pixels = gfx::win::DIPToScreenSize(size);
    228   gfx::Size expanded = GetExpandedWindowSize(
    229       message_handler_->window_ex_style(), size_in_pixels);
    230   window_enlargement_ =
    231       gfx::Vector2d(expanded.width() - size_in_pixels.width(),
    232                     expanded.height() - size_in_pixels.height());
    233   message_handler_->SetSize(expanded);
    234 }
    235 
    236 void DesktopRootWindowHostWin::StackAtTop() {
    237   message_handler_->StackAtTop();
    238 }
    239 
    240 void DesktopRootWindowHostWin::CenterWindow(const gfx::Size& size) {
    241   gfx::Size size_in_pixels = gfx::win::DIPToScreenSize(size);
    242   gfx::Size expanded_size;
    243   expanded_size = GetExpandedWindowSize(message_handler_->window_ex_style(),
    244                                         size_in_pixels);
    245   window_enlargement_ =
    246       gfx::Vector2d(expanded_size.width() - size_in_pixels.width(),
    247                     expanded_size.height() - size_in_pixels.height());
    248   message_handler_->CenterWindow(expanded_size);
    249 }
    250 
    251 void DesktopRootWindowHostWin::GetWindowPlacement(
    252     gfx::Rect* bounds,
    253     ui::WindowShowState* show_state) const {
    254   message_handler_->GetWindowPlacement(bounds, show_state);
    255   InsetBottomRight(bounds, window_enlargement_);
    256   *bounds = gfx::win::ScreenToDIPRect(*bounds);
    257 }
    258 
    259 gfx::Rect DesktopRootWindowHostWin::GetWindowBoundsInScreen() const {
    260   gfx::Rect pixel_bounds = message_handler_->GetWindowBoundsInScreen();
    261   InsetBottomRight(&pixel_bounds, window_enlargement_);
    262   return gfx::win::ScreenToDIPRect(pixel_bounds);
    263 }
    264 
    265 gfx::Rect DesktopRootWindowHostWin::GetClientAreaBoundsInScreen() const {
    266   gfx::Rect pixel_bounds = message_handler_->GetClientAreaBoundsInScreen();
    267   InsetBottomRight(&pixel_bounds, window_enlargement_);
    268   return gfx::win::ScreenToDIPRect(pixel_bounds);
    269 }
    270 
    271 gfx::Rect DesktopRootWindowHostWin::GetRestoredBounds() const {
    272   gfx::Rect pixel_bounds = message_handler_->GetRestoredBounds();
    273   InsetBottomRight(&pixel_bounds, window_enlargement_);
    274   return gfx::win::ScreenToDIPRect(pixel_bounds);
    275 }
    276 
    277 gfx::Rect DesktopRootWindowHostWin::GetWorkAreaBoundsInScreen() const {
    278   MONITORINFO monitor_info;
    279   monitor_info.cbSize = sizeof(monitor_info);
    280   GetMonitorInfo(MonitorFromWindow(message_handler_->hwnd(),
    281                                    MONITOR_DEFAULTTONEAREST),
    282                  &monitor_info);
    283   gfx::Rect pixel_bounds = gfx::Rect(monitor_info.rcWork);
    284   return gfx::win::ScreenToDIPRect(pixel_bounds);
    285 }
    286 
    287 void DesktopRootWindowHostWin::SetShape(gfx::NativeRegion native_region) {
    288   if (native_region) {
    289     message_handler_->SetRegion(gfx::CreateHRGNFromSkRegion(*native_region));
    290   } else {
    291     message_handler_->SetRegion(NULL);
    292   }
    293 
    294   delete native_region;
    295 }
    296 
    297 void DesktopRootWindowHostWin::Activate() {
    298   message_handler_->Activate();
    299 }
    300 
    301 void DesktopRootWindowHostWin::Deactivate() {
    302   message_handler_->Deactivate();
    303 }
    304 
    305 bool DesktopRootWindowHostWin::IsActive() const {
    306   return message_handler_->IsActive();
    307 }
    308 
    309 void DesktopRootWindowHostWin::Maximize() {
    310   message_handler_->Maximize();
    311 }
    312 
    313 void DesktopRootWindowHostWin::Minimize() {
    314   message_handler_->Minimize();
    315 }
    316 
    317 void DesktopRootWindowHostWin::Restore() {
    318   message_handler_->Restore();
    319 }
    320 
    321 bool DesktopRootWindowHostWin::IsMaximized() const {
    322   return message_handler_->IsMaximized();
    323 }
    324 
    325 bool DesktopRootWindowHostWin::IsMinimized() const {
    326   return message_handler_->IsMinimized();
    327 }
    328 
    329 bool DesktopRootWindowHostWin::HasCapture() const {
    330   return message_handler_->HasCapture();
    331 }
    332 
    333 void DesktopRootWindowHostWin::SetAlwaysOnTop(bool always_on_top) {
    334   message_handler_->SetAlwaysOnTop(always_on_top);
    335 }
    336 
    337 bool DesktopRootWindowHostWin::IsAlwaysOnTop() const {
    338   return message_handler_->IsAlwaysOnTop();
    339 }
    340 
    341 bool DesktopRootWindowHostWin::SetWindowTitle(const string16& title) {
    342   return message_handler_->SetTitle(title);
    343 }
    344 
    345 void DesktopRootWindowHostWin::ClearNativeFocus() {
    346   message_handler_->ClearNativeFocus();
    347 }
    348 
    349 Widget::MoveLoopResult DesktopRootWindowHostWin::RunMoveLoop(
    350     const gfx::Vector2d& drag_offset,
    351     Widget::MoveLoopSource source,
    352     Widget::MoveLoopEscapeBehavior escape_behavior) {
    353   const bool hide_on_escape =
    354       escape_behavior == Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_HIDE;
    355   return message_handler_->RunMoveLoop(drag_offset, hide_on_escape) ?
    356       Widget::MOVE_LOOP_SUCCESSFUL : Widget::MOVE_LOOP_CANCELED;
    357 }
    358 
    359 void DesktopRootWindowHostWin::EndMoveLoop() {
    360   message_handler_->EndMoveLoop();
    361 }
    362 
    363 void DesktopRootWindowHostWin::SetVisibilityChangedAnimationsEnabled(
    364     bool value) {
    365   message_handler_->SetVisibilityChangedAnimationsEnabled(value);
    366   content_window_->SetProperty(aura::client::kAnimationsDisabledKey, !value);
    367 }
    368 
    369 bool DesktopRootWindowHostWin::ShouldUseNativeFrame() {
    370   return ui::win::IsAeroGlassEnabled();
    371 }
    372 
    373 void DesktopRootWindowHostWin::FrameTypeChanged() {
    374   message_handler_->FrameTypeChanged();
    375   SetWindowTransparency();
    376 }
    377 
    378 NonClientFrameView* DesktopRootWindowHostWin::CreateNonClientFrameView() {
    379   return GetWidget()->ShouldUseNativeFrame() ?
    380       new NativeFrameView(GetWidget()) : NULL;
    381 }
    382 
    383 void DesktopRootWindowHostWin::SetFullscreen(bool fullscreen) {
    384   message_handler_->fullscreen_handler()->SetFullscreen(fullscreen);
    385   // TODO(sky): workaround for ScopedFullscreenVisibility showing window
    386   // directly. Instead of this should listen for visibility changes and then
    387   // update window.
    388   if (message_handler_->IsVisible() && !content_window_->TargetVisibility())
    389     content_window_->Show();
    390   SetWindowTransparency();
    391 }
    392 
    393 bool DesktopRootWindowHostWin::IsFullscreen() const {
    394   return message_handler_->fullscreen_handler()->fullscreen();
    395 }
    396 
    397 void DesktopRootWindowHostWin::SetOpacity(unsigned char opacity) {
    398   message_handler_->SetOpacity(static_cast<BYTE>(opacity));
    399   content_window_->layer()->SetOpacity(opacity / 255.0);
    400 }
    401 
    402 void DesktopRootWindowHostWin::SetWindowIcons(
    403     const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
    404   message_handler_->SetWindowIcons(window_icon, app_icon);
    405 }
    406 
    407 void DesktopRootWindowHostWin::InitModalType(ui::ModalType modal_type) {
    408   message_handler_->InitModalType(modal_type);
    409 }
    410 
    411 void DesktopRootWindowHostWin::FlashFrame(bool flash_frame) {
    412   message_handler_->FlashFrame(flash_frame);
    413 }
    414 
    415 void DesktopRootWindowHostWin::OnRootViewLayout() const {
    416 }
    417 
    418 void DesktopRootWindowHostWin::OnNativeWidgetFocus() {
    419   // HWNDMessageHandler will perform the proper updating on its own.
    420 }
    421 
    422 void DesktopRootWindowHostWin::OnNativeWidgetBlur() {
    423 }
    424 
    425 bool DesktopRootWindowHostWin::IsAnimatingClosed() const {
    426   return pending_close_;
    427 }
    428 
    429 ////////////////////////////////////////////////////////////////////////////////
    430 // DesktopRootWindowHostWin, RootWindowHost implementation:
    431 
    432 aura::RootWindow* DesktopRootWindowHostWin::GetRootWindow() {
    433   return root_window_;
    434 }
    435 
    436 gfx::AcceleratedWidget DesktopRootWindowHostWin::GetAcceleratedWidget() {
    437   return message_handler_->hwnd();
    438 }
    439 
    440 void DesktopRootWindowHostWin::Show() {
    441   message_handler_->Show();
    442 }
    443 
    444 void DesktopRootWindowHostWin::Hide() {
    445   if (!pending_close_)
    446     message_handler_->Hide();
    447 }
    448 
    449 void DesktopRootWindowHostWin::ToggleFullScreen() {
    450   SetWindowTransparency();
    451 }
    452 
    453 // GetBounds and SetBounds work in pixel coordinates, whereas other get/set
    454 // methods work in DIP.
    455 
    456 gfx::Rect DesktopRootWindowHostWin::GetBounds() const {
    457   gfx::Rect bounds(message_handler_->GetClientAreaBounds());
    458   // If the window bounds were expanded we need to return the original bounds
    459   // To achieve this we do the reverse of the expansion, i.e. add the
    460   // window_expansion_top_left_delta_ to the origin and subtract the
    461   // window_expansion_bottom_right_delta_ from the width and height.
    462   gfx::Rect without_expansion(
    463       bounds.x() + window_expansion_top_left_delta_.x(),
    464       bounds.y() + window_expansion_top_left_delta_.y(),
    465       bounds.width() - window_expansion_bottom_right_delta_.x() -
    466           window_enlargement_.x(),
    467       bounds.height() - window_expansion_bottom_right_delta_.y() -
    468           window_enlargement_.y());
    469   return without_expansion;
    470 }
    471 
    472 void DesktopRootWindowHostWin::SetBounds(const gfx::Rect& bounds) {
    473   // If the window bounds have to be expanded we need to subtract the
    474   // window_expansion_top_left_delta_ from the origin and add the
    475   // window_expansion_bottom_right_delta_ to the width and height
    476   gfx::Size old_hwnd_size(message_handler_->GetClientAreaBounds().size());
    477   gfx::Size old_content_size = GetBounds().size();
    478 
    479   gfx::Rect expanded(
    480       bounds.x() - window_expansion_top_left_delta_.x(),
    481       bounds.y() - window_expansion_top_left_delta_.y(),
    482       bounds.width() + window_expansion_bottom_right_delta_.x(),
    483       bounds.height() + window_expansion_bottom_right_delta_.y());
    484 
    485   gfx::Rect new_expanded(
    486       expanded.origin(),
    487       GetExpandedWindowSize(message_handler_->window_ex_style(),
    488                             expanded.size()));
    489   window_enlargement_ =
    490       gfx::Vector2d(new_expanded.width() - expanded.width(),
    491                     new_expanded.height() - expanded.height());
    492   message_handler_->SetBounds(new_expanded);
    493 
    494   // The client area size may have changed even though the window bounds have
    495   // not, if the window bounds were expanded to 64 pixels both times.
    496   if (old_hwnd_size == new_expanded.size() && old_content_size != bounds.size())
    497     HandleClientSizeChanged(new_expanded.size());
    498 }
    499 
    500 gfx::Insets DesktopRootWindowHostWin::GetInsets() const {
    501   return gfx::Insets();
    502 }
    503 
    504 void DesktopRootWindowHostWin::SetInsets(const gfx::Insets& insets) {
    505 }
    506 
    507 gfx::Point DesktopRootWindowHostWin::GetLocationOnNativeScreen() const {
    508   return GetBounds().origin();
    509 }
    510 
    511 void DesktopRootWindowHostWin::SetCapture() {
    512   message_handler_->SetCapture();
    513 }
    514 
    515 void DesktopRootWindowHostWin::ReleaseCapture() {
    516   message_handler_->ReleaseCapture();
    517 }
    518 
    519 void DesktopRootWindowHostWin::SetCursor(gfx::NativeCursor cursor) {
    520   ui::CursorLoaderWin cursor_loader;
    521   cursor_loader.SetPlatformCursor(&cursor);
    522 
    523   message_handler_->SetCursor(cursor.platform());
    524 }
    525 
    526 bool DesktopRootWindowHostWin::QueryMouseLocation(gfx::Point* location_return) {
    527   aura::client::CursorClient* cursor_client =
    528       aura::client::GetCursorClient(root_window_->window());
    529   if (cursor_client && !cursor_client->IsMouseEventsEnabled()) {
    530     *location_return = gfx::Point(0, 0);
    531     return false;
    532   }
    533   POINT pt = {0};
    534   ::GetCursorPos(&pt);
    535   *location_return =
    536       gfx::Point(static_cast<int>(pt.x), static_cast<int>(pt.y));
    537   return true;
    538 }
    539 
    540 bool DesktopRootWindowHostWin::ConfineCursorToRootWindow() {
    541   RECT window_rect = root_window_->window()->GetBoundsInScreen().ToRECT();
    542   ::ClipCursor(&window_rect);
    543   return true;
    544 }
    545 
    546 void DesktopRootWindowHostWin::UnConfineCursor() {
    547   ::ClipCursor(NULL);
    548 }
    549 
    550 void DesktopRootWindowHostWin::OnCursorVisibilityChanged(bool show) {
    551   if (is_cursor_visible_ == show)
    552     return;
    553   is_cursor_visible_ = show;
    554   ::ShowCursor(!!show);
    555 }
    556 
    557 void DesktopRootWindowHostWin::MoveCursorTo(const gfx::Point& location) {
    558   POINT cursor_location = location.ToPOINT();
    559   ::ClientToScreen(GetHWND(), &cursor_location);
    560   ::SetCursorPos(cursor_location.x, cursor_location.y);
    561 }
    562 
    563 void DesktopRootWindowHostWin::PostNativeEvent(
    564     const base::NativeEvent& native_event) {
    565 }
    566 
    567 void DesktopRootWindowHostWin::OnDeviceScaleFactorChanged(
    568     float device_scale_factor) {
    569 }
    570 
    571 void DesktopRootWindowHostWin::PrepareForShutdown() {
    572 }
    573 
    574 ////////////////////////////////////////////////////////////////////////////////
    575 // DesktopRootWindowHostWin, aura::AnimationHost implementation:
    576 
    577 void DesktopRootWindowHostWin::SetHostTransitionOffsets(
    578     const gfx::Vector2d& top_left_delta,
    579     const gfx::Vector2d& bottom_right_delta) {
    580   gfx::Rect bounds_without_expansion = GetBounds();
    581   window_expansion_top_left_delta_ = top_left_delta;
    582   window_expansion_bottom_right_delta_ = bottom_right_delta;
    583   SetBounds(bounds_without_expansion);
    584 }
    585 
    586 void DesktopRootWindowHostWin::OnWindowHidingAnimationCompleted() {
    587   if (pending_close_)
    588     message_handler_->Close();
    589 }
    590 
    591 ////////////////////////////////////////////////////////////////////////////////
    592 // DesktopRootWindowHostWin, HWNDMessageHandlerDelegate implementation:
    593 
    594 bool DesktopRootWindowHostWin::IsWidgetWindow() const {
    595   return has_non_client_view_;
    596 }
    597 
    598 bool DesktopRootWindowHostWin::IsUsingCustomFrame() const {
    599   return !GetWidget()->ShouldUseNativeFrame();
    600 }
    601 
    602 void DesktopRootWindowHostWin::SchedulePaint() {
    603   GetWidget()->GetRootView()->SchedulePaint();
    604 }
    605 
    606 void DesktopRootWindowHostWin::EnableInactiveRendering() {
    607   native_widget_delegate_->EnableInactiveRendering();
    608 }
    609 
    610 bool DesktopRootWindowHostWin::IsInactiveRenderingDisabled() {
    611   return native_widget_delegate_->IsInactiveRenderingDisabled();
    612 }
    613 
    614 bool DesktopRootWindowHostWin::CanResize() const {
    615   return GetWidget()->widget_delegate()->CanResize();
    616 }
    617 
    618 bool DesktopRootWindowHostWin::CanMaximize() const {
    619   return GetWidget()->widget_delegate()->CanMaximize();
    620 }
    621 
    622 bool DesktopRootWindowHostWin::CanActivate() const {
    623   if (IsModalWindowActive())
    624     return true;
    625   return native_widget_delegate_->CanActivate();
    626 }
    627 
    628 bool DesktopRootWindowHostWin::WidgetSizeIsClientSize() const {
    629   const Widget* widget = GetWidget()->GetTopLevelWidget();
    630   return IsMaximized() || (widget && widget->ShouldUseNativeFrame());
    631 }
    632 
    633 bool DesktopRootWindowHostWin::CanSaveFocus() const {
    634   return GetWidget()->is_top_level();
    635 }
    636 
    637 void DesktopRootWindowHostWin::SaveFocusOnDeactivate() {
    638   GetWidget()->GetFocusManager()->StoreFocusedView(true);
    639 }
    640 
    641 void DesktopRootWindowHostWin::RestoreFocusOnActivate() {
    642   RestoreFocusOnEnable();
    643 }
    644 
    645 void DesktopRootWindowHostWin::RestoreFocusOnEnable() {
    646   GetWidget()->GetFocusManager()->RestoreFocusedView();
    647 }
    648 
    649 bool DesktopRootWindowHostWin::IsModal() const {
    650   return native_widget_delegate_->IsModal();
    651 }
    652 
    653 int DesktopRootWindowHostWin::GetInitialShowState() const {
    654   return SW_SHOWNORMAL;
    655 }
    656 
    657 bool DesktopRootWindowHostWin::WillProcessWorkAreaChange() const {
    658   return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
    659 }
    660 
    661 int DesktopRootWindowHostWin::GetNonClientComponent(
    662     const gfx::Point& point) const {
    663   gfx::Point dip_position = gfx::win::ScreenToDIPPoint(point);
    664   return native_widget_delegate_->GetNonClientComponent(dip_position);
    665 }
    666 
    667 void DesktopRootWindowHostWin::GetWindowMask(const gfx::Size& size,
    668                                              gfx::Path* path) {
    669   if (GetWidget()->non_client_view()) {
    670     GetWidget()->non_client_view()->GetWindowMask(size, path);
    671   } else if (!window_enlargement_.IsZero()) {
    672     gfx::Rect bounds(WidgetSizeIsClientSize()
    673                          ? message_handler_->GetClientAreaBoundsInScreen()
    674                          : message_handler_->GetWindowBoundsInScreen());
    675     InsetBottomRight(&bounds, window_enlargement_);
    676     path->addRect(SkRect::MakeXYWH(0, 0, bounds.width(), bounds.height()));
    677   }
    678 }
    679 
    680 bool DesktopRootWindowHostWin::GetClientAreaInsets(gfx::Insets* insets) const {
    681   return false;
    682 }
    683 
    684 void DesktopRootWindowHostWin::GetMinMaxSize(gfx::Size* min_size,
    685                                              gfx::Size* max_size) const {
    686   *min_size = native_widget_delegate_->GetMinimumSize();
    687   *max_size = native_widget_delegate_->GetMaximumSize();
    688 }
    689 
    690 gfx::Size DesktopRootWindowHostWin::GetRootViewSize() const {
    691   return GetWidget()->GetRootView()->size();
    692 }
    693 
    694 void DesktopRootWindowHostWin::ResetWindowControls() {
    695   GetWidget()->non_client_view()->ResetWindowControls();
    696 }
    697 
    698 void DesktopRootWindowHostWin::PaintLayeredWindow(gfx::Canvas* canvas) {
    699   GetWidget()->GetRootView()->Paint(canvas);
    700 }
    701 
    702 gfx::NativeViewAccessible DesktopRootWindowHostWin::GetNativeViewAccessible() {
    703   return GetWidget()->GetRootView()->GetNativeViewAccessible();
    704 }
    705 
    706 InputMethod* DesktopRootWindowHostWin::GetInputMethod() {
    707   return GetWidget()->GetInputMethodDirect();
    708 }
    709 
    710 bool DesktopRootWindowHostWin::ShouldHandleSystemCommands() const {
    711   return GetWidget()->widget_delegate()->ShouldHandleSystemCommands();
    712 }
    713 
    714 void DesktopRootWindowHostWin::HandleAppDeactivated() {
    715   native_widget_delegate_->EnableInactiveRendering();
    716 }
    717 
    718 void DesktopRootWindowHostWin::HandleActivationChanged(bool active) {
    719   // This can be invoked from HWNDMessageHandler::Init(), at which point we're
    720   // not in a good state and need to ignore it.
    721   if (!delegate_)
    722     return;
    723 
    724   if (active)
    725     delegate_->OnHostActivated();
    726   desktop_native_widget_aura_->HandleActivationChanged(active);
    727 }
    728 
    729 bool DesktopRootWindowHostWin::HandleAppCommand(short command) {
    730   // We treat APPCOMMAND ids as an extension of our command namespace, and just
    731   // let the delegate figure out what to do...
    732   return GetWidget()->widget_delegate() &&
    733       GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
    734 }
    735 
    736 void DesktopRootWindowHostWin::HandleCancelMode() {
    737   delegate_->OnHostCancelMode();
    738 }
    739 
    740 void DesktopRootWindowHostWin::HandleCaptureLost() {
    741   delegate_->OnHostLostWindowCapture();
    742   native_widget_delegate_->OnMouseCaptureLost();
    743 }
    744 
    745 void DesktopRootWindowHostWin::HandleClose() {
    746   GetWidget()->Close();
    747 }
    748 
    749 bool DesktopRootWindowHostWin::HandleCommand(int command) {
    750   return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
    751 }
    752 
    753 void DesktopRootWindowHostWin::HandleAccelerator(
    754     const ui::Accelerator& accelerator) {
    755   GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator);
    756 }
    757 
    758 void DesktopRootWindowHostWin::HandleCreate() {
    759   // TODO(beng): moar
    760   NOTIMPLEMENTED();
    761 
    762   native_widget_delegate_->OnNativeWidgetCreated(true);
    763 
    764   // 1. Window property association
    765   // 2. MouseWheel.
    766 }
    767 
    768 void DesktopRootWindowHostWin::HandleDestroying() {
    769   drag_drop_client_->OnNativeWidgetDestroying(GetHWND());
    770   native_widget_delegate_->OnNativeWidgetDestroying();
    771 }
    772 
    773 void DesktopRootWindowHostWin::HandleDestroyed() {
    774   desktop_native_widget_aura_->OnHostClosed();
    775 }
    776 
    777 bool DesktopRootWindowHostWin::HandleInitialFocus() {
    778   return GetWidget()->SetInitialFocus();
    779 }
    780 
    781 void DesktopRootWindowHostWin::HandleDisplayChange() {
    782   GetWidget()->widget_delegate()->OnDisplayChanged();
    783 }
    784 
    785 void DesktopRootWindowHostWin::HandleBeginWMSizeMove() {
    786   native_widget_delegate_->OnNativeWidgetBeginUserBoundsChange();
    787 }
    788 
    789 void DesktopRootWindowHostWin::HandleEndWMSizeMove() {
    790   native_widget_delegate_->OnNativeWidgetEndUserBoundsChange();
    791 }
    792 
    793 void DesktopRootWindowHostWin::HandleMove() {
    794   native_widget_delegate_->OnNativeWidgetMove();
    795   if (delegate_)
    796     delegate_->OnHostMoved(GetBounds().origin());
    797 }
    798 
    799 void DesktopRootWindowHostWin::HandleWorkAreaChanged() {
    800   GetWidget()->widget_delegate()->OnWorkAreaChanged();
    801 }
    802 
    803 void DesktopRootWindowHostWin::HandleVisibilityChanging(bool visible) {
    804   native_widget_delegate_->OnNativeWidgetVisibilityChanging(visible);
    805 }
    806 
    807 void DesktopRootWindowHostWin::HandleVisibilityChanged(bool visible) {
    808   native_widget_delegate_->OnNativeWidgetVisibilityChanged(visible);
    809 }
    810 
    811 void DesktopRootWindowHostWin::HandleClientSizeChanged(
    812     const gfx::Size& new_size) {
    813   if (delegate_)
    814     delegate_->OnHostResized(new_size);
    815 }
    816 
    817 void DesktopRootWindowHostWin::HandleFrameChanged() {
    818   SetWindowTransparency();
    819   // Replace the frame and layout the contents.
    820   GetWidget()->non_client_view()->UpdateFrame();
    821 }
    822 
    823 void DesktopRootWindowHostWin::HandleNativeFocus(HWND last_focused_window) {
    824   // TODO(beng): inform the native_widget_delegate_.
    825   InputMethod* input_method = GetInputMethod();
    826   if (input_method)
    827     input_method->OnFocus();
    828 }
    829 
    830 void DesktopRootWindowHostWin::HandleNativeBlur(HWND focused_window) {
    831   // TODO(beng): inform the native_widget_delegate_.
    832   InputMethod* input_method = GetInputMethod();
    833   if (input_method)
    834     input_method->OnBlur();
    835 }
    836 
    837 bool DesktopRootWindowHostWin::HandleMouseEvent(const ui::MouseEvent& event) {
    838   if (base::win::IsTSFAwareRequired() && event.IsAnyButton())
    839     ui::TSFBridge::GetInstance()->CancelComposition();
    840   return delegate_->OnHostMouseEvent(const_cast<ui::MouseEvent*>(&event));
    841 }
    842 
    843 bool DesktopRootWindowHostWin::HandleKeyEvent(const ui::KeyEvent& event) {
    844   return false;
    845 }
    846 
    847 bool DesktopRootWindowHostWin::HandleUntranslatedKeyEvent(
    848     const ui::KeyEvent& event) {
    849   ui::KeyEvent duplicate_event(event);
    850   return delegate_->OnHostKeyEvent(&duplicate_event);
    851 }
    852 
    853 void DesktopRootWindowHostWin::HandleTouchEvent(
    854     const ui::TouchEvent& event) {
    855   // HWNDMessageHandler asynchronously processes touch events. Because of this
    856   // it's possible for the aura::RootWindow to have been destroyed by the time
    857   // we attempt to process them.
    858   if (!GetWidget()->GetNativeView())
    859     return;
    860 
    861   // Currently we assume the window that has capture gets touch events too.
    862   aura::RootWindow* root =
    863       aura::RootWindow::GetForAcceleratedWidget(GetCapture());
    864   if (root) {
    865     DesktopRootWindowHostWin* target =
    866         root->window()->GetProperty(kDesktopRootWindowHostKey);
    867     if (target && target->HasCapture() && target != this) {
    868       POINT target_location(event.location().ToPOINT());
    869       ClientToScreen(GetHWND(), &target_location);
    870       ScreenToClient(target->GetHWND(), &target_location);
    871       ui::TouchEvent target_event(event, static_cast<View*>(NULL),
    872                                   static_cast<View*>(NULL));
    873       target_event.set_location(gfx::Point(target_location));
    874       target_event.set_root_location(target_event.location());
    875       target->delegate_->OnHostTouchEvent(&target_event);
    876       return;
    877     }
    878   }
    879   delegate_->OnHostTouchEvent(
    880       const_cast<ui::TouchEvent*>(&event));
    881 }
    882 
    883 bool DesktopRootWindowHostWin::HandleIMEMessage(UINT message,
    884                                                 WPARAM w_param,
    885                                                 LPARAM l_param,
    886                                                 LRESULT* result) {
    887   MSG msg = {};
    888   msg.hwnd = GetHWND();
    889   msg.message = message;
    890   msg.wParam = w_param;
    891   msg.lParam = l_param;
    892   return desktop_native_widget_aura_->input_method_event_filter()->
    893       input_method()->OnUntranslatedIMEMessage(msg, result);
    894 }
    895 
    896 void DesktopRootWindowHostWin::HandleInputLanguageChange(
    897     DWORD character_set,
    898     HKL input_language_id) {
    899   desktop_native_widget_aura_->input_method_event_filter()->
    900       input_method()->OnInputLocaleChanged();
    901 }
    902 
    903 bool DesktopRootWindowHostWin::HandlePaintAccelerated(
    904     const gfx::Rect& invalid_rect) {
    905   return native_widget_delegate_->OnNativeWidgetPaintAccelerated(invalid_rect);
    906 }
    907 
    908 void DesktopRootWindowHostWin::HandlePaint(gfx::Canvas* canvas) {
    909   delegate_->OnHostPaint(gfx::Rect());
    910 }
    911 
    912 bool DesktopRootWindowHostWin::HandleTooltipNotify(int w_param,
    913                                                    NMHDR* l_param,
    914                                                    LRESULT* l_result) {
    915   return tooltip_ && tooltip_->HandleNotify(w_param, l_param, l_result);
    916 }
    917 
    918 void DesktopRootWindowHostWin::HandleTooltipMouseMove(UINT message,
    919                                                       WPARAM w_param,
    920                                                       LPARAM l_param) {
    921   // TooltipWin implementation doesn't need this.
    922   // TODO(sky): remove from HWNDMessageHandler once non-aura path nuked.
    923 }
    924 
    925 bool DesktopRootWindowHostWin::PreHandleMSG(UINT message,
    926                                             WPARAM w_param,
    927                                             LPARAM l_param,
    928                                             LRESULT* result) {
    929   return false;
    930 }
    931 
    932 void DesktopRootWindowHostWin::PostHandleMSG(UINT message,
    933                                              WPARAM w_param,
    934                                              LPARAM l_param) {
    935 }
    936 
    937 bool DesktopRootWindowHostWin::HandleScrollEvent(
    938     const ui::ScrollEvent& event) {
    939   return delegate_->OnHostScrollEvent(const_cast<ui::ScrollEvent*>(&event));
    940 }
    941 
    942 ////////////////////////////////////////////////////////////////////////////////
    943 // DesktopRootWindowHostWin, private:
    944 
    945 Widget* DesktopRootWindowHostWin::GetWidget() {
    946   return native_widget_delegate_->AsWidget();
    947 }
    948 
    949 const Widget* DesktopRootWindowHostWin::GetWidget() const {
    950   return native_widget_delegate_->AsWidget();
    951 }
    952 
    953 HWND DesktopRootWindowHostWin::GetHWND() const {
    954   return message_handler_->hwnd();
    955 }
    956 
    957 void DesktopRootWindowHostWin::SetWindowTransparency() {
    958   bool transparent = ShouldUseNativeFrame() && !IsFullscreen();
    959   root_window_->compositor()->SetHostHasTransparentBackground(transparent);
    960   root_window_->window()->SetTransparent(transparent);
    961   content_window_->SetTransparent(transparent);
    962 }
    963 
    964 bool DesktopRootWindowHostWin::IsModalWindowActive() const {
    965   // This function can get called during window creation which occurs before
    966   // root_window_ has been created.
    967   if (!root_window_)
    968     return false;
    969 
    970   aura::Window::Windows::const_iterator index;
    971   for (index = root_window_->window()->children().begin();
    972        index != root_window_->window()->children().end();
    973        ++index) {
    974     if ((*index)->GetProperty(aura::client::kModalKey) !=
    975         ui:: MODAL_TYPE_NONE && (*index)->TargetVisibility())
    976       return true;
    977   }
    978   return false;
    979 }
    980 
    981 ////////////////////////////////////////////////////////////////////////////////
    982 // DesktopRootWindowHost, public:
    983 
    984 // static
    985 DesktopRootWindowHost* DesktopRootWindowHost::Create(
    986     internal::NativeWidgetDelegate* native_widget_delegate,
    987     DesktopNativeWidgetAura* desktop_native_widget_aura) {
    988   return new DesktopRootWindowHostWin(native_widget_delegate,
    989                                       desktop_native_widget_aura);
    990 }
    991 
    992 }  // namespace views
    993