Add ability for NetLogLogger to gather data from more than just NetLog
[chromium-blink-merge.git] / ui / views / widget / desktop_aura / desktop_window_tree_host_win.cc
blobb54a643e88fa4653aecec5804996a0916739f119
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/geometry/insets.h"
20 #include "ui/gfx/geometry/vector2d.h"
21 #include "ui/gfx/native_widget_types.h"
22 #include "ui/gfx/path.h"
23 #include "ui/gfx/path_win.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 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, 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),
89 need_synchronous_paint_(false),
90 in_sizing_loop_(false) {
93 DesktopWindowTreeHostWin::~DesktopWindowTreeHostWin() {
94 // WARNING: |content_window_| has been destroyed by the time we get here.
95 desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this);
96 DestroyDispatcher();
99 // static
100 aura::Window* DesktopWindowTreeHostWin::GetContentWindowForHWND(HWND hwnd) {
101 aura::WindowTreeHost* host =
102 aura::WindowTreeHost::GetForAcceleratedWidget(hwnd);
103 return host ? host->window()->GetProperty(kContentWindowForRootWindow) : NULL;
106 // static
107 ui::NativeTheme* DesktopWindowTreeHost::GetNativeTheme(aura::Window* window) {
108 // Use NativeThemeWin for windows shown on the desktop, those not on the
109 // desktop come from Ash and get NativeThemeAura.
110 aura::WindowTreeHost* host = window ? window->GetHost() : NULL;
111 if (host) {
112 HWND host_hwnd = host->GetAcceleratedWidget();
113 if (host_hwnd &&
114 DesktopWindowTreeHostWin::GetContentWindowForHWND(host_hwnd)) {
115 return ui::NativeThemeWin::instance();
118 return ui::NativeThemeAura::instance();
121 ////////////////////////////////////////////////////////////////////////////////
122 // DesktopWindowTreeHostWin, DesktopWindowTreeHost implementation:
124 void DesktopWindowTreeHostWin::Init(aura::Window* content_window,
125 const Widget::InitParams& params) {
126 // TODO(beng): SetInitParams().
127 content_window_ = content_window;
129 aura::client::SetAnimationHost(content_window_, this);
131 ConfigureWindowStyles(message_handler_.get(), params,
132 GetWidget()->widget_delegate(),
133 native_widget_delegate_);
135 HWND parent_hwnd = NULL;
136 if (params.parent && params.parent->GetHost())
137 parent_hwnd = params.parent->GetHost()->GetAcceleratedWidget();
139 message_handler_->set_remove_standard_frame(params.remove_standard_frame);
141 has_non_client_view_ = Widget::RequiresNonClientView(params.type);
143 gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(params.bounds);
144 message_handler_->Init(parent_hwnd, pixel_bounds);
145 if (params.type == Widget::InitParams::TYPE_MENU) {
146 ::SetProp(GetAcceleratedWidget(),
147 kForceSoftwareCompositor,
148 reinterpret_cast<HANDLE>(true));
150 CreateCompositor(GetAcceleratedWidget());
153 void DesktopWindowTreeHostWin::OnNativeWidgetCreated(
154 const Widget::InitParams& params) {
155 // The cursor is not necessarily visible when the root window is created.
156 aura::client::CursorClient* cursor_client =
157 aura::client::GetCursorClient(window());
158 if (cursor_client)
159 is_cursor_visible_ = cursor_client->IsCursorVisible();
161 window()->SetProperty(kContentWindowForRootWindow, content_window_);
162 window()->SetProperty(kDesktopWindowTreeHostKey, this);
164 should_animate_window_close_ =
165 content_window_->type() != ui::wm::WINDOW_TYPE_NORMAL &&
166 !wm::WindowAnimationsDisabled(content_window_);
168 // TODO this is not invoked *after* Init(), but should be ok.
169 SetWindowTransparency();
172 scoped_ptr<corewm::Tooltip> DesktopWindowTreeHostWin::CreateTooltip() {
173 DCHECK(!tooltip_);
174 tooltip_ = new corewm::TooltipWin(GetAcceleratedWidget());
175 return make_scoped_ptr(tooltip_);
178 scoped_ptr<aura::client::DragDropClient>
179 DesktopWindowTreeHostWin::CreateDragDropClient(
180 DesktopNativeCursorManager* cursor_manager) {
181 drag_drop_client_ = new DesktopDragDropClientWin(window(), GetHWND());
182 return make_scoped_ptr(drag_drop_client_);
185 void DesktopWindowTreeHostWin::Close() {
186 // TODO(beng): Move this entire branch to DNWA so it can be shared with X11.
187 if (should_animate_window_close_) {
188 pending_close_ = true;
189 const bool is_animating =
190 content_window_->layer()->GetAnimator()->IsAnimatingProperty(
191 ui::LayerAnimationElement::VISIBILITY);
192 // Animation may not start for a number of reasons.
193 if (!is_animating)
194 message_handler_->Close();
195 // else case, OnWindowHidingAnimationCompleted does the actual Close.
196 } else {
197 message_handler_->Close();
201 void DesktopWindowTreeHostWin::CloseNow() {
202 message_handler_->CloseNow();
205 aura::WindowTreeHost* DesktopWindowTreeHostWin::AsWindowTreeHost() {
206 return this;
209 void DesktopWindowTreeHostWin::ShowWindowWithState(
210 ui::WindowShowState show_state) {
211 message_handler_->ShowWindowWithState(show_state);
214 void DesktopWindowTreeHostWin::ShowMaximizedWithBounds(
215 const gfx::Rect& restored_bounds) {
216 gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(restored_bounds);
217 message_handler_->ShowMaximizedWithBounds(pixel_bounds);
220 bool DesktopWindowTreeHostWin::IsVisible() const {
221 return message_handler_->IsVisible();
224 void DesktopWindowTreeHostWin::SetSize(const gfx::Size& size) {
225 gfx::Size size_in_pixels = gfx::win::DIPToScreenSize(size);
226 gfx::Size expanded = GetExpandedWindowSize(
227 message_handler_->window_ex_style(), size_in_pixels);
228 window_enlargement_ =
229 gfx::Vector2d(expanded.width() - size_in_pixels.width(),
230 expanded.height() - size_in_pixels.height());
231 message_handler_->SetSize(expanded);
234 void DesktopWindowTreeHostWin::StackAtTop() {
235 message_handler_->StackAtTop();
238 void DesktopWindowTreeHostWin::CenterWindow(const gfx::Size& size) {
239 gfx::Size size_in_pixels = gfx::win::DIPToScreenSize(size);
240 gfx::Size expanded_size;
241 expanded_size = GetExpandedWindowSize(message_handler_->window_ex_style(),
242 size_in_pixels);
243 window_enlargement_ =
244 gfx::Vector2d(expanded_size.width() - size_in_pixels.width(),
245 expanded_size.height() - size_in_pixels.height());
246 message_handler_->CenterWindow(expanded_size);
249 void DesktopWindowTreeHostWin::GetWindowPlacement(
250 gfx::Rect* bounds,
251 ui::WindowShowState* show_state) const {
252 message_handler_->GetWindowPlacement(bounds, show_state);
253 InsetBottomRight(bounds, window_enlargement_);
254 *bounds = gfx::win::ScreenToDIPRect(*bounds);
257 gfx::Rect DesktopWindowTreeHostWin::GetWindowBoundsInScreen() const {
258 gfx::Rect pixel_bounds = message_handler_->GetWindowBoundsInScreen();
259 InsetBottomRight(&pixel_bounds, window_enlargement_);
260 return gfx::win::ScreenToDIPRect(pixel_bounds);
263 gfx::Rect DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() const {
264 gfx::Rect pixel_bounds = message_handler_->GetClientAreaBoundsInScreen();
265 InsetBottomRight(&pixel_bounds, window_enlargement_);
266 return gfx::win::ScreenToDIPRect(pixel_bounds);
269 gfx::Rect DesktopWindowTreeHostWin::GetRestoredBounds() const {
270 gfx::Rect pixel_bounds = message_handler_->GetRestoredBounds();
271 InsetBottomRight(&pixel_bounds, window_enlargement_);
272 return gfx::win::ScreenToDIPRect(pixel_bounds);
275 gfx::Rect DesktopWindowTreeHostWin::GetWorkAreaBoundsInScreen() const {
276 MONITORINFO monitor_info;
277 monitor_info.cbSize = sizeof(monitor_info);
278 GetMonitorInfo(MonitorFromWindow(message_handler_->hwnd(),
279 MONITOR_DEFAULTTONEAREST),
280 &monitor_info);
281 gfx::Rect pixel_bounds = gfx::Rect(monitor_info.rcWork);
282 return gfx::win::ScreenToDIPRect(pixel_bounds);
285 void DesktopWindowTreeHostWin::SetShape(gfx::NativeRegion native_region) {
286 if (native_region) {
287 // TODO(wez): This would be a lot simpler if we were passed an SkPath.
288 // See crbug.com/410593.
289 gfx::NativeRegion shape = native_region;
290 SkRegion device_region;
291 if (gfx::GetDPIScale() > 1.0) {
292 shape = &device_region;
293 const float& scale = gfx::GetDPIScale();
294 std::vector<SkIRect> rects;
295 for (SkRegion::Iterator it(*native_region); !it.done(); it.next()) {
296 const SkIRect& rect = it.rect();
297 SkRect scaled_rect =
298 SkRect::MakeLTRB(rect.left() * scale, rect.top() * scale,
299 rect.right() * scale, rect.bottom() * scale);
300 SkIRect rounded_scaled_rect;
301 scaled_rect.roundOut(&rounded_scaled_rect);
302 rects.push_back(rounded_scaled_rect);
304 if (!rects.empty())
305 device_region.setRects(&rects[0], rects.size());
308 message_handler_->SetRegion(gfx::CreateHRGNFromSkRegion(*shape));
309 } else {
310 message_handler_->SetRegion(NULL);
313 delete native_region;
316 void DesktopWindowTreeHostWin::Activate() {
317 message_handler_->Activate();
320 void DesktopWindowTreeHostWin::Deactivate() {
321 message_handler_->Deactivate();
324 bool DesktopWindowTreeHostWin::IsActive() const {
325 return message_handler_->IsActive();
328 void DesktopWindowTreeHostWin::Maximize() {
329 message_handler_->Maximize();
332 void DesktopWindowTreeHostWin::Minimize() {
333 message_handler_->Minimize();
336 void DesktopWindowTreeHostWin::Restore() {
337 message_handler_->Restore();
340 bool DesktopWindowTreeHostWin::IsMaximized() const {
341 return message_handler_->IsMaximized();
344 bool DesktopWindowTreeHostWin::IsMinimized() const {
345 return message_handler_->IsMinimized();
348 bool DesktopWindowTreeHostWin::HasCapture() const {
349 return message_handler_->HasCapture();
352 void DesktopWindowTreeHostWin::SetAlwaysOnTop(bool always_on_top) {
353 message_handler_->SetAlwaysOnTop(always_on_top);
356 bool DesktopWindowTreeHostWin::IsAlwaysOnTop() const {
357 return message_handler_->IsAlwaysOnTop();
360 void DesktopWindowTreeHostWin::SetVisibleOnAllWorkspaces(bool always_visible) {
361 // Windows does not have the concept of workspaces.
364 bool DesktopWindowTreeHostWin::SetWindowTitle(const base::string16& title) {
365 return message_handler_->SetTitle(title);
368 void DesktopWindowTreeHostWin::ClearNativeFocus() {
369 message_handler_->ClearNativeFocus();
372 Widget::MoveLoopResult DesktopWindowTreeHostWin::RunMoveLoop(
373 const gfx::Vector2d& drag_offset,
374 Widget::MoveLoopSource source,
375 Widget::MoveLoopEscapeBehavior escape_behavior) {
376 const bool hide_on_escape =
377 escape_behavior == Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_HIDE;
378 return message_handler_->RunMoveLoop(drag_offset, hide_on_escape) ?
379 Widget::MOVE_LOOP_SUCCESSFUL : Widget::MOVE_LOOP_CANCELED;
382 void DesktopWindowTreeHostWin::EndMoveLoop() {
383 message_handler_->EndMoveLoop();
386 void DesktopWindowTreeHostWin::SetVisibilityChangedAnimationsEnabled(
387 bool value) {
388 message_handler_->SetVisibilityChangedAnimationsEnabled(value);
389 content_window_->SetProperty(aura::client::kAnimationsDisabledKey, !value);
392 bool DesktopWindowTreeHostWin::ShouldUseNativeFrame() const {
393 return IsTranslucentWindowOpacitySupported();
396 bool DesktopWindowTreeHostWin::ShouldWindowContentsBeTransparent() const {
397 // If the window has a native frame, we assume it is an Aero Glass window, and
398 // is therefore transparent. Note: This is not equivalent to calling
399 // IsAeroGlassEnabled, because ShouldUseNativeFrame is overridden in a
400 // subclass.
401 return ShouldUseNativeFrame();
404 void DesktopWindowTreeHostWin::FrameTypeChanged() {
405 message_handler_->FrameTypeChanged();
406 SetWindowTransparency();
409 void DesktopWindowTreeHostWin::SetFullscreen(bool fullscreen) {
410 message_handler_->SetFullscreen(fullscreen);
411 // TODO(sky): workaround for ScopedFullscreenVisibility showing window
412 // directly. Instead of this should listen for visibility changes and then
413 // update window.
414 if (message_handler_->IsVisible() && !content_window_->TargetVisibility())
415 content_window_->Show();
416 SetWindowTransparency();
419 bool DesktopWindowTreeHostWin::IsFullscreen() const {
420 return message_handler_->fullscreen_handler()->fullscreen();
423 void DesktopWindowTreeHostWin::SetOpacity(unsigned char opacity) {
424 message_handler_->SetOpacity(static_cast<BYTE>(opacity));
425 content_window_->layer()->SetOpacity(opacity / 255.0);
428 void DesktopWindowTreeHostWin::SetWindowIcons(
429 const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
430 message_handler_->SetWindowIcons(window_icon, app_icon);
433 void DesktopWindowTreeHostWin::InitModalType(ui::ModalType modal_type) {
434 message_handler_->InitModalType(modal_type);
437 void DesktopWindowTreeHostWin::FlashFrame(bool flash_frame) {
438 message_handler_->FlashFrame(flash_frame);
441 void DesktopWindowTreeHostWin::OnRootViewLayout() {
444 void DesktopWindowTreeHostWin::OnNativeWidgetFocus() {
445 // HWNDMessageHandler will perform the proper updating on its own.
448 void DesktopWindowTreeHostWin::OnNativeWidgetBlur() {
451 bool DesktopWindowTreeHostWin::IsAnimatingClosed() const {
452 return pending_close_;
455 bool DesktopWindowTreeHostWin::IsTranslucentWindowOpacitySupported() const {
456 return ui::win::IsAeroGlassEnabled();
459 void DesktopWindowTreeHostWin::SizeConstraintsChanged() {
460 message_handler_->SizeConstraintsChanged();
463 ////////////////////////////////////////////////////////////////////////////////
464 // DesktopWindowTreeHostWin, WindowTreeHost implementation:
466 ui::EventSource* DesktopWindowTreeHostWin::GetEventSource() {
467 return this;
470 gfx::AcceleratedWidget DesktopWindowTreeHostWin::GetAcceleratedWidget() {
471 return message_handler_->hwnd();
474 void DesktopWindowTreeHostWin::Show() {
475 message_handler_->Show();
478 void DesktopWindowTreeHostWin::Hide() {
479 if (!pending_close_)
480 message_handler_->Hide();
483 // GetBounds and SetBounds work in pixel coordinates, whereas other get/set
484 // methods work in DIP.
486 gfx::Rect DesktopWindowTreeHostWin::GetBounds() const {
487 gfx::Rect bounds(message_handler_->GetClientAreaBounds());
488 // If the window bounds were expanded we need to return the original bounds
489 // To achieve this we do the reverse of the expansion, i.e. add the
490 // window_expansion_top_left_delta_ to the origin and subtract the
491 // window_expansion_bottom_right_delta_ from the width and height.
492 gfx::Rect without_expansion(
493 bounds.x() + window_expansion_top_left_delta_.x(),
494 bounds.y() + window_expansion_top_left_delta_.y(),
495 bounds.width() - window_expansion_bottom_right_delta_.x() -
496 window_enlargement_.x(),
497 bounds.height() - window_expansion_bottom_right_delta_.y() -
498 window_enlargement_.y());
499 return without_expansion;
502 void DesktopWindowTreeHostWin::SetBounds(const gfx::Rect& bounds) {
503 // If the window bounds have to be expanded we need to subtract the
504 // window_expansion_top_left_delta_ from the origin and add the
505 // window_expansion_bottom_right_delta_ to the width and height
506 gfx::Size old_hwnd_size(message_handler_->GetClientAreaBounds().size());
507 gfx::Size old_content_size = GetBounds().size();
509 gfx::Rect expanded(
510 bounds.x() - window_expansion_top_left_delta_.x(),
511 bounds.y() - window_expansion_top_left_delta_.y(),
512 bounds.width() + window_expansion_bottom_right_delta_.x(),
513 bounds.height() + window_expansion_bottom_right_delta_.y());
515 gfx::Rect new_expanded(
516 expanded.origin(),
517 GetExpandedWindowSize(message_handler_->window_ex_style(),
518 expanded.size()));
519 window_enlargement_ =
520 gfx::Vector2d(new_expanded.width() - expanded.width(),
521 new_expanded.height() - expanded.height());
522 message_handler_->SetBounds(new_expanded, old_content_size != bounds.size());
525 gfx::Point DesktopWindowTreeHostWin::GetLocationOnNativeScreen() const {
526 return GetBounds().origin();
529 void DesktopWindowTreeHostWin::SetCapture() {
530 message_handler_->SetCapture();
533 void DesktopWindowTreeHostWin::ReleaseCapture() {
534 message_handler_->ReleaseCapture();
537 void DesktopWindowTreeHostWin::SetCursorNative(gfx::NativeCursor cursor) {
538 ui::CursorLoaderWin cursor_loader;
539 cursor_loader.SetPlatformCursor(&cursor);
541 message_handler_->SetCursor(cursor.platform());
544 void DesktopWindowTreeHostWin::OnCursorVisibilityChangedNative(bool show) {
545 if (is_cursor_visible_ == show)
546 return;
547 is_cursor_visible_ = show;
548 ::ShowCursor(!!show);
551 void DesktopWindowTreeHostWin::MoveCursorToNative(const gfx::Point& location) {
552 POINT cursor_location = location.ToPOINT();
553 ::ClientToScreen(GetHWND(), &cursor_location);
554 ::SetCursorPos(cursor_location.x, cursor_location.y);
557 ////////////////////////////////////////////////////////////////////////////////
558 // DesktopWindowTreeHostWin, ui::EventSource implementation:
560 ui::EventProcessor* DesktopWindowTreeHostWin::GetEventProcessor() {
561 return dispatcher();
564 ////////////////////////////////////////////////////////////////////////////////
565 // DesktopWindowTreeHostWin, aura::AnimationHost implementation:
567 void DesktopWindowTreeHostWin::SetHostTransitionOffsets(
568 const gfx::Vector2d& top_left_delta,
569 const gfx::Vector2d& bottom_right_delta) {
570 gfx::Rect bounds_without_expansion = GetBounds();
571 window_expansion_top_left_delta_ = top_left_delta;
572 window_expansion_bottom_right_delta_ = bottom_right_delta;
573 SetBounds(bounds_without_expansion);
576 void DesktopWindowTreeHostWin::OnWindowHidingAnimationCompleted() {
577 if (pending_close_)
578 message_handler_->Close();
581 ////////////////////////////////////////////////////////////////////////////////
582 // DesktopWindowTreeHostWin, HWNDMessageHandlerDelegate implementation:
584 bool DesktopWindowTreeHostWin::IsWidgetWindow() const {
585 return has_non_client_view_;
588 bool DesktopWindowTreeHostWin::IsUsingCustomFrame() const {
589 return !GetWidget()->ShouldUseNativeFrame();
592 void DesktopWindowTreeHostWin::SchedulePaint() {
593 GetWidget()->GetRootView()->SchedulePaint();
596 void DesktopWindowTreeHostWin::EnableInactiveRendering() {
597 native_widget_delegate_->EnableInactiveRendering();
600 bool DesktopWindowTreeHostWin::IsInactiveRenderingDisabled() {
601 return native_widget_delegate_->IsInactiveRenderingDisabled();
604 bool DesktopWindowTreeHostWin::CanResize() const {
605 return GetWidget()->widget_delegate()->CanResize();
608 bool DesktopWindowTreeHostWin::CanMaximize() const {
609 return GetWidget()->widget_delegate()->CanMaximize();
612 bool DesktopWindowTreeHostWin::CanMinimize() const {
613 return GetWidget()->widget_delegate()->CanMinimize();
616 bool DesktopWindowTreeHostWin::CanActivate() const {
617 if (IsModalWindowActive())
618 return true;
619 return native_widget_delegate_->CanActivate();
622 bool DesktopWindowTreeHostWin::WidgetSizeIsClientSize() const {
623 const Widget* widget = GetWidget()->GetTopLevelWidget();
624 return IsMaximized() || (widget && widget->ShouldUseNativeFrame());
627 bool DesktopWindowTreeHostWin::IsModal() const {
628 return native_widget_delegate_->IsModal();
631 int DesktopWindowTreeHostWin::GetInitialShowState() const {
632 return CanActivate() ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
635 bool DesktopWindowTreeHostWin::WillProcessWorkAreaChange() const {
636 return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
639 int DesktopWindowTreeHostWin::GetNonClientComponent(
640 const gfx::Point& point) const {
641 gfx::Point dip_position = gfx::win::ScreenToDIPPoint(point);
642 return native_widget_delegate_->GetNonClientComponent(dip_position);
645 void DesktopWindowTreeHostWin::GetWindowMask(const gfx::Size& size,
646 gfx::Path* path) {
647 if (GetWidget()->non_client_view()) {
648 GetWidget()->non_client_view()->GetWindowMask(size, path);
649 } else if (!window_enlargement_.IsZero()) {
650 gfx::Rect bounds(WidgetSizeIsClientSize()
651 ? message_handler_->GetClientAreaBoundsInScreen()
652 : message_handler_->GetWindowBoundsInScreen());
653 InsetBottomRight(&bounds, window_enlargement_);
654 path->addRect(SkRect::MakeXYWH(0, 0, bounds.width(), bounds.height()));
658 bool DesktopWindowTreeHostWin::GetClientAreaInsets(gfx::Insets* insets) const {
659 return false;
662 void DesktopWindowTreeHostWin::GetMinMaxSize(gfx::Size* min_size,
663 gfx::Size* max_size) const {
664 *min_size = native_widget_delegate_->GetMinimumSize();
665 *max_size = native_widget_delegate_->GetMaximumSize();
668 gfx::Size DesktopWindowTreeHostWin::GetRootViewSize() const {
669 return GetWidget()->GetRootView()->size();
672 void DesktopWindowTreeHostWin::ResetWindowControls() {
673 GetWidget()->non_client_view()->ResetWindowControls();
676 void DesktopWindowTreeHostWin::PaintLayeredWindow(gfx::Canvas* canvas) {
677 GetWidget()->GetRootView()->Paint(canvas, views::CullSet());
680 gfx::NativeViewAccessible DesktopWindowTreeHostWin::GetNativeViewAccessible() {
681 return GetWidget()->GetRootView()->GetNativeViewAccessible();
684 InputMethod* DesktopWindowTreeHostWin::GetInputMethod() {
685 return GetWidget()->GetInputMethodDirect();
688 bool DesktopWindowTreeHostWin::ShouldHandleSystemCommands() const {
689 return GetWidget()->widget_delegate()->ShouldHandleSystemCommands();
692 void DesktopWindowTreeHostWin::HandleAppDeactivated() {
693 native_widget_delegate_->EnableInactiveRendering();
696 void DesktopWindowTreeHostWin::HandleActivationChanged(bool active) {
697 // This can be invoked from HWNDMessageHandler::Init(), at which point we're
698 // not in a good state and need to ignore it.
699 // TODO(beng): Do we need this still now the host owns the dispatcher?
700 if (!dispatcher())
701 return;
703 if (active)
704 OnHostActivated();
705 desktop_native_widget_aura_->HandleActivationChanged(active);
708 bool DesktopWindowTreeHostWin::HandleAppCommand(short command) {
709 // We treat APPCOMMAND ids as an extension of our command namespace, and just
710 // let the delegate figure out what to do...
711 return GetWidget()->widget_delegate() &&
712 GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
715 void DesktopWindowTreeHostWin::HandleCancelMode() {
716 dispatcher()->DispatchCancelModeEvent();
719 void DesktopWindowTreeHostWin::HandleCaptureLost() {
720 OnHostLostWindowCapture();
723 void DesktopWindowTreeHostWin::HandleClose() {
724 GetWidget()->Close();
727 bool DesktopWindowTreeHostWin::HandleCommand(int command) {
728 // Windows uses the 4 lower order bits of |notification_code| for type-
729 // specific information so we must exclude this when comparing.
730 static const int sc_mask = 0xFFF0;
731 switch (command & sc_mask) {
732 case SC_RESTORE:
733 case SC_MAXIMIZE:
734 need_synchronous_paint_ = true;
735 break;
737 case SC_SIZE:
738 in_sizing_loop_ = true;
739 break;
741 default:
742 break;
744 return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
747 void DesktopWindowTreeHostWin::HandleAccelerator(
748 const ui::Accelerator& accelerator) {
749 GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator);
752 void DesktopWindowTreeHostWin::HandleCreate() {
753 native_widget_delegate_->OnNativeWidgetCreated(true);
756 void DesktopWindowTreeHostWin::HandleDestroying() {
757 drag_drop_client_->OnNativeWidgetDestroying(GetHWND());
758 native_widget_delegate_->OnNativeWidgetDestroying();
760 // Destroy the compositor before destroying the HWND since shutdown
761 // may try to swap to the window.
762 DestroyCompositor();
765 void DesktopWindowTreeHostWin::HandleDestroyed() {
766 desktop_native_widget_aura_->OnHostClosed();
769 bool DesktopWindowTreeHostWin::HandleInitialFocus(
770 ui::WindowShowState show_state) {
771 return GetWidget()->SetInitialFocus(show_state);
774 void DesktopWindowTreeHostWin::HandleDisplayChange() {
775 GetWidget()->widget_delegate()->OnDisplayChanged();
778 void DesktopWindowTreeHostWin::HandleBeginWMSizeMove() {
779 if (in_sizing_loop_)
780 need_synchronous_paint_ = true;
781 native_widget_delegate_->OnNativeWidgetBeginUserBoundsChange();
784 void DesktopWindowTreeHostWin::HandleEndWMSizeMove() {
785 if (in_sizing_loop_) {
786 need_synchronous_paint_ = false;
787 in_sizing_loop_ = false;
789 native_widget_delegate_->OnNativeWidgetEndUserBoundsChange();
792 void DesktopWindowTreeHostWin::HandleMove() {
793 native_widget_delegate_->OnNativeWidgetMove();
794 OnHostMoved(GetBounds().origin());
797 void DesktopWindowTreeHostWin::HandleWorkAreaChanged() {
798 GetWidget()->widget_delegate()->OnWorkAreaChanged();
801 void DesktopWindowTreeHostWin::HandleVisibilityChanging(bool visible) {
802 native_widget_delegate_->OnNativeWidgetVisibilityChanging(visible);
805 void DesktopWindowTreeHostWin::HandleVisibilityChanged(bool visible) {
806 native_widget_delegate_->OnNativeWidgetVisibilityChanged(visible);
809 void DesktopWindowTreeHostWin::HandleClientSizeChanged(
810 const gfx::Size& new_size) {
811 if (dispatcher())
812 OnHostResized(new_size);
815 void DesktopWindowTreeHostWin::HandleFrameChanged() {
816 SetWindowTransparency();
817 // Replace the frame and layout the contents.
818 GetWidget()->non_client_view()->UpdateFrame();
821 void DesktopWindowTreeHostWin::HandleNativeFocus(HWND last_focused_window) {
822 // TODO(beng): inform the native_widget_delegate_.
823 InputMethod* input_method = GetInputMethod();
824 if (input_method)
825 input_method->OnFocus();
828 void DesktopWindowTreeHostWin::HandleNativeBlur(HWND focused_window) {
829 // TODO(beng): inform the native_widget_delegate_.
830 InputMethod* input_method = GetInputMethod();
831 if (input_method)
832 input_method->OnBlur();
835 bool DesktopWindowTreeHostWin::HandleMouseEvent(const ui::MouseEvent& event) {
836 SendEventToProcessor(const_cast<ui::MouseEvent*>(&event));
837 return event.handled();
840 bool DesktopWindowTreeHostWin::HandleKeyEvent(const ui::KeyEvent& event) {
841 return false;
844 bool DesktopWindowTreeHostWin::HandleUntranslatedKeyEvent(
845 const ui::KeyEvent& event) {
846 ui::KeyEvent duplicate_event(event);
847 SendEventToProcessor(&duplicate_event);
848 return duplicate_event.handled();
851 void DesktopWindowTreeHostWin::HandleTouchEvent(
852 const ui::TouchEvent& event) {
853 // HWNDMessageHandler asynchronously processes touch events. Because of this
854 // it's possible for the aura::WindowEventDispatcher to have been destroyed
855 // by the time we attempt to process them.
856 if (!GetWidget()->GetNativeView())
857 return;
859 // Currently we assume the window that has capture gets touch events too.
860 aura::WindowTreeHost* host =
861 aura::WindowTreeHost::GetForAcceleratedWidget(GetCapture());
862 if (host) {
863 DesktopWindowTreeHostWin* target =
864 host->window()->GetProperty(kDesktopWindowTreeHostKey);
865 if (target && target->HasCapture() && target != this) {
866 POINT target_location(event.location().ToPOINT());
867 ClientToScreen(GetHWND(), &target_location);
868 ScreenToClient(target->GetHWND(), &target_location);
869 ui::TouchEvent target_event(event, static_cast<View*>(NULL),
870 static_cast<View*>(NULL));
871 target_event.set_location(gfx::Point(target_location));
872 target_event.set_root_location(target_event.location());
873 target->SendEventToProcessor(&target_event);
874 return;
877 SendEventToProcessor(const_cast<ui::TouchEvent*>(&event));
880 bool DesktopWindowTreeHostWin::HandleIMEMessage(UINT message,
881 WPARAM w_param,
882 LPARAM l_param,
883 LRESULT* result) {
884 MSG msg = {};
885 msg.hwnd = GetHWND();
886 msg.message = message;
887 msg.wParam = w_param;
888 msg.lParam = l_param;
889 return desktop_native_widget_aura_->input_method_event_filter()->
890 input_method()->OnUntranslatedIMEMessage(msg, result);
893 void DesktopWindowTreeHostWin::HandleInputLanguageChange(
894 DWORD character_set,
895 HKL input_language_id) {
896 desktop_native_widget_aura_->input_method_event_filter()->
897 input_method()->OnInputLocaleChanged();
900 bool DesktopWindowTreeHostWin::HandlePaintAccelerated(
901 const gfx::Rect& invalid_rect) {
902 return native_widget_delegate_->OnNativeWidgetPaintAccelerated(invalid_rect);
905 void DesktopWindowTreeHostWin::HandlePaint(gfx::Canvas* canvas) {
906 // It appears possible to get WM_PAINT after WM_DESTROY.
907 if (compositor())
908 compositor()->ScheduleRedrawRect(gfx::Rect());
911 bool DesktopWindowTreeHostWin::HandleTooltipNotify(int w_param,
912 NMHDR* l_param,
913 LRESULT* l_result) {
914 return tooltip_ && tooltip_->HandleNotify(w_param, l_param, l_result);
917 void DesktopWindowTreeHostWin::HandleMenuLoop(bool in_menu_loop) {
918 if (in_menu_loop) {
919 tooltip_disabler_.reset(
920 new aura::client::ScopedTooltipDisabler(window()));
921 } else {
922 tooltip_disabler_.reset();
926 bool DesktopWindowTreeHostWin::PreHandleMSG(UINT message,
927 WPARAM w_param,
928 LPARAM l_param,
929 LRESULT* result) {
930 return false;
933 void DesktopWindowTreeHostWin::PostHandleMSG(UINT message,
934 WPARAM w_param,
935 LPARAM l_param) {
938 bool DesktopWindowTreeHostWin::HandleScrollEvent(
939 const ui::ScrollEvent& event) {
940 SendEventToProcessor(const_cast<ui::ScrollEvent*>(&event));
941 return event.handled();
944 void DesktopWindowTreeHostWin::HandleWindowSizeChanging() {
945 if (compositor() && need_synchronous_paint_) {
946 compositor()->DisableSwapUntilResize();
947 // If we received the window size changing notification due to a restore or
948 // maximize operation, then we can reset the need_synchronous_paint_ flag
949 // here. For a sizing operation, the flag will be reset at the end of the
950 // operation.
951 if (!in_sizing_loop_)
952 need_synchronous_paint_ = false;
956 ////////////////////////////////////////////////////////////////////////////////
957 // DesktopWindowTreeHostWin, private:
959 Widget* DesktopWindowTreeHostWin::GetWidget() {
960 return native_widget_delegate_->AsWidget();
963 const Widget* DesktopWindowTreeHostWin::GetWidget() const {
964 return native_widget_delegate_->AsWidget();
967 HWND DesktopWindowTreeHostWin::GetHWND() const {
968 return message_handler_->hwnd();
971 void DesktopWindowTreeHostWin::SetWindowTransparency() {
972 bool transparent = ShouldUseNativeFrame() && !IsFullscreen();
973 compositor()->SetHostHasTransparentBackground(transparent);
974 window()->SetTransparent(transparent);
975 content_window_->SetTransparent(transparent);
978 bool DesktopWindowTreeHostWin::IsModalWindowActive() const {
979 // This function can get called during window creation which occurs before
980 // dispatcher() has been created.
981 if (!dispatcher())
982 return false;
984 aura::Window::Windows::const_iterator index;
985 for (index = window()->children().begin();
986 index != window()->children().end();
987 ++index) {
988 if ((*index)->GetProperty(aura::client::kModalKey) !=
989 ui:: MODAL_TYPE_NONE && (*index)->TargetVisibility())
990 return true;
992 return false;
995 ////////////////////////////////////////////////////////////////////////////////
996 // DesktopWindowTreeHost, public:
998 // static
999 DesktopWindowTreeHost* DesktopWindowTreeHost::Create(
1000 internal::NativeWidgetDelegate* native_widget_delegate,
1001 DesktopNativeWidgetAura* desktop_native_widget_aura) {
1002 return new DesktopWindowTreeHostWin(native_widget_delegate,
1003 desktop_native_widget_aura);
1006 } // namespace views