Fix a long standing painting problem seen in the tabstrip on Windows Desktop Chrome.
[chromium-blink-merge.git] / ui / views / widget / desktop_aura / desktop_window_tree_host_win.cc
blob877e8d1ccb3e30491c326022d939acfcb466e75c
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/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"
43 namespace views {
45 namespace {
47 gfx::Size GetExpandedWindowSize(DWORD window_style, gfx::Size size) {
48 if (!(window_style & WS_EX_COMPOSITED) || !ui::win::IsAeroGlassEnabled())
49 return size;
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;
57 void InsetBottomRight(gfx::Rect* rect, gfx::Vector2d vector) {
58 rect->Inset(0, 0, vector.x(), vector.y());
61 } // namespace
63 DEFINE_WINDOW_PROPERTY_KEY(aura::Window*, kContentWindowForRootWindow, NULL);
65 // Identifies the DesktopWindowTreeHostWin associated with the
66 // WindowEventDispatcher.
67 DEFINE_WINDOW_PROPERTY_KEY(DesktopWindowTreeHostWin*, kDesktopWindowTreeHostKey,
68 NULL);
70 ////////////////////////////////////////////////////////////////////////////////
71 // DesktopWindowTreeHostWin, public:
73 bool DesktopWindowTreeHostWin::is_cursor_visible_ = true;
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) {
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();
95 // static
96 aura::Window* DesktopWindowTreeHostWin::GetContentWindowForHWND(HWND hwnd) {
97 aura::WindowTreeHost* host =
98 aura::WindowTreeHost::GetForAcceleratedWidget(hwnd);
99 return host ? host->window()->GetProperty(kContentWindowForRootWindow) : NULL;
102 // static
103 ui::NativeTheme* DesktopWindowTreeHost::GetNativeTheme(aura::Window* window) {
104 // Use NativeThemeWin for windows shown on the desktop, those not on the
105 // desktop come from Ash and get NativeThemeAura.
106 aura::WindowTreeHost* host = window ? window->GetHost() : NULL;
107 if (host) {
108 HWND host_hwnd = host->GetAcceleratedWidget();
109 if (host_hwnd &&
110 DesktopWindowTreeHostWin::GetContentWindowForHWND(host_hwnd)) {
111 return ui::NativeThemeWin::instance();
114 return ui::NativeThemeAura::instance();
117 ////////////////////////////////////////////////////////////////////////////////
118 // DesktopWindowTreeHostWin, DesktopWindowTreeHost implementation:
120 void DesktopWindowTreeHostWin::Init(aura::Window* content_window,
121 const Widget::InitParams& params) {
122 // TODO(beng): SetInitParams().
123 content_window_ = content_window;
125 aura::client::SetAnimationHost(content_window_, this);
127 ConfigureWindowStyles(message_handler_.get(), params,
128 GetWidget()->widget_delegate(),
129 native_widget_delegate_);
131 HWND parent_hwnd = NULL;
132 if (params.parent && params.parent->GetHost())
133 parent_hwnd = params.parent->GetHost()->GetAcceleratedWidget();
135 message_handler_->set_remove_standard_frame(params.remove_standard_frame);
137 has_non_client_view_ = Widget::RequiresNonClientView(params.type);
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));
146 CreateCompositor(GetAcceleratedWidget());
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();
157 window()->SetProperty(kContentWindowForRootWindow, content_window_);
158 window()->SetProperty(kDesktopWindowTreeHostKey, this);
160 should_animate_window_close_ =
161 content_window_->type() != ui::wm::WINDOW_TYPE_NORMAL &&
162 !wm::WindowAnimationsDisabled(content_window_);
164 // TODO this is not invoked *after* Init(), but should be ok.
165 SetWindowTransparency();
168 scoped_ptr<corewm::Tooltip> DesktopWindowTreeHostWin::CreateTooltip() {
169 DCHECK(!tooltip_);
170 tooltip_ = new corewm::TooltipWin(GetAcceleratedWidget());
171 return scoped_ptr<corewm::Tooltip>(tooltip_);
174 scoped_ptr<aura::client::DragDropClient>
175 DesktopWindowTreeHostWin::CreateDragDropClient(
176 DesktopNativeCursorManager* cursor_manager) {
177 drag_drop_client_ = new DesktopDragDropClientWin(window(), GetHWND());
178 return scoped_ptr<aura::client::DragDropClient>(drag_drop_client_).Pass();
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();
197 void DesktopWindowTreeHostWin::CloseNow() {
198 message_handler_->CloseNow();
201 aura::WindowTreeHost* DesktopWindowTreeHostWin::AsWindowTreeHost() {
202 return this;
205 void DesktopWindowTreeHostWin::ShowWindowWithState(
206 ui::WindowShowState show_state) {
207 message_handler_->ShowWindowWithState(show_state);
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);
216 bool DesktopWindowTreeHostWin::IsVisible() const {
217 return message_handler_->IsVisible();
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);
230 void DesktopWindowTreeHostWin::StackAtTop() {
231 message_handler_->StackAtTop();
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);
245 void DesktopWindowTreeHostWin::GetWindowPlacement(
246 gfx::Rect* bounds,
247 ui::WindowShowState* show_state) const {
248 message_handler_->GetWindowPlacement(bounds, show_state);
249 InsetBottomRight(bounds, window_enlargement_);
250 *bounds = gfx::win::ScreenToDIPRect(*bounds);
253 gfx::Rect DesktopWindowTreeHostWin::GetWindowBoundsInScreen() const {
254 gfx::Rect pixel_bounds = message_handler_->GetWindowBoundsInScreen();
255 InsetBottomRight(&pixel_bounds, window_enlargement_);
256 return gfx::win::ScreenToDIPRect(pixel_bounds);
259 gfx::Rect DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() const {
260 gfx::Rect pixel_bounds = message_handler_->GetClientAreaBoundsInScreen();
261 InsetBottomRight(&pixel_bounds, window_enlargement_);
262 return gfx::win::ScreenToDIPRect(pixel_bounds);
265 gfx::Rect DesktopWindowTreeHostWin::GetRestoredBounds() const {
266 gfx::Rect pixel_bounds = message_handler_->GetRestoredBounds();
267 InsetBottomRight(&pixel_bounds, window_enlargement_);
268 return gfx::win::ScreenToDIPRect(pixel_bounds);
271 gfx::Rect DesktopWindowTreeHostWin::GetWorkAreaBoundsInScreen() const {
272 MONITORINFO monitor_info;
273 monitor_info.cbSize = sizeof(monitor_info);
274 GetMonitorInfo(MonitorFromWindow(message_handler_->hwnd(),
275 MONITOR_DEFAULTTONEAREST),
276 &monitor_info);
277 gfx::Rect pixel_bounds = gfx::Rect(monitor_info.rcWork);
278 return gfx::win::ScreenToDIPRect(pixel_bounds);
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);
288 delete native_region;
291 void DesktopWindowTreeHostWin::Activate() {
292 message_handler_->Activate();
295 void DesktopWindowTreeHostWin::Deactivate() {
296 message_handler_->Deactivate();
299 bool DesktopWindowTreeHostWin::IsActive() const {
300 return message_handler_->IsActive();
303 void DesktopWindowTreeHostWin::Maximize() {
304 message_handler_->Maximize();
307 void DesktopWindowTreeHostWin::Minimize() {
308 message_handler_->Minimize();
311 void DesktopWindowTreeHostWin::Restore() {
312 message_handler_->Restore();
315 bool DesktopWindowTreeHostWin::IsMaximized() const {
316 return message_handler_->IsMaximized();
319 bool DesktopWindowTreeHostWin::IsMinimized() const {
320 return message_handler_->IsMinimized();
323 bool DesktopWindowTreeHostWin::HasCapture() const {
324 return message_handler_->HasCapture();
327 void DesktopWindowTreeHostWin::SetAlwaysOnTop(bool always_on_top) {
328 message_handler_->SetAlwaysOnTop(always_on_top);
331 bool DesktopWindowTreeHostWin::IsAlwaysOnTop() const {
332 return message_handler_->IsAlwaysOnTop();
335 void DesktopWindowTreeHostWin::SetVisibleOnAllWorkspaces(bool always_visible) {
336 // Windows does not have the concept of workspaces.
339 bool DesktopWindowTreeHostWin::SetWindowTitle(const base::string16& title) {
340 return message_handler_->SetTitle(title);
343 void DesktopWindowTreeHostWin::ClearNativeFocus() {
344 message_handler_->ClearNativeFocus();
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;
357 void DesktopWindowTreeHostWin::EndMoveLoop() {
358 message_handler_->EndMoveLoop();
361 void DesktopWindowTreeHostWin::SetVisibilityChangedAnimationsEnabled(
362 bool value) {
363 message_handler_->SetVisibilityChangedAnimationsEnabled(value);
364 content_window_->SetProperty(aura::client::kAnimationsDisabledKey, !value);
367 bool DesktopWindowTreeHostWin::ShouldUseNativeFrame() const {
368 return IsTranslucentWindowOpacitySupported();
371 bool DesktopWindowTreeHostWin::ShouldWindowContentsBeTransparent() const {
372 // If the window has a native frame, we assume it is an Aero Glass window, and
373 // is therefore transparent. Note: This is not equivalent to calling
374 // IsAeroGlassEnabled, because ShouldUseNativeFrame is overridden in a
375 // subclass.
376 return ShouldUseNativeFrame();
379 void DesktopWindowTreeHostWin::FrameTypeChanged() {
380 message_handler_->FrameTypeChanged();
381 SetWindowTransparency();
384 void DesktopWindowTreeHostWin::SetFullscreen(bool fullscreen) {
385 message_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();
394 bool DesktopWindowTreeHostWin::IsFullscreen() const {
395 return message_handler_->fullscreen_handler()->fullscreen();
398 void DesktopWindowTreeHostWin::SetOpacity(unsigned char opacity) {
399 message_handler_->SetOpacity(static_cast<BYTE>(opacity));
400 content_window_->layer()->SetOpacity(opacity / 255.0);
403 void DesktopWindowTreeHostWin::SetWindowIcons(
404 const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
405 message_handler_->SetWindowIcons(window_icon, app_icon);
408 void DesktopWindowTreeHostWin::InitModalType(ui::ModalType modal_type) {
409 message_handler_->InitModalType(modal_type);
412 void DesktopWindowTreeHostWin::FlashFrame(bool flash_frame) {
413 message_handler_->FlashFrame(flash_frame);
416 void DesktopWindowTreeHostWin::OnRootViewLayout() {
419 void DesktopWindowTreeHostWin::OnNativeWidgetFocus() {
420 // HWNDMessageHandler will perform the proper updating on its own.
423 void DesktopWindowTreeHostWin::OnNativeWidgetBlur() {
426 bool DesktopWindowTreeHostWin::IsAnimatingClosed() const {
427 return pending_close_;
430 bool DesktopWindowTreeHostWin::IsTranslucentWindowOpacitySupported() const {
431 return ui::win::IsAeroGlassEnabled();
434 ////////////////////////////////////////////////////////////////////////////////
435 // DesktopWindowTreeHostWin, WindowTreeHost implementation:
437 ui::EventSource* DesktopWindowTreeHostWin::GetEventSource() {
438 return this;
441 gfx::AcceleratedWidget DesktopWindowTreeHostWin::GetAcceleratedWidget() {
442 return message_handler_->hwnd();
445 void DesktopWindowTreeHostWin::Show() {
446 message_handler_->Show();
449 void DesktopWindowTreeHostWin::Hide() {
450 if (!pending_close_)
451 message_handler_->Hide();
454 // GetBounds and SetBounds work in pixel coordinates, whereas other get/set
455 // methods work in DIP.
457 gfx::Rect DesktopWindowTreeHostWin::GetBounds() const {
458 gfx::Rect bounds(message_handler_->GetClientAreaBounds());
459 // If the window bounds were expanded we need to return the original bounds
460 // To achieve this we do the reverse of the expansion, i.e. add the
461 // window_expansion_top_left_delta_ to the origin and subtract the
462 // window_expansion_bottom_right_delta_ from the width and height.
463 gfx::Rect without_expansion(
464 bounds.x() + window_expansion_top_left_delta_.x(),
465 bounds.y() + window_expansion_top_left_delta_.y(),
466 bounds.width() - window_expansion_bottom_right_delta_.x() -
467 window_enlargement_.x(),
468 bounds.height() - window_expansion_bottom_right_delta_.y() -
469 window_enlargement_.y());
470 return without_expansion;
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();
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());
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());
496 gfx::Point DesktopWindowTreeHostWin::GetLocationOnNativeScreen() const {
497 return GetBounds().origin();
500 void DesktopWindowTreeHostWin::SetCapture() {
501 message_handler_->SetCapture();
504 void DesktopWindowTreeHostWin::ReleaseCapture() {
505 message_handler_->ReleaseCapture();
508 void DesktopWindowTreeHostWin::PostNativeEvent(
509 const base::NativeEvent& native_event) {
512 void DesktopWindowTreeHostWin::SetCursorNative(gfx::NativeCursor cursor) {
513 ui::CursorLoaderWin cursor_loader;
514 cursor_loader.SetPlatformCursor(&cursor);
516 message_handler_->SetCursor(cursor.platform());
519 void DesktopWindowTreeHostWin::OnCursorVisibilityChangedNative(bool show) {
520 if (is_cursor_visible_ == show)
521 return;
522 is_cursor_visible_ = show;
523 ::ShowCursor(!!show);
526 void DesktopWindowTreeHostWin::MoveCursorToNative(const gfx::Point& location) {
527 POINT cursor_location = location.ToPOINT();
528 ::ClientToScreen(GetHWND(), &cursor_location);
529 ::SetCursorPos(cursor_location.x, cursor_location.y);
532 ////////////////////////////////////////////////////////////////////////////////
533 // DesktopWindowTreeHostWin, ui::EventSource implementation:
535 ui::EventProcessor* DesktopWindowTreeHostWin::GetEventProcessor() {
536 return dispatcher();
539 ////////////////////////////////////////////////////////////////////////////////
540 // DesktopWindowTreeHostWin, aura::AnimationHost implementation:
542 void DesktopWindowTreeHostWin::SetHostTransitionOffsets(
543 const gfx::Vector2d& top_left_delta,
544 const gfx::Vector2d& bottom_right_delta) {
545 gfx::Rect bounds_without_expansion = GetBounds();
546 window_expansion_top_left_delta_ = top_left_delta;
547 window_expansion_bottom_right_delta_ = bottom_right_delta;
548 SetBounds(bounds_without_expansion);
551 void DesktopWindowTreeHostWin::OnWindowHidingAnimationCompleted() {
552 if (pending_close_)
553 message_handler_->Close();
556 ////////////////////////////////////////////////////////////////////////////////
557 // DesktopWindowTreeHostWin, HWNDMessageHandlerDelegate implementation:
559 bool DesktopWindowTreeHostWin::IsWidgetWindow() const {
560 return has_non_client_view_;
563 bool DesktopWindowTreeHostWin::IsUsingCustomFrame() const {
564 return !GetWidget()->ShouldUseNativeFrame();
567 void DesktopWindowTreeHostWin::SchedulePaint() {
568 GetWidget()->GetRootView()->SchedulePaint();
571 void DesktopWindowTreeHostWin::EnableInactiveRendering() {
572 native_widget_delegate_->EnableInactiveRendering();
575 bool DesktopWindowTreeHostWin::IsInactiveRenderingDisabled() {
576 return native_widget_delegate_->IsInactiveRenderingDisabled();
579 bool DesktopWindowTreeHostWin::CanResize() const {
580 return GetWidget()->widget_delegate()->CanResize();
583 bool DesktopWindowTreeHostWin::CanMaximize() const {
584 return GetWidget()->widget_delegate()->CanMaximize();
587 bool DesktopWindowTreeHostWin::CanActivate() const {
588 if (IsModalWindowActive())
589 return true;
590 return native_widget_delegate_->CanActivate();
593 bool DesktopWindowTreeHostWin::WidgetSizeIsClientSize() const {
594 const Widget* widget = GetWidget()->GetTopLevelWidget();
595 return IsMaximized() || (widget && widget->ShouldUseNativeFrame());
598 bool DesktopWindowTreeHostWin::IsModal() const {
599 return native_widget_delegate_->IsModal();
602 int DesktopWindowTreeHostWin::GetInitialShowState() const {
603 return CanActivate() ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
606 bool DesktopWindowTreeHostWin::WillProcessWorkAreaChange() const {
607 return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
610 int DesktopWindowTreeHostWin::GetNonClientComponent(
611 const gfx::Point& point) const {
612 gfx::Point dip_position = gfx::win::ScreenToDIPPoint(point);
613 return native_widget_delegate_->GetNonClientComponent(dip_position);
616 void DesktopWindowTreeHostWin::GetWindowMask(const gfx::Size& size,
617 gfx::Path* path) {
618 if (GetWidget()->non_client_view()) {
619 GetWidget()->non_client_view()->GetWindowMask(size, path);
620 } else if (!window_enlargement_.IsZero()) {
621 gfx::Rect bounds(WidgetSizeIsClientSize()
622 ? message_handler_->GetClientAreaBoundsInScreen()
623 : message_handler_->GetWindowBoundsInScreen());
624 InsetBottomRight(&bounds, window_enlargement_);
625 path->addRect(SkRect::MakeXYWH(0, 0, bounds.width(), bounds.height()));
629 bool DesktopWindowTreeHostWin::GetClientAreaInsets(gfx::Insets* insets) const {
630 return false;
633 void DesktopWindowTreeHostWin::GetMinMaxSize(gfx::Size* min_size,
634 gfx::Size* max_size) const {
635 *min_size = native_widget_delegate_->GetMinimumSize();
636 *max_size = native_widget_delegate_->GetMaximumSize();
639 gfx::Size DesktopWindowTreeHostWin::GetRootViewSize() const {
640 return GetWidget()->GetRootView()->size();
643 void DesktopWindowTreeHostWin::ResetWindowControls() {
644 GetWidget()->non_client_view()->ResetWindowControls();
647 void DesktopWindowTreeHostWin::PaintLayeredWindow(gfx::Canvas* canvas) {
648 GetWidget()->GetRootView()->Paint(canvas, views::CullSet());
651 gfx::NativeViewAccessible DesktopWindowTreeHostWin::GetNativeViewAccessible() {
652 return GetWidget()->GetRootView()->GetNativeViewAccessible();
655 InputMethod* DesktopWindowTreeHostWin::GetInputMethod() {
656 return GetWidget()->GetInputMethodDirect();
659 bool DesktopWindowTreeHostWin::ShouldHandleSystemCommands() const {
660 return GetWidget()->widget_delegate()->ShouldHandleSystemCommands();
663 void DesktopWindowTreeHostWin::HandleAppDeactivated() {
664 native_widget_delegate_->EnableInactiveRendering();
667 void DesktopWindowTreeHostWin::HandleActivationChanged(bool active) {
668 // This can be invoked from HWNDMessageHandler::Init(), at which point we're
669 // not in a good state and need to ignore it.
670 // TODO(beng): Do we need this still now the host owns the dispatcher?
671 if (!dispatcher())
672 return;
674 if (active)
675 OnHostActivated();
676 desktop_native_widget_aura_->HandleActivationChanged(active);
679 bool DesktopWindowTreeHostWin::HandleAppCommand(short command) {
680 // We treat APPCOMMAND ids as an extension of our command namespace, and just
681 // let the delegate figure out what to do...
682 return GetWidget()->widget_delegate() &&
683 GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
686 void DesktopWindowTreeHostWin::HandleCancelMode() {
687 dispatcher()->DispatchCancelModeEvent();
690 void DesktopWindowTreeHostWin::HandleCaptureLost() {
691 OnHostLostWindowCapture();
694 void DesktopWindowTreeHostWin::HandleClose() {
695 GetWidget()->Close();
698 bool DesktopWindowTreeHostWin::HandleCommand(int command) {
699 return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
702 void DesktopWindowTreeHostWin::HandleAccelerator(
703 const ui::Accelerator& accelerator) {
704 GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator);
707 void DesktopWindowTreeHostWin::HandleCreate() {
708 native_widget_delegate_->OnNativeWidgetCreated(true);
711 void DesktopWindowTreeHostWin::HandleDestroying() {
712 drag_drop_client_->OnNativeWidgetDestroying(GetHWND());
713 native_widget_delegate_->OnNativeWidgetDestroying();
715 // Destroy the compositor before destroying the HWND since shutdown
716 // may try to swap to the window.
717 DestroyCompositor();
720 void DesktopWindowTreeHostWin::HandleDestroyed() {
721 desktop_native_widget_aura_->OnHostClosed();
724 bool DesktopWindowTreeHostWin::HandleInitialFocus(
725 ui::WindowShowState show_state) {
726 return GetWidget()->SetInitialFocus(show_state);
729 void DesktopWindowTreeHostWin::HandleDisplayChange() {
730 GetWidget()->widget_delegate()->OnDisplayChanged();
733 void DesktopWindowTreeHostWin::HandleBeginWMSizeMove() {
734 native_widget_delegate_->OnNativeWidgetBeginUserBoundsChange();
737 void DesktopWindowTreeHostWin::HandleEndWMSizeMove() {
738 native_widget_delegate_->OnNativeWidgetEndUserBoundsChange();
741 void DesktopWindowTreeHostWin::HandleMove() {
742 native_widget_delegate_->OnNativeWidgetMove();
743 OnHostMoved(GetBounds().origin());
746 void DesktopWindowTreeHostWin::HandleWorkAreaChanged() {
747 GetWidget()->widget_delegate()->OnWorkAreaChanged();
750 void DesktopWindowTreeHostWin::HandleVisibilityChanging(bool visible) {
751 native_widget_delegate_->OnNativeWidgetVisibilityChanging(visible);
754 void DesktopWindowTreeHostWin::HandleVisibilityChanged(bool visible) {
755 native_widget_delegate_->OnNativeWidgetVisibilityChanged(visible);
758 void DesktopWindowTreeHostWin::HandleClientSizeChanged(
759 const gfx::Size& new_size) {
760 if (dispatcher())
761 OnHostResized(new_size);
764 void DesktopWindowTreeHostWin::HandleFrameChanged() {
765 SetWindowTransparency();
766 // Replace the frame and layout the contents.
767 GetWidget()->non_client_view()->UpdateFrame();
770 void DesktopWindowTreeHostWin::HandleNativeFocus(HWND last_focused_window) {
771 // TODO(beng): inform the native_widget_delegate_.
772 InputMethod* input_method = GetInputMethod();
773 if (input_method)
774 input_method->OnFocus();
777 void DesktopWindowTreeHostWin::HandleNativeBlur(HWND focused_window) {
778 // TODO(beng): inform the native_widget_delegate_.
779 InputMethod* input_method = GetInputMethod();
780 if (input_method)
781 input_method->OnBlur();
784 bool DesktopWindowTreeHostWin::HandleMouseEvent(const ui::MouseEvent& event) {
785 SendEventToProcessor(const_cast<ui::MouseEvent*>(&event));
786 return event.handled();
789 bool DesktopWindowTreeHostWin::HandleKeyEvent(const ui::KeyEvent& event) {
790 return false;
793 bool DesktopWindowTreeHostWin::HandleUntranslatedKeyEvent(
794 const ui::KeyEvent& event) {
795 ui::KeyEvent duplicate_event(event);
796 SendEventToProcessor(&duplicate_event);
797 return duplicate_event.handled();
800 void DesktopWindowTreeHostWin::HandleTouchEvent(
801 const ui::TouchEvent& event) {
802 // HWNDMessageHandler asynchronously processes touch events. Because of this
803 // it's possible for the aura::WindowEventDispatcher to have been destroyed
804 // by the time we attempt to process them.
805 if (!GetWidget()->GetNativeView())
806 return;
808 // Currently we assume the window that has capture gets touch events too.
809 aura::WindowTreeHost* host =
810 aura::WindowTreeHost::GetForAcceleratedWidget(GetCapture());
811 if (host) {
812 DesktopWindowTreeHostWin* target =
813 host->window()->GetProperty(kDesktopWindowTreeHostKey);
814 if (target && target->HasCapture() && target != this) {
815 POINT target_location(event.location().ToPOINT());
816 ClientToScreen(GetHWND(), &target_location);
817 ScreenToClient(target->GetHWND(), &target_location);
818 ui::TouchEvent target_event(event, static_cast<View*>(NULL),
819 static_cast<View*>(NULL));
820 target_event.set_location(gfx::Point(target_location));
821 target_event.set_root_location(target_event.location());
822 target->SendEventToProcessor(&target_event);
823 return;
826 SendEventToProcessor(const_cast<ui::TouchEvent*>(&event));
829 bool DesktopWindowTreeHostWin::HandleIMEMessage(UINT message,
830 WPARAM w_param,
831 LPARAM l_param,
832 LRESULT* result) {
833 MSG msg = {};
834 msg.hwnd = GetHWND();
835 msg.message = message;
836 msg.wParam = w_param;
837 msg.lParam = l_param;
838 return desktop_native_widget_aura_->input_method_event_filter()->
839 input_method()->OnUntranslatedIMEMessage(msg, result);
842 void DesktopWindowTreeHostWin::HandleInputLanguageChange(
843 DWORD character_set,
844 HKL input_language_id) {
845 desktop_native_widget_aura_->input_method_event_filter()->
846 input_method()->OnInputLocaleChanged();
849 bool DesktopWindowTreeHostWin::HandlePaintAccelerated(
850 const gfx::Rect& invalid_rect) {
851 return native_widget_delegate_->OnNativeWidgetPaintAccelerated(invalid_rect);
854 void DesktopWindowTreeHostWin::HandlePaint(gfx::Canvas* canvas) {
855 // It appears possible to get WM_PAINT after WM_DESTROY.
856 if (compositor())
857 compositor()->ScheduleRedrawRect(gfx::Rect());
860 bool DesktopWindowTreeHostWin::HandleTooltipNotify(int w_param,
861 NMHDR* l_param,
862 LRESULT* l_result) {
863 return tooltip_ && tooltip_->HandleNotify(w_param, l_param, l_result);
866 void DesktopWindowTreeHostWin::HandleMenuLoop(bool in_menu_loop) {
867 if (in_menu_loop) {
868 tooltip_disabler_.reset(
869 new aura::client::ScopedTooltipDisabler(window()));
870 } else {
871 tooltip_disabler_.reset();
875 bool DesktopWindowTreeHostWin::PreHandleMSG(UINT message,
876 WPARAM w_param,
877 LPARAM l_param,
878 LRESULT* result) {
879 return false;
882 void DesktopWindowTreeHostWin::PostHandleMSG(UINT message,
883 WPARAM w_param,
884 LPARAM l_param) {
887 bool DesktopWindowTreeHostWin::HandleScrollEvent(
888 const ui::ScrollEvent& event) {
889 SendEventToProcessor(const_cast<ui::ScrollEvent*>(&event));
890 return event.handled();
893 void DesktopWindowTreeHostWin::HandleWindowSizeChanging() {
894 if (compositor())
895 compositor()->FinishAllRendering();
898 ////////////////////////////////////////////////////////////////////////////////
899 // DesktopWindowTreeHostWin, private:
901 Widget* DesktopWindowTreeHostWin::GetWidget() {
902 return native_widget_delegate_->AsWidget();
905 const Widget* DesktopWindowTreeHostWin::GetWidget() const {
906 return native_widget_delegate_->AsWidget();
909 HWND DesktopWindowTreeHostWin::GetHWND() const {
910 return message_handler_->hwnd();
913 void DesktopWindowTreeHostWin::SetWindowTransparency() {
914 bool transparent = ShouldUseNativeFrame() && !IsFullscreen();
915 compositor()->SetHostHasTransparentBackground(transparent);
916 window()->SetTransparent(transparent);
917 content_window_->SetTransparent(transparent);
920 bool DesktopWindowTreeHostWin::IsModalWindowActive() const {
921 // This function can get called during window creation which occurs before
922 // dispatcher() has been created.
923 if (!dispatcher())
924 return false;
926 aura::Window::Windows::const_iterator index;
927 for (index = window()->children().begin();
928 index != window()->children().end();
929 ++index) {
930 if ((*index)->GetProperty(aura::client::kModalKey) !=
931 ui:: MODAL_TYPE_NONE && (*index)->TargetVisibility())
932 return true;
934 return false;
937 ////////////////////////////////////////////////////////////////////////////////
938 // DesktopWindowTreeHost, public:
940 // static
941 DesktopWindowTreeHost* DesktopWindowTreeHost::Create(
942 internal::NativeWidgetDelegate* native_widget_delegate,
943 DesktopNativeWidgetAura* desktop_native_widget_aura) {
944 return new DesktopWindowTreeHostWin(native_widget_delegate,
945 desktop_native_widget_aura);
948 } // namespace views