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