• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetExpandedWindowSize(DWORD window_style,gfx::Size size)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 
InsetBottomRight(gfx::Rect * rect,gfx::Vector2d vector)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 
DesktopWindowTreeHostWin(internal::NativeWidgetDelegate * native_widget_delegate,DesktopNativeWidgetAura * desktop_native_widget_aura)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 
~DesktopWindowTreeHostWin()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
GetContentWindowForHWND(HWND hwnd)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
GetNativeTheme(aura::Window * window)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 
Init(aura::Window * content_window,const Widget::InitParams & params)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 
OnNativeWidgetCreated(const Widget::InitParams & params)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 
CreateTooltip()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>
CreateDragDropClient(DesktopNativeCursorManager * cursor_manager)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 
Close()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 
CloseNow()197 void DesktopWindowTreeHostWin::CloseNow() {
198   message_handler_->CloseNow();
199 }
200 
AsWindowTreeHost()201 aura::WindowTreeHost* DesktopWindowTreeHostWin::AsWindowTreeHost() {
202   return this;
203 }
204 
ShowWindowWithState(ui::WindowShowState show_state)205 void DesktopWindowTreeHostWin::ShowWindowWithState(
206     ui::WindowShowState show_state) {
207   message_handler_->ShowWindowWithState(show_state);
208 }
209 
ShowMaximizedWithBounds(const gfx::Rect & restored_bounds)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 
IsVisible() const216 bool DesktopWindowTreeHostWin::IsVisible() const {
217   return message_handler_->IsVisible();
218 }
219 
SetSize(const gfx::Size & size)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 
StackAtTop()230 void DesktopWindowTreeHostWin::StackAtTop() {
231   message_handler_->StackAtTop();
232 }
233 
CenterWindow(const gfx::Size & size)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 
GetWindowPlacement(gfx::Rect * bounds,ui::WindowShowState * show_state) const245 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 
GetWindowBoundsInScreen() const253 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 
GetClientAreaBoundsInScreen() const259 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 
GetRestoredBounds() const265 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 
GetWorkAreaBoundsInScreen() const271 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 
SetShape(gfx::NativeRegion native_region)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 
Activate()291 void DesktopWindowTreeHostWin::Activate() {
292   message_handler_->Activate();
293 }
294 
Deactivate()295 void DesktopWindowTreeHostWin::Deactivate() {
296   message_handler_->Deactivate();
297 }
298 
IsActive() const299 bool DesktopWindowTreeHostWin::IsActive() const {
300   return message_handler_->IsActive();
301 }
302 
Maximize()303 void DesktopWindowTreeHostWin::Maximize() {
304   message_handler_->Maximize();
305 }
306 
Minimize()307 void DesktopWindowTreeHostWin::Minimize() {
308   message_handler_->Minimize();
309 }
310 
Restore()311 void DesktopWindowTreeHostWin::Restore() {
312   message_handler_->Restore();
313 }
314 
IsMaximized() const315 bool DesktopWindowTreeHostWin::IsMaximized() const {
316   return message_handler_->IsMaximized();
317 }
318 
IsMinimized() const319 bool DesktopWindowTreeHostWin::IsMinimized() const {
320   return message_handler_->IsMinimized();
321 }
322 
HasCapture() const323 bool DesktopWindowTreeHostWin::HasCapture() const {
324   return message_handler_->HasCapture();
325 }
326 
SetAlwaysOnTop(bool always_on_top)327 void DesktopWindowTreeHostWin::SetAlwaysOnTop(bool always_on_top) {
328   message_handler_->SetAlwaysOnTop(always_on_top);
329 }
330 
IsAlwaysOnTop() const331 bool DesktopWindowTreeHostWin::IsAlwaysOnTop() const {
332   return message_handler_->IsAlwaysOnTop();
333 }
334 
SetVisibleOnAllWorkspaces(bool always_visible)335 void DesktopWindowTreeHostWin::SetVisibleOnAllWorkspaces(bool always_visible) {
336   // Windows does not have the concept of workspaces.
337 }
338 
SetWindowTitle(const base::string16 & title)339 bool DesktopWindowTreeHostWin::SetWindowTitle(const base::string16& title) {
340   return message_handler_->SetTitle(title);
341 }
342 
ClearNativeFocus()343 void DesktopWindowTreeHostWin::ClearNativeFocus() {
344   message_handler_->ClearNativeFocus();
345 }
346 
RunMoveLoop(const gfx::Vector2d & drag_offset,Widget::MoveLoopSource source,Widget::MoveLoopEscapeBehavior escape_behavior)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 
EndMoveLoop()357 void DesktopWindowTreeHostWin::EndMoveLoop() {
358   message_handler_->EndMoveLoop();
359 }
360 
SetVisibilityChangedAnimationsEnabled(bool value)361 void DesktopWindowTreeHostWin::SetVisibilityChangedAnimationsEnabled(
362     bool value) {
363   message_handler_->SetVisibilityChangedAnimationsEnabled(value);
364   content_window_->SetProperty(aura::client::kAnimationsDisabledKey, !value);
365 }
366 
ShouldUseNativeFrame() const367 bool DesktopWindowTreeHostWin::ShouldUseNativeFrame() const {
368   return IsTranslucentWindowOpacitySupported();
369 }
370 
ShouldWindowContentsBeTransparent() const371 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 
FrameTypeChanged()379 void DesktopWindowTreeHostWin::FrameTypeChanged() {
380   message_handler_->FrameTypeChanged();
381   SetWindowTransparency();
382 }
383 
SetFullscreen(bool fullscreen)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 
IsFullscreen() const394 bool DesktopWindowTreeHostWin::IsFullscreen() const {
395   return message_handler_->fullscreen_handler()->fullscreen();
396 }
397 
SetOpacity(unsigned char opacity)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 
SetWindowIcons(const gfx::ImageSkia & window_icon,const gfx::ImageSkia & app_icon)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 
InitModalType(ui::ModalType modal_type)408 void DesktopWindowTreeHostWin::InitModalType(ui::ModalType modal_type) {
409   message_handler_->InitModalType(modal_type);
410 }
411 
FlashFrame(bool flash_frame)412 void DesktopWindowTreeHostWin::FlashFrame(bool flash_frame) {
413   message_handler_->FlashFrame(flash_frame);
414 }
415 
OnRootViewLayout() const416 void DesktopWindowTreeHostWin::OnRootViewLayout() const {
417 }
418 
OnNativeWidgetFocus()419 void DesktopWindowTreeHostWin::OnNativeWidgetFocus() {
420   // HWNDMessageHandler will perform the proper updating on its own.
421 }
422 
OnNativeWidgetBlur()423 void DesktopWindowTreeHostWin::OnNativeWidgetBlur() {
424 }
425 
IsAnimatingClosed() const426 bool DesktopWindowTreeHostWin::IsAnimatingClosed() const {
427   return pending_close_;
428 }
429 
IsTranslucentWindowOpacitySupported() const430 bool DesktopWindowTreeHostWin::IsTranslucentWindowOpacitySupported() const {
431   return ui::win::IsAeroGlassEnabled();
432 }
433 
434 ////////////////////////////////////////////////////////////////////////////////
435 // DesktopWindowTreeHostWin, WindowTreeHost implementation:
436 
GetEventSource()437 ui::EventSource* DesktopWindowTreeHostWin::GetEventSource() {
438   return this;
439 }
440 
GetAcceleratedWidget()441 gfx::AcceleratedWidget DesktopWindowTreeHostWin::GetAcceleratedWidget() {
442   return message_handler_->hwnd();
443 }
444 
Show()445 void DesktopWindowTreeHostWin::Show() {
446   message_handler_->Show();
447 }
448 
Hide()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 
GetBounds() const457 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 
SetBounds(const gfx::Rect & bounds)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 
GetLocationOnNativeScreen() const496 gfx::Point DesktopWindowTreeHostWin::GetLocationOnNativeScreen() const {
497   return GetBounds().origin();
498 }
499 
SetCapture()500 void DesktopWindowTreeHostWin::SetCapture() {
501   message_handler_->SetCapture();
502 }
503 
ReleaseCapture()504 void DesktopWindowTreeHostWin::ReleaseCapture() {
505   message_handler_->ReleaseCapture();
506 }
507 
PostNativeEvent(const base::NativeEvent & native_event)508 void DesktopWindowTreeHostWin::PostNativeEvent(
509     const base::NativeEvent& native_event) {
510 }
511 
OnDeviceScaleFactorChanged(float device_scale_factor)512 void DesktopWindowTreeHostWin::OnDeviceScaleFactorChanged(
513     float device_scale_factor) {
514 }
515 
SetCursorNative(gfx::NativeCursor cursor)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 
OnCursorVisibilityChangedNative(bool show)523 void DesktopWindowTreeHostWin::OnCursorVisibilityChangedNative(bool show) {
524   if (is_cursor_visible_ == show)
525     return;
526   is_cursor_visible_ = show;
527   ::ShowCursor(!!show);
528 }
529 
MoveCursorToNative(const gfx::Point & location)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 
GetEventProcessor()539 ui::EventProcessor* DesktopWindowTreeHostWin::GetEventProcessor() {
540   return dispatcher();
541 }
542 
543 ////////////////////////////////////////////////////////////////////////////////
544 // DesktopWindowTreeHostWin, aura::AnimationHost implementation:
545 
SetHostTransitionOffsets(const gfx::Vector2d & top_left_delta,const gfx::Vector2d & bottom_right_delta)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 
OnWindowHidingAnimationCompleted()555 void DesktopWindowTreeHostWin::OnWindowHidingAnimationCompleted() {
556   if (pending_close_)
557     message_handler_->Close();
558 }
559 
560 ////////////////////////////////////////////////////////////////////////////////
561 // DesktopWindowTreeHostWin, HWNDMessageHandlerDelegate implementation:
562 
IsWidgetWindow() const563 bool DesktopWindowTreeHostWin::IsWidgetWindow() const {
564   return has_non_client_view_;
565 }
566 
IsUsingCustomFrame() const567 bool DesktopWindowTreeHostWin::IsUsingCustomFrame() const {
568   return !GetWidget()->ShouldUseNativeFrame();
569 }
570 
SchedulePaint()571 void DesktopWindowTreeHostWin::SchedulePaint() {
572   GetWidget()->GetRootView()->SchedulePaint();
573 }
574 
EnableInactiveRendering()575 void DesktopWindowTreeHostWin::EnableInactiveRendering() {
576   native_widget_delegate_->EnableInactiveRendering();
577 }
578 
IsInactiveRenderingDisabled()579 bool DesktopWindowTreeHostWin::IsInactiveRenderingDisabled() {
580   return native_widget_delegate_->IsInactiveRenderingDisabled();
581 }
582 
CanResize() const583 bool DesktopWindowTreeHostWin::CanResize() const {
584   return GetWidget()->widget_delegate()->CanResize();
585 }
586 
CanMaximize() const587 bool DesktopWindowTreeHostWin::CanMaximize() const {
588   return GetWidget()->widget_delegate()->CanMaximize();
589 }
590 
CanActivate() const591 bool DesktopWindowTreeHostWin::CanActivate() const {
592   if (IsModalWindowActive())
593     return true;
594   return native_widget_delegate_->CanActivate();
595 }
596 
WidgetSizeIsClientSize() const597 bool DesktopWindowTreeHostWin::WidgetSizeIsClientSize() const {
598   const Widget* widget = GetWidget()->GetTopLevelWidget();
599   return IsMaximized() || (widget && widget->ShouldUseNativeFrame());
600 }
601 
IsModal() const602 bool DesktopWindowTreeHostWin::IsModal() const {
603   return native_widget_delegate_->IsModal();
604 }
605 
GetInitialShowState() const606 int DesktopWindowTreeHostWin::GetInitialShowState() const {
607   return CanActivate() ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
608 }
609 
WillProcessWorkAreaChange() const610 bool DesktopWindowTreeHostWin::WillProcessWorkAreaChange() const {
611   return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
612 }
613 
GetNonClientComponent(const gfx::Point & point) const614 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 
GetWindowMask(const gfx::Size & size,gfx::Path * path)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 
GetClientAreaInsets(gfx::Insets * insets) const633 bool DesktopWindowTreeHostWin::GetClientAreaInsets(gfx::Insets* insets) const {
634   return false;
635 }
636 
GetMinMaxSize(gfx::Size * min_size,gfx::Size * max_size) const637 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 
GetRootViewSize() const643 gfx::Size DesktopWindowTreeHostWin::GetRootViewSize() const {
644   return GetWidget()->GetRootView()->size();
645 }
646 
ResetWindowControls()647 void DesktopWindowTreeHostWin::ResetWindowControls() {
648   GetWidget()->non_client_view()->ResetWindowControls();
649 }
650 
PaintLayeredWindow(gfx::Canvas * canvas)651 void DesktopWindowTreeHostWin::PaintLayeredWindow(gfx::Canvas* canvas) {
652   GetWidget()->GetRootView()->Paint(canvas, views::CullSet());
653 }
654 
GetNativeViewAccessible()655 gfx::NativeViewAccessible DesktopWindowTreeHostWin::GetNativeViewAccessible() {
656   return GetWidget()->GetRootView()->GetNativeViewAccessible();
657 }
658 
GetInputMethod()659 InputMethod* DesktopWindowTreeHostWin::GetInputMethod() {
660   return GetWidget()->GetInputMethodDirect();
661 }
662 
ShouldHandleSystemCommands() const663 bool DesktopWindowTreeHostWin::ShouldHandleSystemCommands() const {
664   return GetWidget()->widget_delegate()->ShouldHandleSystemCommands();
665 }
666 
HandleAppDeactivated()667 void DesktopWindowTreeHostWin::HandleAppDeactivated() {
668   native_widget_delegate_->EnableInactiveRendering();
669 }
670 
HandleActivationChanged(bool active)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 
HandleAppCommand(short command)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 
HandleCancelMode()690 void DesktopWindowTreeHostWin::HandleCancelMode() {
691   dispatcher()->DispatchCancelModeEvent();
692 }
693 
HandleCaptureLost()694 void DesktopWindowTreeHostWin::HandleCaptureLost() {
695   OnHostLostWindowCapture();
696   native_widget_delegate_->OnMouseCaptureLost();
697 }
698 
HandleClose()699 void DesktopWindowTreeHostWin::HandleClose() {
700   GetWidget()->Close();
701 }
702 
HandleCommand(int command)703 bool DesktopWindowTreeHostWin::HandleCommand(int command) {
704   return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
705 }
706 
HandleAccelerator(const ui::Accelerator & accelerator)707 void DesktopWindowTreeHostWin::HandleAccelerator(
708     const ui::Accelerator& accelerator) {
709   GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator);
710 }
711 
HandleCreate()712 void DesktopWindowTreeHostWin::HandleCreate() {
713   native_widget_delegate_->OnNativeWidgetCreated(true);
714 }
715 
HandleDestroying()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 
HandleDestroyed()725 void DesktopWindowTreeHostWin::HandleDestroyed() {
726   desktop_native_widget_aura_->OnHostClosed();
727 }
728 
HandleInitialFocus(ui::WindowShowState show_state)729 bool DesktopWindowTreeHostWin::HandleInitialFocus(
730     ui::WindowShowState show_state) {
731   return GetWidget()->SetInitialFocus(show_state);
732 }
733 
HandleDisplayChange()734 void DesktopWindowTreeHostWin::HandleDisplayChange() {
735   GetWidget()->widget_delegate()->OnDisplayChanged();
736 }
737 
HandleBeginWMSizeMove()738 void DesktopWindowTreeHostWin::HandleBeginWMSizeMove() {
739   native_widget_delegate_->OnNativeWidgetBeginUserBoundsChange();
740 }
741 
HandleEndWMSizeMove()742 void DesktopWindowTreeHostWin::HandleEndWMSizeMove() {
743   native_widget_delegate_->OnNativeWidgetEndUserBoundsChange();
744 }
745 
HandleMove()746 void DesktopWindowTreeHostWin::HandleMove() {
747   native_widget_delegate_->OnNativeWidgetMove();
748   OnHostMoved(GetBounds().origin());
749 }
750 
HandleWorkAreaChanged()751 void DesktopWindowTreeHostWin::HandleWorkAreaChanged() {
752   GetWidget()->widget_delegate()->OnWorkAreaChanged();
753 }
754 
HandleVisibilityChanging(bool visible)755 void DesktopWindowTreeHostWin::HandleVisibilityChanging(bool visible) {
756   native_widget_delegate_->OnNativeWidgetVisibilityChanging(visible);
757 }
758 
HandleVisibilityChanged(bool visible)759 void DesktopWindowTreeHostWin::HandleVisibilityChanged(bool visible) {
760   native_widget_delegate_->OnNativeWidgetVisibilityChanged(visible);
761 }
762 
HandleClientSizeChanged(const gfx::Size & new_size)763 void DesktopWindowTreeHostWin::HandleClientSizeChanged(
764     const gfx::Size& new_size) {
765   if (dispatcher())
766     OnHostResized(new_size);
767 }
768 
HandleFrameChanged()769 void DesktopWindowTreeHostWin::HandleFrameChanged() {
770   SetWindowTransparency();
771   // Replace the frame and layout the contents.
772   GetWidget()->non_client_view()->UpdateFrame();
773 }
774 
HandleNativeFocus(HWND last_focused_window)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 
HandleNativeBlur(HWND focused_window)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 
HandleMouseEvent(const ui::MouseEvent & event)789 bool DesktopWindowTreeHostWin::HandleMouseEvent(const ui::MouseEvent& event) {
790   SendEventToProcessor(const_cast<ui::MouseEvent*>(&event));
791   return event.handled();
792 }
793 
HandleKeyEvent(const ui::KeyEvent & event)794 bool DesktopWindowTreeHostWin::HandleKeyEvent(const ui::KeyEvent& event) {
795   return false;
796 }
797 
HandleUntranslatedKeyEvent(const ui::KeyEvent & event)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 
HandleTouchEvent(const ui::TouchEvent & event)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 
HandleIMEMessage(UINT message,WPARAM w_param,LPARAM l_param,LRESULT * result)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 
HandleInputLanguageChange(DWORD character_set,HKL input_language_id)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 
HandlePaintAccelerated(const gfx::Rect & invalid_rect)854 bool DesktopWindowTreeHostWin::HandlePaintAccelerated(
855     const gfx::Rect& invalid_rect) {
856   return native_widget_delegate_->OnNativeWidgetPaintAccelerated(invalid_rect);
857 }
858 
HandlePaint(gfx::Canvas * canvas)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 
HandleTooltipNotify(int w_param,NMHDR * l_param,LRESULT * l_result)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 
HandleTooltipMouseMove(UINT message,WPARAM w_param,LPARAM l_param)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 
HandleMenuLoop(bool in_menu_loop)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 
PreHandleMSG(UINT message,WPARAM w_param,LPARAM l_param,LRESULT * result)887 bool DesktopWindowTreeHostWin::PreHandleMSG(UINT message,
888                                             WPARAM w_param,
889                                             LPARAM l_param,
890                                             LRESULT* result) {
891   return false;
892 }
893 
PostHandleMSG(UINT message,WPARAM w_param,LPARAM l_param)894 void DesktopWindowTreeHostWin::PostHandleMSG(UINT message,
895                                              WPARAM w_param,
896                                              LPARAM l_param) {
897 }
898 
HandleScrollEvent(const ui::ScrollEvent & event)899 bool DesktopWindowTreeHostWin::HandleScrollEvent(
900     const ui::ScrollEvent& event) {
901   SendEventToProcessor(const_cast<ui::ScrollEvent*>(&event));
902   return event.handled();
903 }
904 
HandleWindowSizeChanging()905 void DesktopWindowTreeHostWin::HandleWindowSizeChanging() {
906   if (compositor())
907     compositor()->FinishAllRendering();
908 }
909 
910 ////////////////////////////////////////////////////////////////////////////////
911 // DesktopWindowTreeHostWin, private:
912 
GetWidget()913 Widget* DesktopWindowTreeHostWin::GetWidget() {
914   return native_widget_delegate_->AsWidget();
915 }
916 
GetWidget() const917 const Widget* DesktopWindowTreeHostWin::GetWidget() const {
918   return native_widget_delegate_->AsWidget();
919 }
920 
GetHWND() const921 HWND DesktopWindowTreeHostWin::GetHWND() const {
922   return message_handler_->hwnd();
923 }
924 
SetWindowTransparency()925 void DesktopWindowTreeHostWin::SetWindowTransparency() {
926   bool transparent = ShouldUseNativeFrame() && !IsFullscreen();
927   compositor()->SetHostHasTransparentBackground(transparent);
928   window()->SetTransparent(transparent);
929   content_window_->SetTransparent(transparent);
930 }
931 
IsModalWindowActive() const932 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
Create(internal::NativeWidgetDelegate * native_widget_delegate,DesktopNativeWidgetAura * desktop_native_widget_aura)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