Roll src/third_party/skia d32087a:1052f51
[chromium-blink-merge.git] / ui / views / widget / desktop_aura / desktop_window_tree_host_win.cc
blob270bd54b597ef879104b4dc42977cfcad8157934
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.
5 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
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/compositor/paint_context.h"
20 #include "ui/gfx/geometry/insets.h"
21 #include "ui/gfx/geometry/vector2d.h"
22 #include "ui/gfx/native_widget_types.h"
23 #include "ui/gfx/path.h"
24 #include "ui/gfx/path_win.h"
25 #include "ui/gfx/win/dpi.h"
26 #include "ui/native_theme/native_theme_aura.h"
27 #include "ui/native_theme/native_theme_win.h"
28 #include "ui/views/corewm/tooltip_win.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/views/win/hwnd_util.h"
39 #include "ui/wm/core/compound_event_filter.h"
40 #include "ui/wm/core/window_animations.h"
41 #include "ui/wm/public/scoped_tooltip_disabler.h"
43 DECLARE_WINDOW_PROPERTY_TYPE(views::DesktopWindowTreeHostWin*);
45 namespace views {
47 namespace {
49 gfx::Size GetExpandedWindowSize(DWORD window_style, gfx::Size size) {
50 if (!(window_style & WS_EX_COMPOSITED) || !ui::win::IsAeroGlassEnabled())
51 return size;
53 // Some AMD drivers can't display windows that are less than 64x64 pixels,
54 // so expand them to be at least that size. http://crbug.com/286609
55 gfx::Size expanded(std::max(size.width(), 64), std::max(size.height(), 64));
56 return expanded;
59 void InsetBottomRight(gfx::Rect* rect, const gfx::Vector2d& vector) {
60 rect->Inset(0, 0, vector.x(), vector.y());
63 } // namespace
65 DEFINE_WINDOW_PROPERTY_KEY(aura::Window*, kContentWindowForRootWindow, NULL);
67 // Identifies the DesktopWindowTreeHostWin associated with the
68 // WindowEventDispatcher.
69 DEFINE_WINDOW_PROPERTY_KEY(DesktopWindowTreeHostWin*, kDesktopWindowTreeHostKey,
70 NULL);
72 ////////////////////////////////////////////////////////////////////////////////
73 // DesktopWindowTreeHostWin, public:
75 bool DesktopWindowTreeHostWin::is_cursor_visible_ = true;
77 DesktopWindowTreeHostWin::DesktopWindowTreeHostWin(
78 internal::NativeWidgetDelegate* native_widget_delegate,
79 DesktopNativeWidgetAura* desktop_native_widget_aura)
80 : message_handler_(new HWNDMessageHandler(this)),
81 native_widget_delegate_(native_widget_delegate),
82 desktop_native_widget_aura_(desktop_native_widget_aura),
83 content_window_(NULL),
84 drag_drop_client_(NULL),
85 should_animate_window_close_(false),
86 pending_close_(false),
87 has_non_client_view_(false),
88 tooltip_(NULL) {
91 DesktopWindowTreeHostWin::~DesktopWindowTreeHostWin() {
92 // WARNING: |content_window_| has been destroyed by the time we get here.
93 desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this);
94 DestroyDispatcher();
97 // static
98 aura::Window* DesktopWindowTreeHostWin::GetContentWindowForHWND(HWND hwnd) {
99 aura::WindowTreeHost* host =
100 aura::WindowTreeHost::GetForAcceleratedWidget(hwnd);
101 return host ? host->window()->GetProperty(kContentWindowForRootWindow) : NULL;
104 // static
105 ui::NativeTheme* DesktopWindowTreeHost::GetNativeTheme(aura::Window* window) {
106 // Use NativeThemeWin for windows shown on the desktop, those not on the
107 // desktop come from Ash and get NativeThemeAura.
108 aura::WindowTreeHost* host = window ? window->GetHost() : NULL;
109 if (host) {
110 HWND host_hwnd = host->GetAcceleratedWidget();
111 if (host_hwnd &&
112 DesktopWindowTreeHostWin::GetContentWindowForHWND(host_hwnd)) {
113 return ui::NativeThemeWin::instance();
116 return ui::NativeThemeAura::instance();
119 ////////////////////////////////////////////////////////////////////////////////
120 // DesktopWindowTreeHostWin, DesktopWindowTreeHost implementation:
122 void DesktopWindowTreeHostWin::Init(aura::Window* content_window,
123 const Widget::InitParams& params) {
124 // TODO(beng): SetInitParams().
125 content_window_ = content_window;
127 aura::client::SetAnimationHost(content_window_, this);
129 ConfigureWindowStyles(message_handler_.get(), params,
130 GetWidget()->widget_delegate(),
131 native_widget_delegate_);
133 HWND parent_hwnd = NULL;
134 if (params.parent && params.parent->GetHost())
135 parent_hwnd = params.parent->GetHost()->GetAcceleratedWidget();
137 message_handler_->set_remove_standard_frame(params.remove_standard_frame);
139 has_non_client_view_ = Widget::RequiresNonClientView(params.type);
141 gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(params.bounds);
142 message_handler_->Init(parent_hwnd, pixel_bounds);
143 if (params.type == Widget::InitParams::TYPE_MENU) {
144 ::SetProp(GetAcceleratedWidget(),
145 kForceSoftwareCompositor,
146 reinterpret_cast<HANDLE>(true));
148 CreateCompositor();
149 OnAcceleratedWidgetAvailable();
152 void DesktopWindowTreeHostWin::OnNativeWidgetCreated(
153 const Widget::InitParams& params) {
154 // The cursor is not necessarily visible when the root window is created.
155 aura::client::CursorClient* cursor_client =
156 aura::client::GetCursorClient(window());
157 if (cursor_client)
158 is_cursor_visible_ = cursor_client->IsCursorVisible();
160 window()->SetProperty(kContentWindowForRootWindow, content_window_);
161 window()->SetProperty(kDesktopWindowTreeHostKey, this);
163 should_animate_window_close_ =
164 content_window_->type() != ui::wm::WINDOW_TYPE_NORMAL &&
165 !wm::WindowAnimationsDisabled(content_window_);
167 // TODO this is not invoked *after* Init(), but should be ok.
168 SetWindowTransparency();
171 scoped_ptr<corewm::Tooltip> DesktopWindowTreeHostWin::CreateTooltip() {
172 DCHECK(!tooltip_);
173 tooltip_ = new corewm::TooltipWin(GetAcceleratedWidget());
174 return make_scoped_ptr(tooltip_);
177 scoped_ptr<aura::client::DragDropClient>
178 DesktopWindowTreeHostWin::CreateDragDropClient(
179 DesktopNativeCursorManager* cursor_manager) {
180 drag_drop_client_ = new DesktopDragDropClientWin(window(), GetHWND());
181 return make_scoped_ptr(drag_drop_client_);
184 void DesktopWindowTreeHostWin::Close() {
185 // TODO(beng): Move this entire branch to DNWA so it can be shared with X11.
186 if (should_animate_window_close_) {
187 pending_close_ = true;
188 const bool is_animating =
189 content_window_->layer()->GetAnimator()->IsAnimatingProperty(
190 ui::LayerAnimationElement::VISIBILITY);
191 // Animation may not start for a number of reasons.
192 if (!is_animating)
193 message_handler_->Close();
194 // else case, OnWindowHidingAnimationCompleted does the actual Close.
195 } else {
196 message_handler_->Close();
200 void DesktopWindowTreeHostWin::CloseNow() {
201 message_handler_->CloseNow();
204 aura::WindowTreeHost* DesktopWindowTreeHostWin::AsWindowTreeHost() {
205 return this;
208 void DesktopWindowTreeHostWin::ShowWindowWithState(
209 ui::WindowShowState show_state) {
210 if (compositor())
211 compositor()->SetVisible(true);
212 message_handler_->ShowWindowWithState(show_state);
215 void DesktopWindowTreeHostWin::ShowMaximizedWithBounds(
216 const gfx::Rect& restored_bounds) {
217 if (compositor())
218 compositor()->SetVisible(true);
219 gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(restored_bounds);
220 message_handler_->ShowMaximizedWithBounds(pixel_bounds);
223 bool DesktopWindowTreeHostWin::IsVisible() const {
224 return message_handler_->IsVisible();
227 void DesktopWindowTreeHostWin::SetSize(const gfx::Size& size) {
228 gfx::Size size_in_pixels = gfx::win::DIPToScreenSize(size);
229 gfx::Size expanded = GetExpandedWindowSize(
230 message_handler_->window_ex_style(), size_in_pixels);
231 window_enlargement_ =
232 gfx::Vector2d(expanded.width() - size_in_pixels.width(),
233 expanded.height() - size_in_pixels.height());
234 message_handler_->SetSize(expanded);
237 void DesktopWindowTreeHostWin::StackAbove(aura::Window* window) {
238 HWND hwnd = HWNDForNativeView(window);
239 if (hwnd)
240 message_handler_->StackAbove(hwnd);
243 void DesktopWindowTreeHostWin::StackAtTop() {
244 message_handler_->StackAtTop();
247 void DesktopWindowTreeHostWin::CenterWindow(const gfx::Size& size) {
248 gfx::Size size_in_pixels = gfx::win::DIPToScreenSize(size);
249 gfx::Size expanded_size;
250 expanded_size = GetExpandedWindowSize(message_handler_->window_ex_style(),
251 size_in_pixels);
252 window_enlargement_ =
253 gfx::Vector2d(expanded_size.width() - size_in_pixels.width(),
254 expanded_size.height() - size_in_pixels.height());
255 message_handler_->CenterWindow(expanded_size);
258 void DesktopWindowTreeHostWin::GetWindowPlacement(
259 gfx::Rect* bounds,
260 ui::WindowShowState* show_state) const {
261 message_handler_->GetWindowPlacement(bounds, show_state);
262 InsetBottomRight(bounds, window_enlargement_);
263 *bounds = gfx::win::ScreenToDIPRect(*bounds);
266 gfx::Rect DesktopWindowTreeHostWin::GetWindowBoundsInScreen() const {
267 gfx::Rect pixel_bounds = message_handler_->GetWindowBoundsInScreen();
268 InsetBottomRight(&pixel_bounds, window_enlargement_);
269 return gfx::win::ScreenToDIPRect(pixel_bounds);
272 gfx::Rect DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() const {
273 gfx::Rect pixel_bounds = message_handler_->GetClientAreaBoundsInScreen();
274 InsetBottomRight(&pixel_bounds, window_enlargement_);
275 return gfx::win::ScreenToDIPRect(pixel_bounds);
278 gfx::Rect DesktopWindowTreeHostWin::GetRestoredBounds() const {
279 gfx::Rect pixel_bounds = message_handler_->GetRestoredBounds();
280 InsetBottomRight(&pixel_bounds, window_enlargement_);
281 return gfx::win::ScreenToDIPRect(pixel_bounds);
284 gfx::Rect DesktopWindowTreeHostWin::GetWorkAreaBoundsInScreen() const {
285 MONITORINFO monitor_info;
286 monitor_info.cbSize = sizeof(monitor_info);
287 GetMonitorInfo(MonitorFromWindow(message_handler_->hwnd(),
288 MONITOR_DEFAULTTONEAREST),
289 &monitor_info);
290 gfx::Rect pixel_bounds = gfx::Rect(monitor_info.rcWork);
291 return gfx::win::ScreenToDIPRect(pixel_bounds);
294 void DesktopWindowTreeHostWin::SetShape(SkRegion* native_region) {
295 if (native_region) {
296 // TODO(wez): This would be a lot simpler if we were passed an SkPath.
297 // See crbug.com/410593.
298 SkRegion* shape = native_region;
299 SkRegion device_region;
300 if (gfx::GetDPIScale() > 1.0) {
301 shape = &device_region;
302 const float& scale = gfx::GetDPIScale();
303 std::vector<SkIRect> rects;
304 for (SkRegion::Iterator it(*native_region); !it.done(); it.next()) {
305 const SkIRect& rect = it.rect();
306 SkRect scaled_rect =
307 SkRect::MakeLTRB(rect.left() * scale, rect.top() * scale,
308 rect.right() * scale, rect.bottom() * scale);
309 SkIRect rounded_scaled_rect;
310 scaled_rect.roundOut(&rounded_scaled_rect);
311 rects.push_back(rounded_scaled_rect);
313 if (!rects.empty())
314 device_region.setRects(&rects[0], rects.size());
317 message_handler_->SetRegion(gfx::CreateHRGNFromSkRegion(*shape));
318 } else {
319 message_handler_->SetRegion(NULL);
322 delete native_region;
325 void DesktopWindowTreeHostWin::Activate() {
326 message_handler_->Activate();
329 void DesktopWindowTreeHostWin::Deactivate() {
330 message_handler_->Deactivate();
333 bool DesktopWindowTreeHostWin::IsActive() const {
334 return message_handler_->IsActive();
337 void DesktopWindowTreeHostWin::Maximize() {
338 message_handler_->Maximize();
341 void DesktopWindowTreeHostWin::Minimize() {
342 message_handler_->Minimize();
345 void DesktopWindowTreeHostWin::Restore() {
346 message_handler_->Restore();
349 bool DesktopWindowTreeHostWin::IsMaximized() const {
350 return message_handler_->IsMaximized();
353 bool DesktopWindowTreeHostWin::IsMinimized() const {
354 return message_handler_->IsMinimized();
357 bool DesktopWindowTreeHostWin::HasCapture() const {
358 return message_handler_->HasCapture();
361 void DesktopWindowTreeHostWin::SetAlwaysOnTop(bool always_on_top) {
362 message_handler_->SetAlwaysOnTop(always_on_top);
365 bool DesktopWindowTreeHostWin::IsAlwaysOnTop() const {
366 return message_handler_->IsAlwaysOnTop();
369 void DesktopWindowTreeHostWin::SetVisibleOnAllWorkspaces(bool always_visible) {
370 // Windows does not have the concept of workspaces.
373 bool DesktopWindowTreeHostWin::SetWindowTitle(const base::string16& title) {
374 return message_handler_->SetTitle(title);
377 void DesktopWindowTreeHostWin::ClearNativeFocus() {
378 message_handler_->ClearNativeFocus();
381 Widget::MoveLoopResult DesktopWindowTreeHostWin::RunMoveLoop(
382 const gfx::Vector2d& drag_offset,
383 Widget::MoveLoopSource source,
384 Widget::MoveLoopEscapeBehavior escape_behavior) {
385 const bool hide_on_escape =
386 escape_behavior == Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_HIDE;
387 return message_handler_->RunMoveLoop(drag_offset, hide_on_escape) ?
388 Widget::MOVE_LOOP_SUCCESSFUL : Widget::MOVE_LOOP_CANCELED;
391 void DesktopWindowTreeHostWin::EndMoveLoop() {
392 message_handler_->EndMoveLoop();
395 void DesktopWindowTreeHostWin::SetVisibilityChangedAnimationsEnabled(
396 bool value) {
397 message_handler_->SetVisibilityChangedAnimationsEnabled(value);
398 content_window_->SetProperty(aura::client::kAnimationsDisabledKey, !value);
401 bool DesktopWindowTreeHostWin::ShouldUseNativeFrame() const {
402 return IsTranslucentWindowOpacitySupported();
405 bool DesktopWindowTreeHostWin::ShouldWindowContentsBeTransparent() const {
406 // If the window has a native frame, we assume it is an Aero Glass window, and
407 // is therefore transparent. Note: This is not equivalent to calling
408 // IsAeroGlassEnabled, because ShouldUseNativeFrame is overridden in a
409 // subclass.
410 return ShouldUseNativeFrame();
413 void DesktopWindowTreeHostWin::FrameTypeChanged() {
414 message_handler_->FrameTypeChanged();
415 SetWindowTransparency();
418 void DesktopWindowTreeHostWin::SetFullscreen(bool fullscreen) {
419 message_handler_->SetFullscreen(fullscreen);
420 // TODO(sky): workaround for ScopedFullscreenVisibility showing window
421 // directly. Instead of this should listen for visibility changes and then
422 // update window.
423 if (message_handler_->IsVisible() && !content_window_->TargetVisibility()) {
424 if (compositor())
425 compositor()->SetVisible(true);
426 content_window_->Show();
428 SetWindowTransparency();
431 bool DesktopWindowTreeHostWin::IsFullscreen() const {
432 return message_handler_->fullscreen_handler()->fullscreen();
435 void DesktopWindowTreeHostWin::SetOpacity(unsigned char opacity) {
436 content_window_->layer()->SetOpacity(opacity / 255.0);
439 void DesktopWindowTreeHostWin::SetWindowIcons(
440 const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
441 message_handler_->SetWindowIcons(window_icon, app_icon);
444 void DesktopWindowTreeHostWin::InitModalType(ui::ModalType modal_type) {
445 message_handler_->InitModalType(modal_type);
448 void DesktopWindowTreeHostWin::FlashFrame(bool flash_frame) {
449 message_handler_->FlashFrame(flash_frame);
452 void DesktopWindowTreeHostWin::OnRootViewLayout() {
455 void DesktopWindowTreeHostWin::OnNativeWidgetFocus() {
456 // HWNDMessageHandler will perform the proper updating on its own.
459 void DesktopWindowTreeHostWin::OnNativeWidgetBlur() {
462 bool DesktopWindowTreeHostWin::IsAnimatingClosed() const {
463 return pending_close_;
466 bool DesktopWindowTreeHostWin::IsTranslucentWindowOpacitySupported() const {
467 return ui::win::IsAeroGlassEnabled();
470 void DesktopWindowTreeHostWin::SizeConstraintsChanged() {
471 message_handler_->SizeConstraintsChanged();
474 ////////////////////////////////////////////////////////////////////////////////
475 // DesktopWindowTreeHostWin, WindowTreeHost implementation:
477 ui::EventSource* DesktopWindowTreeHostWin::GetEventSource() {
478 return this;
481 gfx::AcceleratedWidget DesktopWindowTreeHostWin::GetAcceleratedWidget() {
482 return message_handler_->hwnd();
485 void DesktopWindowTreeHostWin::ShowImpl() {
486 message_handler_->Show();
489 void DesktopWindowTreeHostWin::HideImpl() {
490 if (!pending_close_)
491 message_handler_->Hide();
494 // GetBounds and SetBounds work in pixel coordinates, whereas other get/set
495 // methods work in DIP.
497 gfx::Rect DesktopWindowTreeHostWin::GetBounds() const {
498 gfx::Rect bounds(message_handler_->GetClientAreaBounds());
499 // If the window bounds were expanded we need to return the original bounds
500 // To achieve this we do the reverse of the expansion, i.e. add the
501 // window_expansion_top_left_delta_ to the origin and subtract the
502 // window_expansion_bottom_right_delta_ from the width and height.
503 gfx::Rect without_expansion(
504 bounds.x() + window_expansion_top_left_delta_.x(),
505 bounds.y() + window_expansion_top_left_delta_.y(),
506 bounds.width() - window_expansion_bottom_right_delta_.x() -
507 window_enlargement_.x(),
508 bounds.height() - window_expansion_bottom_right_delta_.y() -
509 window_enlargement_.y());
510 return without_expansion;
513 void DesktopWindowTreeHostWin::SetBounds(const gfx::Rect& bounds) {
514 // If the window bounds have to be expanded we need to subtract the
515 // window_expansion_top_left_delta_ from the origin and add the
516 // window_expansion_bottom_right_delta_ to the width and height
517 gfx::Size old_hwnd_size(message_handler_->GetClientAreaBounds().size());
518 gfx::Size old_content_size = GetBounds().size();
520 gfx::Rect expanded(
521 bounds.x() - window_expansion_top_left_delta_.x(),
522 bounds.y() - window_expansion_top_left_delta_.y(),
523 bounds.width() + window_expansion_bottom_right_delta_.x(),
524 bounds.height() + window_expansion_bottom_right_delta_.y());
526 gfx::Rect new_expanded(
527 expanded.origin(),
528 GetExpandedWindowSize(message_handler_->window_ex_style(),
529 expanded.size()));
530 window_enlargement_ =
531 gfx::Vector2d(new_expanded.width() - expanded.width(),
532 new_expanded.height() - expanded.height());
533 message_handler_->SetBounds(new_expanded, old_content_size != bounds.size());
536 gfx::Point DesktopWindowTreeHostWin::GetLocationOnNativeScreen() const {
537 return GetBounds().origin();
540 void DesktopWindowTreeHostWin::SetCapture() {
541 message_handler_->SetCapture();
544 void DesktopWindowTreeHostWin::ReleaseCapture() {
545 message_handler_->ReleaseCapture();
548 void DesktopWindowTreeHostWin::SetCursorNative(gfx::NativeCursor cursor) {
549 ui::CursorLoaderWin cursor_loader;
550 cursor_loader.SetPlatformCursor(&cursor);
552 message_handler_->SetCursor(cursor.platform());
555 void DesktopWindowTreeHostWin::OnCursorVisibilityChangedNative(bool show) {
556 if (is_cursor_visible_ == show)
557 return;
558 is_cursor_visible_ = show;
559 ::ShowCursor(!!show);
562 void DesktopWindowTreeHostWin::MoveCursorToNative(const gfx::Point& location) {
563 POINT cursor_location = location.ToPOINT();
564 ::ClientToScreen(GetHWND(), &cursor_location);
565 ::SetCursorPos(cursor_location.x, cursor_location.y);
568 ////////////////////////////////////////////////////////////////////////////////
569 // DesktopWindowTreeHostWin, aura::AnimationHost implementation:
571 void DesktopWindowTreeHostWin::SetHostTransitionOffsets(
572 const gfx::Vector2d& top_left_delta,
573 const gfx::Vector2d& bottom_right_delta) {
574 gfx::Rect bounds_without_expansion = GetBounds();
575 window_expansion_top_left_delta_ = top_left_delta;
576 window_expansion_bottom_right_delta_ = bottom_right_delta;
577 SetBounds(bounds_without_expansion);
580 void DesktopWindowTreeHostWin::OnWindowHidingAnimationCompleted() {
581 if (pending_close_)
582 message_handler_->Close();
585 ////////////////////////////////////////////////////////////////////////////////
586 // DesktopWindowTreeHostWin, HWNDMessageHandlerDelegate implementation:
588 bool DesktopWindowTreeHostWin::IsWidgetWindow() const {
589 return has_non_client_view_;
592 bool DesktopWindowTreeHostWin::IsUsingCustomFrame() const {
593 return !GetWidget()->ShouldUseNativeFrame();
596 void DesktopWindowTreeHostWin::SchedulePaint() {
597 GetWidget()->GetRootView()->SchedulePaint();
600 void DesktopWindowTreeHostWin::EnableInactiveRendering() {
601 native_widget_delegate_->EnableInactiveRendering();
604 bool DesktopWindowTreeHostWin::IsInactiveRenderingDisabled() {
605 return native_widget_delegate_->IsInactiveRenderingDisabled();
608 bool DesktopWindowTreeHostWin::CanResize() const {
609 return GetWidget()->widget_delegate()->CanResize();
612 bool DesktopWindowTreeHostWin::CanMaximize() const {
613 return GetWidget()->widget_delegate()->CanMaximize();
616 bool DesktopWindowTreeHostWin::CanMinimize() const {
617 return GetWidget()->widget_delegate()->CanMinimize();
620 bool DesktopWindowTreeHostWin::CanActivate() const {
621 if (IsModalWindowActive())
622 return true;
623 return native_widget_delegate_->CanActivate();
626 bool DesktopWindowTreeHostWin::WidgetSizeIsClientSize() const {
627 const Widget* widget = GetWidget()->GetTopLevelWidget();
628 return IsMaximized() || (widget && widget->ShouldUseNativeFrame());
631 bool DesktopWindowTreeHostWin::IsModal() const {
632 return native_widget_delegate_->IsModal();
635 int DesktopWindowTreeHostWin::GetInitialShowState() const {
636 return CanActivate() ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
639 bool DesktopWindowTreeHostWin::WillProcessWorkAreaChange() const {
640 return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
643 int DesktopWindowTreeHostWin::GetNonClientComponent(
644 const gfx::Point& point) const {
645 gfx::Point dip_position = gfx::win::ScreenToDIPPoint(point);
646 return native_widget_delegate_->GetNonClientComponent(dip_position);
649 void DesktopWindowTreeHostWin::GetWindowMask(const gfx::Size& size,
650 gfx::Path* path) {
651 if (GetWidget()->non_client_view()) {
652 GetWidget()->non_client_view()->GetWindowMask(size, path);
653 } else if (!window_enlargement_.IsZero()) {
654 gfx::Rect bounds(WidgetSizeIsClientSize()
655 ? message_handler_->GetClientAreaBoundsInScreen()
656 : message_handler_->GetWindowBoundsInScreen());
657 InsetBottomRight(&bounds, window_enlargement_);
658 path->addRect(SkRect::MakeXYWH(0, 0, bounds.width(), bounds.height()));
662 bool DesktopWindowTreeHostWin::GetClientAreaInsets(gfx::Insets* insets) const {
663 return false;
666 void DesktopWindowTreeHostWin::GetMinMaxSize(gfx::Size* min_size,
667 gfx::Size* max_size) const {
668 *min_size = native_widget_delegate_->GetMinimumSize();
669 *max_size = native_widget_delegate_->GetMaximumSize();
672 gfx::Size DesktopWindowTreeHostWin::GetRootViewSize() const {
673 return GetWidget()->GetRootView()->size();
676 void DesktopWindowTreeHostWin::ResetWindowControls() {
677 GetWidget()->non_client_view()->ResetWindowControls();
680 gfx::NativeViewAccessible DesktopWindowTreeHostWin::GetNativeViewAccessible() {
681 return GetWidget()->GetRootView()->GetNativeViewAccessible();
684 bool DesktopWindowTreeHostWin::ShouldHandleSystemCommands() const {
685 return GetWidget()->widget_delegate()->ShouldHandleSystemCommands();
688 void DesktopWindowTreeHostWin::HandleAppDeactivated() {
689 native_widget_delegate_->EnableInactiveRendering();
692 void DesktopWindowTreeHostWin::HandleActivationChanged(bool active) {
693 // This can be invoked from HWNDMessageHandler::Init(), at which point we're
694 // not in a good state and need to ignore it.
695 // TODO(beng): Do we need this still now the host owns the dispatcher?
696 if (!dispatcher())
697 return;
699 if (active)
700 OnHostActivated();
701 desktop_native_widget_aura_->HandleActivationChanged(active);
704 bool DesktopWindowTreeHostWin::HandleAppCommand(short command) {
705 // We treat APPCOMMAND ids as an extension of our command namespace, and just
706 // let the delegate figure out what to do...
707 return GetWidget()->widget_delegate() &&
708 GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
711 void DesktopWindowTreeHostWin::HandleCancelMode() {
712 dispatcher()->DispatchCancelModeEvent();
715 void DesktopWindowTreeHostWin::HandleCaptureLost() {
716 OnHostLostWindowCapture();
719 void DesktopWindowTreeHostWin::HandleClose() {
720 GetWidget()->Close();
723 bool DesktopWindowTreeHostWin::HandleCommand(int command) {
724 return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
727 void DesktopWindowTreeHostWin::HandleAccelerator(
728 const ui::Accelerator& accelerator) {
729 GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator);
732 void DesktopWindowTreeHostWin::HandleCreate() {
733 native_widget_delegate_->OnNativeWidgetCreated(true);
736 void DesktopWindowTreeHostWin::HandleDestroying() {
737 drag_drop_client_->OnNativeWidgetDestroying(GetHWND());
738 native_widget_delegate_->OnNativeWidgetDestroying();
740 // Destroy the compositor before destroying the HWND since shutdown
741 // may try to swap to the window.
742 DestroyCompositor();
745 void DesktopWindowTreeHostWin::HandleDestroyed() {
746 desktop_native_widget_aura_->OnHostClosed();
749 bool DesktopWindowTreeHostWin::HandleInitialFocus(
750 ui::WindowShowState show_state) {
751 return GetWidget()->SetInitialFocus(show_state);
754 void DesktopWindowTreeHostWin::HandleDisplayChange() {
755 GetWidget()->widget_delegate()->OnDisplayChanged();
758 void DesktopWindowTreeHostWin::HandleBeginWMSizeMove() {
759 native_widget_delegate_->OnNativeWidgetBeginUserBoundsChange();
762 void DesktopWindowTreeHostWin::HandleEndWMSizeMove() {
763 native_widget_delegate_->OnNativeWidgetEndUserBoundsChange();
766 void DesktopWindowTreeHostWin::HandleMove() {
767 native_widget_delegate_->OnNativeWidgetMove();
768 OnHostMoved(GetBounds().origin());
771 void DesktopWindowTreeHostWin::HandleWorkAreaChanged() {
772 GetWidget()->widget_delegate()->OnWorkAreaChanged();
775 void DesktopWindowTreeHostWin::HandleVisibilityChanging(bool visible) {
776 native_widget_delegate_->OnNativeWidgetVisibilityChanging(visible);
779 void DesktopWindowTreeHostWin::HandleVisibilityChanged(bool visible) {
780 native_widget_delegate_->OnNativeWidgetVisibilityChanged(visible);
783 void DesktopWindowTreeHostWin::HandleClientSizeChanged(
784 const gfx::Size& new_size) {
785 if (dispatcher())
786 OnHostResized(new_size);
789 void DesktopWindowTreeHostWin::HandleFrameChanged() {
790 SetWindowTransparency();
791 // Replace the frame and layout the contents.
792 GetWidget()->non_client_view()->UpdateFrame();
795 void DesktopWindowTreeHostWin::HandleNativeFocus(HWND last_focused_window) {
796 // TODO(beng): inform the native_widget_delegate_.
799 void DesktopWindowTreeHostWin::HandleNativeBlur(HWND focused_window) {
800 // TODO(beng): inform the native_widget_delegate_.
803 bool DesktopWindowTreeHostWin::HandleMouseEvent(const ui::MouseEvent& event) {
804 SendEventToProcessor(const_cast<ui::MouseEvent*>(&event));
805 return event.handled();
808 void DesktopWindowTreeHostWin::HandleKeyEvent(ui::KeyEvent* event) {
809 GetInputMethod()->DispatchKeyEvent(event);
812 void DesktopWindowTreeHostWin::HandleTouchEvent(
813 const ui::TouchEvent& event) {
814 // HWNDMessageHandler asynchronously processes touch events. Because of this
815 // it's possible for the aura::WindowEventDispatcher to have been destroyed
816 // by the time we attempt to process them.
817 if (!GetWidget()->GetNativeView())
818 return;
820 // Currently we assume the window that has capture gets touch events too.
821 aura::WindowTreeHost* host =
822 aura::WindowTreeHost::GetForAcceleratedWidget(GetCapture());
823 if (host) {
824 DesktopWindowTreeHostWin* target =
825 host->window()->GetProperty(kDesktopWindowTreeHostKey);
826 if (target && target->HasCapture() && target != this) {
827 POINT target_location(event.location().ToPOINT());
828 ClientToScreen(GetHWND(), &target_location);
829 ScreenToClient(target->GetHWND(), &target_location);
830 ui::TouchEvent target_event(event, static_cast<View*>(NULL),
831 static_cast<View*>(NULL));
832 target_event.set_location(gfx::Point(target_location));
833 target_event.set_root_location(target_event.location());
834 target->SendEventToProcessor(&target_event);
835 return;
838 SendEventToProcessor(const_cast<ui::TouchEvent*>(&event));
841 bool DesktopWindowTreeHostWin::HandleIMEMessage(UINT message,
842 WPARAM w_param,
843 LPARAM l_param,
844 LRESULT* result) {
845 MSG msg = {};
846 msg.hwnd = GetHWND();
847 msg.message = message;
848 msg.wParam = w_param;
849 msg.lParam = l_param;
850 return GetInputMethod()->OnUntranslatedIMEMessage(msg, result);
853 void DesktopWindowTreeHostWin::HandleInputLanguageChange(
854 DWORD character_set,
855 HKL input_language_id) {
856 GetInputMethod()->OnInputLocaleChanged();
859 void DesktopWindowTreeHostWin::HandlePaintAccelerated(
860 const gfx::Rect& invalid_rect) {
861 if (compositor())
862 compositor()->ScheduleRedrawRect(invalid_rect);
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);
871 void DesktopWindowTreeHostWin::HandleMenuLoop(bool in_menu_loop) {
872 if (in_menu_loop) {
873 tooltip_disabler_.reset(
874 new aura::client::ScopedTooltipDisabler(window()));
875 } else {
876 tooltip_disabler_.reset();
880 bool DesktopWindowTreeHostWin::PreHandleMSG(UINT message,
881 WPARAM w_param,
882 LPARAM l_param,
883 LRESULT* result) {
884 return false;
887 void DesktopWindowTreeHostWin::PostHandleMSG(UINT message,
888 WPARAM w_param,
889 LPARAM l_param) {
892 bool DesktopWindowTreeHostWin::HandleScrollEvent(
893 const ui::ScrollEvent& event) {
894 SendEventToProcessor(const_cast<ui::ScrollEvent*>(&event));
895 return event.handled();
898 void DesktopWindowTreeHostWin::HandleWindowSizeChanging() {
899 if (compositor())
900 compositor()->DisableSwapUntilResize();
903 void DesktopWindowTreeHostWin::HandleWindowSizeChanged() {
904 // A resize may not have occurred if the window size happened not to have
905 // changed (can occur on Windows 10 when snapping a window to the side of
906 // the screen). In that case do a resize to the current size to reenable
907 // swaps.
908 if (compositor())
909 compositor()->SetScaleAndSize(compositor()->device_scale_factor(),
910 compositor()->size());
913 ////////////////////////////////////////////////////////////////////////////////
914 // DesktopWindowTreeHostWin, private:
916 Widget* DesktopWindowTreeHostWin::GetWidget() {
917 return native_widget_delegate_->AsWidget();
920 const Widget* DesktopWindowTreeHostWin::GetWidget() const {
921 return native_widget_delegate_->AsWidget();
924 HWND DesktopWindowTreeHostWin::GetHWND() const {
925 return message_handler_->hwnd();
928 void DesktopWindowTreeHostWin::SetWindowTransparency() {
929 bool transparent = ShouldUseNativeFrame() && !IsFullscreen();
930 compositor()->SetHostHasTransparentBackground(transparent);
931 window()->SetTransparent(transparent);
932 content_window_->SetTransparent(transparent);
935 bool DesktopWindowTreeHostWin::IsModalWindowActive() const {
936 // This function can get called during window creation which occurs before
937 // dispatcher() has been created.
938 if (!dispatcher())
939 return false;
941 aura::Window::Windows::const_iterator index;
942 for (index = window()->children().begin();
943 index != window()->children().end();
944 ++index) {
945 if ((*index)->GetProperty(aura::client::kModalKey) !=
946 ui:: MODAL_TYPE_NONE && (*index)->TargetVisibility())
947 return true;
949 return false;
952 ////////////////////////////////////////////////////////////////////////////////
953 // DesktopWindowTreeHost, public:
955 // static
956 DesktopWindowTreeHost* DesktopWindowTreeHost::Create(
957 internal::NativeWidgetDelegate* native_widget_delegate,
958 DesktopNativeWidgetAura* desktop_native_widget_aura) {
959 return new DesktopWindowTreeHostWin(native_widget_delegate,
960 desktop_native_widget_aura);
963 } // namespace views