fc2bda6311aa5a4f12320aa4e32dddff7e74c827
[platform/framework/web/crosswalk.git] / src / ui / views / widget / desktop_aura / desktop_window_tree_host_win.cc
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 ui::win::IsAeroGlassEnabled();
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 ////////////////////////////////////////////////////////////////////////////////
431 // DesktopWindowTreeHostWin, WindowTreeHost implementation:
432
433 ui::EventSource* DesktopWindowTreeHostWin::GetEventSource() {
434   return this;
435 }
436
437 gfx::AcceleratedWidget DesktopWindowTreeHostWin::GetAcceleratedWidget() {
438   return message_handler_->hwnd();
439 }
440
441 void DesktopWindowTreeHostWin::Show() {
442   message_handler_->Show();
443 }
444
445 void DesktopWindowTreeHostWin::Hide() {
446   if (!pending_close_)
447     message_handler_->Hide();
448 }
449
450 // GetBounds and SetBounds work in pixel coordinates, whereas other get/set
451 // methods work in DIP.
452
453 gfx::Rect DesktopWindowTreeHostWin::GetBounds() const {
454   gfx::Rect bounds(message_handler_->GetClientAreaBounds());
455   // If the window bounds were expanded we need to return the original bounds
456   // To achieve this we do the reverse of the expansion, i.e. add the
457   // window_expansion_top_left_delta_ to the origin and subtract the
458   // window_expansion_bottom_right_delta_ from the width and height.
459   gfx::Rect without_expansion(
460       bounds.x() + window_expansion_top_left_delta_.x(),
461       bounds.y() + window_expansion_top_left_delta_.y(),
462       bounds.width() - window_expansion_bottom_right_delta_.x() -
463           window_enlargement_.x(),
464       bounds.height() - window_expansion_bottom_right_delta_.y() -
465           window_enlargement_.y());
466   return without_expansion;
467 }
468
469 void DesktopWindowTreeHostWin::SetBounds(const gfx::Rect& bounds) {
470   // If the window bounds have to be expanded we need to subtract the
471   // window_expansion_top_left_delta_ from the origin and add the
472   // window_expansion_bottom_right_delta_ to the width and height
473   gfx::Size old_hwnd_size(message_handler_->GetClientAreaBounds().size());
474   gfx::Size old_content_size = GetBounds().size();
475
476   gfx::Rect expanded(
477       bounds.x() - window_expansion_top_left_delta_.x(),
478       bounds.y() - window_expansion_top_left_delta_.y(),
479       bounds.width() + window_expansion_bottom_right_delta_.x(),
480       bounds.height() + window_expansion_bottom_right_delta_.y());
481
482   gfx::Rect new_expanded(
483       expanded.origin(),
484       GetExpandedWindowSize(message_handler_->window_ex_style(),
485                             expanded.size()));
486   window_enlargement_ =
487       gfx::Vector2d(new_expanded.width() - expanded.width(),
488                     new_expanded.height() - expanded.height());
489   message_handler_->SetBounds(new_expanded, old_content_size != bounds.size());
490 }
491
492 gfx::Point DesktopWindowTreeHostWin::GetLocationOnNativeScreen() const {
493   return GetBounds().origin();
494 }
495
496 void DesktopWindowTreeHostWin::SetCapture() {
497   message_handler_->SetCapture();
498 }
499
500 void DesktopWindowTreeHostWin::ReleaseCapture() {
501   message_handler_->ReleaseCapture();
502 }
503
504 void DesktopWindowTreeHostWin::PostNativeEvent(
505     const base::NativeEvent& native_event) {
506 }
507
508 void DesktopWindowTreeHostWin::OnDeviceScaleFactorChanged(
509     float device_scale_factor) {
510 }
511
512 void DesktopWindowTreeHostWin::SetCursorNative(gfx::NativeCursor cursor) {
513   ui::CursorLoaderWin cursor_loader;
514   cursor_loader.SetPlatformCursor(&cursor);
515
516   message_handler_->SetCursor(cursor.platform());
517 }
518
519 void DesktopWindowTreeHostWin::OnCursorVisibilityChangedNative(bool show) {
520   if (is_cursor_visible_ == show)
521     return;
522   is_cursor_visible_ = show;
523   ::ShowCursor(!!show);
524 }
525
526 void DesktopWindowTreeHostWin::MoveCursorToNative(const gfx::Point& location) {
527   POINT cursor_location = location.ToPOINT();
528   ::ClientToScreen(GetHWND(), &cursor_location);
529   ::SetCursorPos(cursor_location.x, cursor_location.y);
530 }
531
532 ////////////////////////////////////////////////////////////////////////////////
533 // DesktopWindowTreeHostWin, ui::EventSource implementation:
534
535 ui::EventProcessor* DesktopWindowTreeHostWin::GetEventProcessor() {
536   return dispatcher();
537 }
538
539 ////////////////////////////////////////////////////////////////////////////////
540 // DesktopWindowTreeHostWin, aura::AnimationHost implementation:
541
542 void DesktopWindowTreeHostWin::SetHostTransitionOffsets(
543     const gfx::Vector2d& top_left_delta,
544     const gfx::Vector2d& bottom_right_delta) {
545   gfx::Rect bounds_without_expansion = GetBounds();
546   window_expansion_top_left_delta_ = top_left_delta;
547   window_expansion_bottom_right_delta_ = bottom_right_delta;
548   SetBounds(bounds_without_expansion);
549 }
550
551 void DesktopWindowTreeHostWin::OnWindowHidingAnimationCompleted() {
552   if (pending_close_)
553     message_handler_->Close();
554 }
555
556 ////////////////////////////////////////////////////////////////////////////////
557 // DesktopWindowTreeHostWin, HWNDMessageHandlerDelegate implementation:
558
559 bool DesktopWindowTreeHostWin::IsWidgetWindow() const {
560   return has_non_client_view_;
561 }
562
563 bool DesktopWindowTreeHostWin::IsUsingCustomFrame() const {
564   return !GetWidget()->ShouldUseNativeFrame();
565 }
566
567 void DesktopWindowTreeHostWin::SchedulePaint() {
568   GetWidget()->GetRootView()->SchedulePaint();
569 }
570
571 void DesktopWindowTreeHostWin::EnableInactiveRendering() {
572   native_widget_delegate_->EnableInactiveRendering();
573 }
574
575 bool DesktopWindowTreeHostWin::IsInactiveRenderingDisabled() {
576   return native_widget_delegate_->IsInactiveRenderingDisabled();
577 }
578
579 bool DesktopWindowTreeHostWin::CanResize() const {
580   return GetWidget()->widget_delegate()->CanResize();
581 }
582
583 bool DesktopWindowTreeHostWin::CanMaximize() const {
584   return GetWidget()->widget_delegate()->CanMaximize();
585 }
586
587 bool DesktopWindowTreeHostWin::CanActivate() const {
588   if (IsModalWindowActive())
589     return true;
590   return native_widget_delegate_->CanActivate();
591 }
592
593 bool DesktopWindowTreeHostWin::WidgetSizeIsClientSize() const {
594   const Widget* widget = GetWidget()->GetTopLevelWidget();
595   return IsMaximized() || (widget && widget->ShouldUseNativeFrame());
596 }
597
598 bool DesktopWindowTreeHostWin::IsModal() const {
599   return native_widget_delegate_->IsModal();
600 }
601
602 int DesktopWindowTreeHostWin::GetInitialShowState() const {
603   return CanActivate() ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
604 }
605
606 bool DesktopWindowTreeHostWin::WillProcessWorkAreaChange() const {
607   return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
608 }
609
610 int DesktopWindowTreeHostWin::GetNonClientComponent(
611     const gfx::Point& point) const {
612   gfx::Point dip_position = gfx::win::ScreenToDIPPoint(point);
613   return native_widget_delegate_->GetNonClientComponent(dip_position);
614 }
615
616 void DesktopWindowTreeHostWin::GetWindowMask(const gfx::Size& size,
617                                              gfx::Path* path) {
618   if (GetWidget()->non_client_view()) {
619     GetWidget()->non_client_view()->GetWindowMask(size, path);
620   } else if (!window_enlargement_.IsZero()) {
621     gfx::Rect bounds(WidgetSizeIsClientSize()
622                          ? message_handler_->GetClientAreaBoundsInScreen()
623                          : message_handler_->GetWindowBoundsInScreen());
624     InsetBottomRight(&bounds, window_enlargement_);
625     path->addRect(SkRect::MakeXYWH(0, 0, bounds.width(), bounds.height()));
626   }
627 }
628
629 bool DesktopWindowTreeHostWin::GetClientAreaInsets(gfx::Insets* insets) const {
630   return false;
631 }
632
633 void DesktopWindowTreeHostWin::GetMinMaxSize(gfx::Size* min_size,
634                                              gfx::Size* max_size) const {
635   *min_size = native_widget_delegate_->GetMinimumSize();
636   *max_size = native_widget_delegate_->GetMaximumSize();
637 }
638
639 gfx::Size DesktopWindowTreeHostWin::GetRootViewSize() const {
640   return GetWidget()->GetRootView()->size();
641 }
642
643 void DesktopWindowTreeHostWin::ResetWindowControls() {
644   GetWidget()->non_client_view()->ResetWindowControls();
645 }
646
647 void DesktopWindowTreeHostWin::PaintLayeredWindow(gfx::Canvas* canvas) {
648   GetWidget()->GetRootView()->Paint(canvas, views::CullSet());
649 }
650
651 gfx::NativeViewAccessible DesktopWindowTreeHostWin::GetNativeViewAccessible() {
652   return GetWidget()->GetRootView()->GetNativeViewAccessible();
653 }
654
655 InputMethod* DesktopWindowTreeHostWin::GetInputMethod() {
656   return GetWidget()->GetInputMethodDirect();
657 }
658
659 bool DesktopWindowTreeHostWin::ShouldHandleSystemCommands() const {
660   return GetWidget()->widget_delegate()->ShouldHandleSystemCommands();
661 }
662
663 void DesktopWindowTreeHostWin::HandleAppDeactivated() {
664   native_widget_delegate_->EnableInactiveRendering();
665 }
666
667 void DesktopWindowTreeHostWin::HandleActivationChanged(bool active) {
668   // This can be invoked from HWNDMessageHandler::Init(), at which point we're
669   // not in a good state and need to ignore it.
670   // TODO(beng): Do we need this still now the host owns the dispatcher?
671   if (!dispatcher())
672     return;
673
674   if (active)
675     OnHostActivated();
676   desktop_native_widget_aura_->HandleActivationChanged(active);
677 }
678
679 bool DesktopWindowTreeHostWin::HandleAppCommand(short command) {
680   // We treat APPCOMMAND ids as an extension of our command namespace, and just
681   // let the delegate figure out what to do...
682   return GetWidget()->widget_delegate() &&
683       GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
684 }
685
686 void DesktopWindowTreeHostWin::HandleCancelMode() {
687   dispatcher()->DispatchCancelModeEvent();
688 }
689
690 void DesktopWindowTreeHostWin::HandleCaptureLost() {
691   OnHostLostWindowCapture();
692   native_widget_delegate_->OnMouseCaptureLost();
693 }
694
695 void DesktopWindowTreeHostWin::HandleClose() {
696   GetWidget()->Close();
697 }
698
699 bool DesktopWindowTreeHostWin::HandleCommand(int command) {
700   return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
701 }
702
703 void DesktopWindowTreeHostWin::HandleAccelerator(
704     const ui::Accelerator& accelerator) {
705   GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator);
706 }
707
708 void DesktopWindowTreeHostWin::HandleCreate() {
709   native_widget_delegate_->OnNativeWidgetCreated(true);
710 }
711
712 void DesktopWindowTreeHostWin::HandleDestroying() {
713   drag_drop_client_->OnNativeWidgetDestroying(GetHWND());
714   native_widget_delegate_->OnNativeWidgetDestroying();
715
716   // Destroy the compositor before destroying the HWND since shutdown
717   // may try to swap to the window.
718   DestroyCompositor();
719 }
720
721 void DesktopWindowTreeHostWin::HandleDestroyed() {
722   desktop_native_widget_aura_->OnHostClosed();
723 }
724
725 bool DesktopWindowTreeHostWin::HandleInitialFocus(
726     ui::WindowShowState show_state) {
727   return GetWidget()->SetInitialFocus(show_state);
728 }
729
730 void DesktopWindowTreeHostWin::HandleDisplayChange() {
731   GetWidget()->widget_delegate()->OnDisplayChanged();
732 }
733
734 void DesktopWindowTreeHostWin::HandleBeginWMSizeMove() {
735   native_widget_delegate_->OnNativeWidgetBeginUserBoundsChange();
736 }
737
738 void DesktopWindowTreeHostWin::HandleEndWMSizeMove() {
739   native_widget_delegate_->OnNativeWidgetEndUserBoundsChange();
740 }
741
742 void DesktopWindowTreeHostWin::HandleMove() {
743   native_widget_delegate_->OnNativeWidgetMove();
744   OnHostMoved(GetBounds().origin());
745 }
746
747 void DesktopWindowTreeHostWin::HandleWorkAreaChanged() {
748   GetWidget()->widget_delegate()->OnWorkAreaChanged();
749 }
750
751 void DesktopWindowTreeHostWin::HandleVisibilityChanging(bool visible) {
752   native_widget_delegate_->OnNativeWidgetVisibilityChanging(visible);
753 }
754
755 void DesktopWindowTreeHostWin::HandleVisibilityChanged(bool visible) {
756   native_widget_delegate_->OnNativeWidgetVisibilityChanged(visible);
757 }
758
759 void DesktopWindowTreeHostWin::HandleClientSizeChanged(
760     const gfx::Size& new_size) {
761   if (dispatcher())
762     OnHostResized(new_size);
763 }
764
765 void DesktopWindowTreeHostWin::HandleFrameChanged() {
766   SetWindowTransparency();
767   // Replace the frame and layout the contents.
768   GetWidget()->non_client_view()->UpdateFrame();
769 }
770
771 void DesktopWindowTreeHostWin::HandleNativeFocus(HWND last_focused_window) {
772   // TODO(beng): inform the native_widget_delegate_.
773   InputMethod* input_method = GetInputMethod();
774   if (input_method)
775     input_method->OnFocus();
776 }
777
778 void DesktopWindowTreeHostWin::HandleNativeBlur(HWND focused_window) {
779   // TODO(beng): inform the native_widget_delegate_.
780   InputMethod* input_method = GetInputMethod();
781   if (input_method)
782     input_method->OnBlur();
783 }
784
785 bool DesktopWindowTreeHostWin::HandleMouseEvent(const ui::MouseEvent& event) {
786   SendEventToProcessor(const_cast<ui::MouseEvent*>(&event));
787   return event.handled();
788 }
789
790 bool DesktopWindowTreeHostWin::HandleKeyEvent(const ui::KeyEvent& event) {
791   return false;
792 }
793
794 bool DesktopWindowTreeHostWin::HandleUntranslatedKeyEvent(
795     const ui::KeyEvent& event) {
796   ui::KeyEvent duplicate_event(event);
797   SendEventToProcessor(&duplicate_event);
798   return duplicate_event.handled();
799 }
800
801 void DesktopWindowTreeHostWin::HandleTouchEvent(
802     const ui::TouchEvent& event) {
803   // HWNDMessageHandler asynchronously processes touch events. Because of this
804   // it's possible for the aura::WindowEventDispatcher to have been destroyed
805   // by the time we attempt to process them.
806   if (!GetWidget()->GetNativeView())
807     return;
808
809   // Currently we assume the window that has capture gets touch events too.
810   aura::WindowTreeHost* host =
811       aura::WindowTreeHost::GetForAcceleratedWidget(GetCapture());
812   if (host) {
813     DesktopWindowTreeHostWin* target =
814         host->window()->GetProperty(kDesktopWindowTreeHostKey);
815     if (target && target->HasCapture() && target != this) {
816       POINT target_location(event.location().ToPOINT());
817       ClientToScreen(GetHWND(), &target_location);
818       ScreenToClient(target->GetHWND(), &target_location);
819       ui::TouchEvent target_event(event, static_cast<View*>(NULL),
820                                   static_cast<View*>(NULL));
821       target_event.set_location(gfx::Point(target_location));
822       target_event.set_root_location(target_event.location());
823       target->SendEventToProcessor(&target_event);
824       return;
825     }
826   }
827   SendEventToProcessor(const_cast<ui::TouchEvent*>(&event));
828 }
829
830 bool DesktopWindowTreeHostWin::HandleIMEMessage(UINT message,
831                                                 WPARAM w_param,
832                                                 LPARAM l_param,
833                                                 LRESULT* result) {
834   MSG msg = {};
835   msg.hwnd = GetHWND();
836   msg.message = message;
837   msg.wParam = w_param;
838   msg.lParam = l_param;
839   return desktop_native_widget_aura_->input_method_event_filter()->
840       input_method()->OnUntranslatedIMEMessage(msg, result);
841 }
842
843 void DesktopWindowTreeHostWin::HandleInputLanguageChange(
844     DWORD character_set,
845     HKL input_language_id) {
846   desktop_native_widget_aura_->input_method_event_filter()->
847       input_method()->OnInputLocaleChanged();
848 }
849
850 bool DesktopWindowTreeHostWin::HandlePaintAccelerated(
851     const gfx::Rect& invalid_rect) {
852   return native_widget_delegate_->OnNativeWidgetPaintAccelerated(invalid_rect);
853 }
854
855 void DesktopWindowTreeHostWin::HandlePaint(gfx::Canvas* canvas) {
856   // It appears possible to get WM_PAINT after WM_DESTROY.
857   if (compositor())
858     compositor()->ScheduleRedrawRect(gfx::Rect());
859 }
860
861 bool DesktopWindowTreeHostWin::HandleTooltipNotify(int w_param,
862                                                    NMHDR* l_param,
863                                                    LRESULT* l_result) {
864   return tooltip_ && tooltip_->HandleNotify(w_param, l_param, l_result);
865 }
866
867 void DesktopWindowTreeHostWin::HandleTooltipMouseMove(UINT message,
868                                                       WPARAM w_param,
869                                                       LPARAM l_param) {
870   // TooltipWin implementation doesn't need this.
871   // TODO(sky): remove from HWNDMessageHandler once non-aura path nuked.
872 }
873
874 void DesktopWindowTreeHostWin::HandleMenuLoop(bool in_menu_loop) {
875   if (in_menu_loop) {
876     tooltip_disabler_.reset(
877         new aura::client::ScopedTooltipDisabler(window()));
878   } else {
879     tooltip_disabler_.reset();
880   }
881 }
882
883 bool DesktopWindowTreeHostWin::PreHandleMSG(UINT message,
884                                             WPARAM w_param,
885                                             LPARAM l_param,
886                                             LRESULT* result) {
887   return false;
888 }
889
890 void DesktopWindowTreeHostWin::PostHandleMSG(UINT message,
891                                              WPARAM w_param,
892                                              LPARAM l_param) {
893 }
894
895 bool DesktopWindowTreeHostWin::HandleScrollEvent(
896     const ui::ScrollEvent& event) {
897   SendEventToProcessor(const_cast<ui::ScrollEvent*>(&event));
898   return event.handled();
899 }
900
901 void DesktopWindowTreeHostWin::HandleWindowSizeChanging() {
902   if (compositor())
903     compositor()->FinishAllRendering();
904 }
905
906 ////////////////////////////////////////////////////////////////////////////////
907 // DesktopWindowTreeHostWin, private:
908
909 Widget* DesktopWindowTreeHostWin::GetWidget() {
910   return native_widget_delegate_->AsWidget();
911 }
912
913 const Widget* DesktopWindowTreeHostWin::GetWidget() const {
914   return native_widget_delegate_->AsWidget();
915 }
916
917 HWND DesktopWindowTreeHostWin::GetHWND() const {
918   return message_handler_->hwnd();
919 }
920
921 void DesktopWindowTreeHostWin::SetWindowTransparency() {
922   bool transparent = ShouldUseNativeFrame() && !IsFullscreen();
923   compositor()->SetHostHasTransparentBackground(transparent);
924   window()->SetTransparent(transparent);
925   content_window_->SetTransparent(transparent);
926 }
927
928 bool DesktopWindowTreeHostWin::IsModalWindowActive() const {
929   // This function can get called during window creation which occurs before
930   // dispatcher() has been created.
931   if (!dispatcher())
932     return false;
933
934   aura::Window::Windows::const_iterator index;
935   for (index = window()->children().begin();
936        index != window()->children().end();
937        ++index) {
938     if ((*index)->GetProperty(aura::client::kModalKey) !=
939         ui:: MODAL_TYPE_NONE && (*index)->TargetVisibility())
940       return true;
941   }
942   return false;
943 }
944
945 ////////////////////////////////////////////////////////////////////////////////
946 // DesktopWindowTreeHost, public:
947
948 // static
949 DesktopWindowTreeHost* DesktopWindowTreeHost::Create(
950     internal::NativeWidgetDelegate* native_widget_delegate,
951     DesktopNativeWidgetAura* desktop_native_widget_aura) {
952   return new DesktopWindowTreeHostWin(native_widget_delegate,
953                                       desktop_native_widget_aura);
954 }
955
956 }  // namespace views