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