MacViews: Get c/b/ui/views/tabs to build on Mac
[chromium-blink-merge.git] / ui / views / widget / desktop_aura / desktop_window_tree_host_win.cc
blobac57a18aa23df7e8937f23bc081bd4133faa1e58
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),
87 need_synchronous_paint_(false),
88 in_sizing_loop_(false) {
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(GetAcceleratedWidget());
151 void DesktopWindowTreeHostWin::OnNativeWidgetCreated(
152 const Widget::InitParams& params) {
153 // The cursor is not necessarily visible when the root window is created.
154 aura::client::CursorClient* cursor_client =
155 aura::client::GetCursorClient(window());
156 if (cursor_client)
157 is_cursor_visible_ = cursor_client->IsCursorVisible();
159 window()->SetProperty(kContentWindowForRootWindow, content_window_);
160 window()->SetProperty(kDesktopWindowTreeHostKey, this);
162 should_animate_window_close_ =
163 content_window_->type() != ui::wm::WINDOW_TYPE_NORMAL &&
164 !wm::WindowAnimationsDisabled(content_window_);
166 // TODO this is not invoked *after* Init(), but should be ok.
167 SetWindowTransparency();
170 scoped_ptr<corewm::Tooltip> DesktopWindowTreeHostWin::CreateTooltip() {
171 DCHECK(!tooltip_);
172 tooltip_ = new corewm::TooltipWin(GetAcceleratedWidget());
173 return scoped_ptr<corewm::Tooltip>(tooltip_);
176 scoped_ptr<aura::client::DragDropClient>
177 DesktopWindowTreeHostWin::CreateDragDropClient(
178 DesktopNativeCursorManager* cursor_manager) {
179 drag_drop_client_ = new DesktopDragDropClientWin(window(), GetHWND());
180 return scoped_ptr<aura::client::DragDropClient>(drag_drop_client_).Pass();
183 void DesktopWindowTreeHostWin::Close() {
184 // TODO(beng): Move this entire branch to DNWA so it can be shared with X11.
185 if (should_animate_window_close_) {
186 pending_close_ = true;
187 const bool is_animating =
188 content_window_->layer()->GetAnimator()->IsAnimatingProperty(
189 ui::LayerAnimationElement::VISIBILITY);
190 // Animation may not start for a number of reasons.
191 if (!is_animating)
192 message_handler_->Close();
193 // else case, OnWindowHidingAnimationCompleted does the actual Close.
194 } else {
195 message_handler_->Close();
199 void DesktopWindowTreeHostWin::CloseNow() {
200 message_handler_->CloseNow();
203 aura::WindowTreeHost* DesktopWindowTreeHostWin::AsWindowTreeHost() {
204 return this;
207 void DesktopWindowTreeHostWin::ShowWindowWithState(
208 ui::WindowShowState show_state) {
209 message_handler_->ShowWindowWithState(show_state);
212 void DesktopWindowTreeHostWin::ShowMaximizedWithBounds(
213 const gfx::Rect& restored_bounds) {
214 gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(restored_bounds);
215 message_handler_->ShowMaximizedWithBounds(pixel_bounds);
218 bool DesktopWindowTreeHostWin::IsVisible() const {
219 return message_handler_->IsVisible();
222 void DesktopWindowTreeHostWin::SetSize(const gfx::Size& size) {
223 gfx::Size size_in_pixels = gfx::win::DIPToScreenSize(size);
224 gfx::Size expanded = GetExpandedWindowSize(
225 message_handler_->window_ex_style(), size_in_pixels);
226 window_enlargement_ =
227 gfx::Vector2d(expanded.width() - size_in_pixels.width(),
228 expanded.height() - size_in_pixels.height());
229 message_handler_->SetSize(expanded);
232 void DesktopWindowTreeHostWin::StackAtTop() {
233 message_handler_->StackAtTop();
236 void DesktopWindowTreeHostWin::CenterWindow(const gfx::Size& size) {
237 gfx::Size size_in_pixels = gfx::win::DIPToScreenSize(size);
238 gfx::Size expanded_size;
239 expanded_size = GetExpandedWindowSize(message_handler_->window_ex_style(),
240 size_in_pixels);
241 window_enlargement_ =
242 gfx::Vector2d(expanded_size.width() - size_in_pixels.width(),
243 expanded_size.height() - size_in_pixels.height());
244 message_handler_->CenterWindow(expanded_size);
247 void DesktopWindowTreeHostWin::GetWindowPlacement(
248 gfx::Rect* bounds,
249 ui::WindowShowState* show_state) const {
250 message_handler_->GetWindowPlacement(bounds, show_state);
251 InsetBottomRight(bounds, window_enlargement_);
252 *bounds = gfx::win::ScreenToDIPRect(*bounds);
255 gfx::Rect DesktopWindowTreeHostWin::GetWindowBoundsInScreen() const {
256 gfx::Rect pixel_bounds = message_handler_->GetWindowBoundsInScreen();
257 InsetBottomRight(&pixel_bounds, window_enlargement_);
258 return gfx::win::ScreenToDIPRect(pixel_bounds);
261 gfx::Rect DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() const {
262 gfx::Rect pixel_bounds = message_handler_->GetClientAreaBoundsInScreen();
263 InsetBottomRight(&pixel_bounds, window_enlargement_);
264 return gfx::win::ScreenToDIPRect(pixel_bounds);
267 gfx::Rect DesktopWindowTreeHostWin::GetRestoredBounds() const {
268 gfx::Rect pixel_bounds = message_handler_->GetRestoredBounds();
269 InsetBottomRight(&pixel_bounds, window_enlargement_);
270 return gfx::win::ScreenToDIPRect(pixel_bounds);
273 gfx::Rect DesktopWindowTreeHostWin::GetWorkAreaBoundsInScreen() const {
274 MONITORINFO monitor_info;
275 monitor_info.cbSize = sizeof(monitor_info);
276 GetMonitorInfo(MonitorFromWindow(message_handler_->hwnd(),
277 MONITOR_DEFAULTTONEAREST),
278 &monitor_info);
279 gfx::Rect pixel_bounds = gfx::Rect(monitor_info.rcWork);
280 return gfx::win::ScreenToDIPRect(pixel_bounds);
283 void DesktopWindowTreeHostWin::SetShape(gfx::NativeRegion native_region) {
284 if (native_region) {
285 // TODO(wez): This would be a lot simpler if we were passed an SkPath.
286 // See crbug.com/410593.
287 gfx::NativeRegion shape = native_region;
288 SkRegion device_region;
289 if (gfx::GetDPIScale() > 1.0) {
290 shape = &device_region;
291 const float& scale = gfx::GetDPIScale();
292 std::vector<SkIRect> rects;
293 for (SkRegion::Iterator it(*native_region); !it.done(); it.next()) {
294 const SkIRect& rect = it.rect();
295 SkRect scaled_rect =
296 SkRect::MakeLTRB(rect.left() * scale, rect.top() * scale,
297 rect.right() * scale, rect.bottom() * scale);
298 SkIRect rounded_scaled_rect;
299 scaled_rect.roundOut(&rounded_scaled_rect);
300 rects.push_back(rounded_scaled_rect);
302 if (!rects.empty())
303 device_region.setRects(&rects[0], rects.size());
306 message_handler_->SetRegion(gfx::CreateHRGNFromSkRegion(*shape));
307 } else {
308 message_handler_->SetRegion(NULL);
311 delete native_region;
314 void DesktopWindowTreeHostWin::Activate() {
315 message_handler_->Activate();
318 void DesktopWindowTreeHostWin::Deactivate() {
319 message_handler_->Deactivate();
322 bool DesktopWindowTreeHostWin::IsActive() const {
323 return message_handler_->IsActive();
326 void DesktopWindowTreeHostWin::Maximize() {
327 message_handler_->Maximize();
330 void DesktopWindowTreeHostWin::Minimize() {
331 message_handler_->Minimize();
334 void DesktopWindowTreeHostWin::Restore() {
335 message_handler_->Restore();
338 bool DesktopWindowTreeHostWin::IsMaximized() const {
339 return message_handler_->IsMaximized();
342 bool DesktopWindowTreeHostWin::IsMinimized() const {
343 return message_handler_->IsMinimized();
346 bool DesktopWindowTreeHostWin::HasCapture() const {
347 return message_handler_->HasCapture();
350 void DesktopWindowTreeHostWin::SetAlwaysOnTop(bool always_on_top) {
351 message_handler_->SetAlwaysOnTop(always_on_top);
354 bool DesktopWindowTreeHostWin::IsAlwaysOnTop() const {
355 return message_handler_->IsAlwaysOnTop();
358 void DesktopWindowTreeHostWin::SetVisibleOnAllWorkspaces(bool always_visible) {
359 // Windows does not have the concept of workspaces.
362 bool DesktopWindowTreeHostWin::SetWindowTitle(const base::string16& title) {
363 return message_handler_->SetTitle(title);
366 void DesktopWindowTreeHostWin::ClearNativeFocus() {
367 message_handler_->ClearNativeFocus();
370 Widget::MoveLoopResult DesktopWindowTreeHostWin::RunMoveLoop(
371 const gfx::Vector2d& drag_offset,
372 Widget::MoveLoopSource source,
373 Widget::MoveLoopEscapeBehavior escape_behavior) {
374 const bool hide_on_escape =
375 escape_behavior == Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_HIDE;
376 return message_handler_->RunMoveLoop(drag_offset, hide_on_escape) ?
377 Widget::MOVE_LOOP_SUCCESSFUL : Widget::MOVE_LOOP_CANCELED;
380 void DesktopWindowTreeHostWin::EndMoveLoop() {
381 message_handler_->EndMoveLoop();
384 void DesktopWindowTreeHostWin::SetVisibilityChangedAnimationsEnabled(
385 bool value) {
386 message_handler_->SetVisibilityChangedAnimationsEnabled(value);
387 content_window_->SetProperty(aura::client::kAnimationsDisabledKey, !value);
390 bool DesktopWindowTreeHostWin::ShouldUseNativeFrame() const {
391 return IsTranslucentWindowOpacitySupported();
394 bool DesktopWindowTreeHostWin::ShouldWindowContentsBeTransparent() const {
395 // If the window has a native frame, we assume it is an Aero Glass window, and
396 // is therefore transparent. Note: This is not equivalent to calling
397 // IsAeroGlassEnabled, because ShouldUseNativeFrame is overridden in a
398 // subclass.
399 return ShouldUseNativeFrame();
402 void DesktopWindowTreeHostWin::FrameTypeChanged() {
403 message_handler_->FrameTypeChanged();
404 SetWindowTransparency();
407 void DesktopWindowTreeHostWin::SetFullscreen(bool fullscreen) {
408 message_handler_->SetFullscreen(fullscreen);
409 // TODO(sky): workaround for ScopedFullscreenVisibility showing window
410 // directly. Instead of this should listen for visibility changes and then
411 // update window.
412 if (message_handler_->IsVisible() && !content_window_->TargetVisibility())
413 content_window_->Show();
414 SetWindowTransparency();
417 bool DesktopWindowTreeHostWin::IsFullscreen() const {
418 return message_handler_->fullscreen_handler()->fullscreen();
421 void DesktopWindowTreeHostWin::SetOpacity(unsigned char opacity) {
422 message_handler_->SetOpacity(static_cast<BYTE>(opacity));
423 content_window_->layer()->SetOpacity(opacity / 255.0);
426 void DesktopWindowTreeHostWin::SetWindowIcons(
427 const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
428 message_handler_->SetWindowIcons(window_icon, app_icon);
431 void DesktopWindowTreeHostWin::InitModalType(ui::ModalType modal_type) {
432 message_handler_->InitModalType(modal_type);
435 void DesktopWindowTreeHostWin::FlashFrame(bool flash_frame) {
436 message_handler_->FlashFrame(flash_frame);
439 void DesktopWindowTreeHostWin::OnRootViewLayout() {
442 void DesktopWindowTreeHostWin::OnNativeWidgetFocus() {
443 // HWNDMessageHandler will perform the proper updating on its own.
446 void DesktopWindowTreeHostWin::OnNativeWidgetBlur() {
449 bool DesktopWindowTreeHostWin::IsAnimatingClosed() const {
450 return pending_close_;
453 bool DesktopWindowTreeHostWin::IsTranslucentWindowOpacitySupported() const {
454 return ui::win::IsAeroGlassEnabled();
457 void DesktopWindowTreeHostWin::SizeConstraintsChanged() {
458 message_handler_->SizeConstraintsChanged();
461 ////////////////////////////////////////////////////////////////////////////////
462 // DesktopWindowTreeHostWin, WindowTreeHost implementation:
464 ui::EventSource* DesktopWindowTreeHostWin::GetEventSource() {
465 return this;
468 gfx::AcceleratedWidget DesktopWindowTreeHostWin::GetAcceleratedWidget() {
469 return message_handler_->hwnd();
472 void DesktopWindowTreeHostWin::Show() {
473 message_handler_->Show();
476 void DesktopWindowTreeHostWin::Hide() {
477 if (!pending_close_)
478 message_handler_->Hide();
481 // GetBounds and SetBounds work in pixel coordinates, whereas other get/set
482 // methods work in DIP.
484 gfx::Rect DesktopWindowTreeHostWin::GetBounds() const {
485 gfx::Rect bounds(message_handler_->GetClientAreaBounds());
486 // If the window bounds were expanded we need to return the original bounds
487 // To achieve this we do the reverse of the expansion, i.e. add the
488 // window_expansion_top_left_delta_ to the origin and subtract the
489 // window_expansion_bottom_right_delta_ from the width and height.
490 gfx::Rect without_expansion(
491 bounds.x() + window_expansion_top_left_delta_.x(),
492 bounds.y() + window_expansion_top_left_delta_.y(),
493 bounds.width() - window_expansion_bottom_right_delta_.x() -
494 window_enlargement_.x(),
495 bounds.height() - window_expansion_bottom_right_delta_.y() -
496 window_enlargement_.y());
497 return without_expansion;
500 void DesktopWindowTreeHostWin::SetBounds(const gfx::Rect& bounds) {
501 // If the window bounds have to be expanded we need to subtract the
502 // window_expansion_top_left_delta_ from the origin and add the
503 // window_expansion_bottom_right_delta_ to the width and height
504 gfx::Size old_hwnd_size(message_handler_->GetClientAreaBounds().size());
505 gfx::Size old_content_size = GetBounds().size();
507 gfx::Rect expanded(
508 bounds.x() - window_expansion_top_left_delta_.x(),
509 bounds.y() - window_expansion_top_left_delta_.y(),
510 bounds.width() + window_expansion_bottom_right_delta_.x(),
511 bounds.height() + window_expansion_bottom_right_delta_.y());
513 gfx::Rect new_expanded(
514 expanded.origin(),
515 GetExpandedWindowSize(message_handler_->window_ex_style(),
516 expanded.size()));
517 window_enlargement_ =
518 gfx::Vector2d(new_expanded.width() - expanded.width(),
519 new_expanded.height() - expanded.height());
520 message_handler_->SetBounds(new_expanded, old_content_size != bounds.size());
523 gfx::Point DesktopWindowTreeHostWin::GetLocationOnNativeScreen() const {
524 return GetBounds().origin();
527 void DesktopWindowTreeHostWin::SetCapture() {
528 message_handler_->SetCapture();
531 void DesktopWindowTreeHostWin::ReleaseCapture() {
532 message_handler_->ReleaseCapture();
535 void DesktopWindowTreeHostWin::PostNativeEvent(
536 const base::NativeEvent& native_event) {
539 void DesktopWindowTreeHostWin::SetCursorNative(gfx::NativeCursor cursor) {
540 ui::CursorLoaderWin cursor_loader;
541 cursor_loader.SetPlatformCursor(&cursor);
543 message_handler_->SetCursor(cursor.platform());
546 void DesktopWindowTreeHostWin::OnCursorVisibilityChangedNative(bool show) {
547 if (is_cursor_visible_ == show)
548 return;
549 is_cursor_visible_ = show;
550 ::ShowCursor(!!show);
553 void DesktopWindowTreeHostWin::MoveCursorToNative(const gfx::Point& location) {
554 POINT cursor_location = location.ToPOINT();
555 ::ClientToScreen(GetHWND(), &cursor_location);
556 ::SetCursorPos(cursor_location.x, cursor_location.y);
559 ////////////////////////////////////////////////////////////////////////////////
560 // DesktopWindowTreeHostWin, ui::EventSource implementation:
562 ui::EventProcessor* DesktopWindowTreeHostWin::GetEventProcessor() {
563 return dispatcher();
566 ////////////////////////////////////////////////////////////////////////////////
567 // DesktopWindowTreeHostWin, aura::AnimationHost implementation:
569 void DesktopWindowTreeHostWin::SetHostTransitionOffsets(
570 const gfx::Vector2d& top_left_delta,
571 const gfx::Vector2d& bottom_right_delta) {
572 gfx::Rect bounds_without_expansion = GetBounds();
573 window_expansion_top_left_delta_ = top_left_delta;
574 window_expansion_bottom_right_delta_ = bottom_right_delta;
575 SetBounds(bounds_without_expansion);
578 void DesktopWindowTreeHostWin::OnWindowHidingAnimationCompleted() {
579 if (pending_close_)
580 message_handler_->Close();
583 ////////////////////////////////////////////////////////////////////////////////
584 // DesktopWindowTreeHostWin, HWNDMessageHandlerDelegate implementation:
586 bool DesktopWindowTreeHostWin::IsWidgetWindow() const {
587 return has_non_client_view_;
590 bool DesktopWindowTreeHostWin::IsUsingCustomFrame() const {
591 return !GetWidget()->ShouldUseNativeFrame();
594 void DesktopWindowTreeHostWin::SchedulePaint() {
595 GetWidget()->GetRootView()->SchedulePaint();
598 void DesktopWindowTreeHostWin::EnableInactiveRendering() {
599 native_widget_delegate_->EnableInactiveRendering();
602 bool DesktopWindowTreeHostWin::IsInactiveRenderingDisabled() {
603 return native_widget_delegate_->IsInactiveRenderingDisabled();
606 bool DesktopWindowTreeHostWin::CanResize() const {
607 return GetWidget()->widget_delegate()->CanResize();
610 bool DesktopWindowTreeHostWin::CanMaximize() const {
611 return GetWidget()->widget_delegate()->CanMaximize();
614 bool DesktopWindowTreeHostWin::CanMinimize() const {
615 return GetWidget()->widget_delegate()->CanMinimize();
618 bool DesktopWindowTreeHostWin::CanActivate() const {
619 if (IsModalWindowActive())
620 return true;
621 return native_widget_delegate_->CanActivate();
624 bool DesktopWindowTreeHostWin::WidgetSizeIsClientSize() const {
625 const Widget* widget = GetWidget()->GetTopLevelWidget();
626 return IsMaximized() || (widget && widget->ShouldUseNativeFrame());
629 bool DesktopWindowTreeHostWin::IsModal() const {
630 return native_widget_delegate_->IsModal();
633 int DesktopWindowTreeHostWin::GetInitialShowState() const {
634 return CanActivate() ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
637 bool DesktopWindowTreeHostWin::WillProcessWorkAreaChange() const {
638 return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
641 int DesktopWindowTreeHostWin::GetNonClientComponent(
642 const gfx::Point& point) const {
643 gfx::Point dip_position = gfx::win::ScreenToDIPPoint(point);
644 return native_widget_delegate_->GetNonClientComponent(dip_position);
647 void DesktopWindowTreeHostWin::GetWindowMask(const gfx::Size& size,
648 gfx::Path* path) {
649 if (GetWidget()->non_client_view()) {
650 GetWidget()->non_client_view()->GetWindowMask(size, path);
651 } else if (!window_enlargement_.IsZero()) {
652 gfx::Rect bounds(WidgetSizeIsClientSize()
653 ? message_handler_->GetClientAreaBoundsInScreen()
654 : message_handler_->GetWindowBoundsInScreen());
655 InsetBottomRight(&bounds, window_enlargement_);
656 path->addRect(SkRect::MakeXYWH(0, 0, bounds.width(), bounds.height()));
660 bool DesktopWindowTreeHostWin::GetClientAreaInsets(gfx::Insets* insets) const {
661 return false;
664 void DesktopWindowTreeHostWin::GetMinMaxSize(gfx::Size* min_size,
665 gfx::Size* max_size) const {
666 *min_size = native_widget_delegate_->GetMinimumSize();
667 *max_size = native_widget_delegate_->GetMaximumSize();
670 gfx::Size DesktopWindowTreeHostWin::GetRootViewSize() const {
671 return GetWidget()->GetRootView()->size();
674 void DesktopWindowTreeHostWin::ResetWindowControls() {
675 GetWidget()->non_client_view()->ResetWindowControls();
678 void DesktopWindowTreeHostWin::PaintLayeredWindow(gfx::Canvas* canvas) {
679 GetWidget()->GetRootView()->Paint(canvas, views::CullSet());
682 gfx::NativeViewAccessible DesktopWindowTreeHostWin::GetNativeViewAccessible() {
683 return GetWidget()->GetRootView()->GetNativeViewAccessible();
686 InputMethod* DesktopWindowTreeHostWin::GetInputMethod() {
687 return GetWidget()->GetInputMethodDirect();
690 bool DesktopWindowTreeHostWin::ShouldHandleSystemCommands() const {
691 return GetWidget()->widget_delegate()->ShouldHandleSystemCommands();
694 void DesktopWindowTreeHostWin::HandleAppDeactivated() {
695 native_widget_delegate_->EnableInactiveRendering();
698 void DesktopWindowTreeHostWin::HandleActivationChanged(bool active) {
699 // This can be invoked from HWNDMessageHandler::Init(), at which point we're
700 // not in a good state and need to ignore it.
701 // TODO(beng): Do we need this still now the host owns the dispatcher?
702 if (!dispatcher())
703 return;
705 if (active)
706 OnHostActivated();
707 desktop_native_widget_aura_->HandleActivationChanged(active);
710 bool DesktopWindowTreeHostWin::HandleAppCommand(short command) {
711 // We treat APPCOMMAND ids as an extension of our command namespace, and just
712 // let the delegate figure out what to do...
713 return GetWidget()->widget_delegate() &&
714 GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
717 void DesktopWindowTreeHostWin::HandleCancelMode() {
718 dispatcher()->DispatchCancelModeEvent();
721 void DesktopWindowTreeHostWin::HandleCaptureLost() {
722 OnHostLostWindowCapture();
725 void DesktopWindowTreeHostWin::HandleClose() {
726 GetWidget()->Close();
729 bool DesktopWindowTreeHostWin::HandleCommand(int command) {
730 // Windows uses the 4 lower order bits of |notification_code| for type-
731 // specific information so we must exclude this when comparing.
732 static const int sc_mask = 0xFFF0;
733 switch (command & sc_mask) {
734 case SC_RESTORE:
735 case SC_MAXIMIZE:
736 need_synchronous_paint_ = true;
737 break;
739 case SC_SIZE:
740 in_sizing_loop_ = true;
741 break;
743 default:
744 break;
746 return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
749 void DesktopWindowTreeHostWin::HandleAccelerator(
750 const ui::Accelerator& accelerator) {
751 GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator);
754 void DesktopWindowTreeHostWin::HandleCreate() {
755 native_widget_delegate_->OnNativeWidgetCreated(true);
758 void DesktopWindowTreeHostWin::HandleDestroying() {
759 drag_drop_client_->OnNativeWidgetDestroying(GetHWND());
760 native_widget_delegate_->OnNativeWidgetDestroying();
762 // Destroy the compositor before destroying the HWND since shutdown
763 // may try to swap to the window.
764 DestroyCompositor();
767 void DesktopWindowTreeHostWin::HandleDestroyed() {
768 desktop_native_widget_aura_->OnHostClosed();
771 bool DesktopWindowTreeHostWin::HandleInitialFocus(
772 ui::WindowShowState show_state) {
773 return GetWidget()->SetInitialFocus(show_state);
776 void DesktopWindowTreeHostWin::HandleDisplayChange() {
777 GetWidget()->widget_delegate()->OnDisplayChanged();
780 void DesktopWindowTreeHostWin::HandleBeginWMSizeMove() {
781 if (in_sizing_loop_)
782 need_synchronous_paint_ = true;
783 native_widget_delegate_->OnNativeWidgetBeginUserBoundsChange();
786 void DesktopWindowTreeHostWin::HandleEndWMSizeMove() {
787 if (in_sizing_loop_) {
788 need_synchronous_paint_ = false;
789 in_sizing_loop_ = false;
791 native_widget_delegate_->OnNativeWidgetEndUserBoundsChange();
794 void DesktopWindowTreeHostWin::HandleMove() {
795 native_widget_delegate_->OnNativeWidgetMove();
796 OnHostMoved(GetBounds().origin());
799 void DesktopWindowTreeHostWin::HandleWorkAreaChanged() {
800 GetWidget()->widget_delegate()->OnWorkAreaChanged();
803 void DesktopWindowTreeHostWin::HandleVisibilityChanging(bool visible) {
804 native_widget_delegate_->OnNativeWidgetVisibilityChanging(visible);
807 void DesktopWindowTreeHostWin::HandleVisibilityChanged(bool visible) {
808 native_widget_delegate_->OnNativeWidgetVisibilityChanged(visible);
811 void DesktopWindowTreeHostWin::HandleClientSizeChanged(
812 const gfx::Size& new_size) {
813 if (dispatcher())
814 OnHostResized(new_size);
817 void DesktopWindowTreeHostWin::HandleFrameChanged() {
818 SetWindowTransparency();
819 // Replace the frame and layout the contents.
820 GetWidget()->non_client_view()->UpdateFrame();
823 void DesktopWindowTreeHostWin::HandleNativeFocus(HWND last_focused_window) {
824 // TODO(beng): inform the native_widget_delegate_.
825 InputMethod* input_method = GetInputMethod();
826 if (input_method)
827 input_method->OnFocus();
830 void DesktopWindowTreeHostWin::HandleNativeBlur(HWND focused_window) {
831 // TODO(beng): inform the native_widget_delegate_.
832 InputMethod* input_method = GetInputMethod();
833 if (input_method)
834 input_method->OnBlur();
837 bool DesktopWindowTreeHostWin::HandleMouseEvent(const ui::MouseEvent& event) {
838 SendEventToProcessor(const_cast<ui::MouseEvent*>(&event));
839 return event.handled();
842 bool DesktopWindowTreeHostWin::HandleKeyEvent(const ui::KeyEvent& event) {
843 return false;
846 bool DesktopWindowTreeHostWin::HandleUntranslatedKeyEvent(
847 const ui::KeyEvent& event) {
848 ui::KeyEvent duplicate_event(event);
849 SendEventToProcessor(&duplicate_event);
850 return duplicate_event.handled();
853 void DesktopWindowTreeHostWin::HandleTouchEvent(
854 const ui::TouchEvent& event) {
855 // HWNDMessageHandler asynchronously processes touch events. Because of this
856 // it's possible for the aura::WindowEventDispatcher to have been destroyed
857 // by the time we attempt to process them.
858 if (!GetWidget()->GetNativeView())
859 return;
861 // Currently we assume the window that has capture gets touch events too.
862 aura::WindowTreeHost* host =
863 aura::WindowTreeHost::GetForAcceleratedWidget(GetCapture());
864 if (host) {
865 DesktopWindowTreeHostWin* target =
866 host->window()->GetProperty(kDesktopWindowTreeHostKey);
867 if (target && target->HasCapture() && target != this) {
868 POINT target_location(event.location().ToPOINT());
869 ClientToScreen(GetHWND(), &target_location);
870 ScreenToClient(target->GetHWND(), &target_location);
871 ui::TouchEvent target_event(event, static_cast<View*>(NULL),
872 static_cast<View*>(NULL));
873 target_event.set_location(gfx::Point(target_location));
874 target_event.set_root_location(target_event.location());
875 target->SendEventToProcessor(&target_event);
876 return;
879 SendEventToProcessor(const_cast<ui::TouchEvent*>(&event));
882 bool DesktopWindowTreeHostWin::HandleIMEMessage(UINT message,
883 WPARAM w_param,
884 LPARAM l_param,
885 LRESULT* result) {
886 MSG msg = {};
887 msg.hwnd = GetHWND();
888 msg.message = message;
889 msg.wParam = w_param;
890 msg.lParam = l_param;
891 return desktop_native_widget_aura_->input_method_event_filter()->
892 input_method()->OnUntranslatedIMEMessage(msg, result);
895 void DesktopWindowTreeHostWin::HandleInputLanguageChange(
896 DWORD character_set,
897 HKL input_language_id) {
898 desktop_native_widget_aura_->input_method_event_filter()->
899 input_method()->OnInputLocaleChanged();
902 bool DesktopWindowTreeHostWin::HandlePaintAccelerated(
903 const gfx::Rect& invalid_rect) {
904 return native_widget_delegate_->OnNativeWidgetPaintAccelerated(invalid_rect);
907 void DesktopWindowTreeHostWin::HandlePaint(gfx::Canvas* canvas) {
908 // It appears possible to get WM_PAINT after WM_DESTROY.
909 if (compositor())
910 compositor()->ScheduleRedrawRect(gfx::Rect());
913 bool DesktopWindowTreeHostWin::HandleTooltipNotify(int w_param,
914 NMHDR* l_param,
915 LRESULT* l_result) {
916 return tooltip_ && tooltip_->HandleNotify(w_param, l_param, l_result);
919 void DesktopWindowTreeHostWin::HandleMenuLoop(bool in_menu_loop) {
920 if (in_menu_loop) {
921 tooltip_disabler_.reset(
922 new aura::client::ScopedTooltipDisabler(window()));
923 } else {
924 tooltip_disabler_.reset();
928 bool DesktopWindowTreeHostWin::PreHandleMSG(UINT message,
929 WPARAM w_param,
930 LPARAM l_param,
931 LRESULT* result) {
932 return false;
935 void DesktopWindowTreeHostWin::PostHandleMSG(UINT message,
936 WPARAM w_param,
937 LPARAM l_param) {
940 bool DesktopWindowTreeHostWin::HandleScrollEvent(
941 const ui::ScrollEvent& event) {
942 SendEventToProcessor(const_cast<ui::ScrollEvent*>(&event));
943 return event.handled();
946 void DesktopWindowTreeHostWin::HandleWindowSizeChanging() {
947 if (compositor() && need_synchronous_paint_) {
948 compositor()->FinishAllRendering();
949 // If we received the window size changing notification due to a restore or
950 // maximize operation, then we can reset the need_synchronous_paint_ flag
951 // here. For a sizing operation, the flag will be reset at the end of the
952 // operation.
953 if (!in_sizing_loop_)
954 need_synchronous_paint_ = false;
958 ////////////////////////////////////////////////////////////////////////////////
959 // DesktopWindowTreeHostWin, private:
961 Widget* DesktopWindowTreeHostWin::GetWidget() {
962 return native_widget_delegate_->AsWidget();
965 const Widget* DesktopWindowTreeHostWin::GetWidget() const {
966 return native_widget_delegate_->AsWidget();
969 HWND DesktopWindowTreeHostWin::GetHWND() const {
970 return message_handler_->hwnd();
973 void DesktopWindowTreeHostWin::SetWindowTransparency() {
974 bool transparent = ShouldUseNativeFrame() && !IsFullscreen();
975 compositor()->SetHostHasTransparentBackground(transparent);
976 window()->SetTransparent(transparent);
977 content_window_->SetTransparent(transparent);
980 bool DesktopWindowTreeHostWin::IsModalWindowActive() const {
981 // This function can get called during window creation which occurs before
982 // dispatcher() has been created.
983 if (!dispatcher())
984 return false;
986 aura::Window::Windows::const_iterator index;
987 for (index = window()->children().begin();
988 index != window()->children().end();
989 ++index) {
990 if ((*index)->GetProperty(aura::client::kModalKey) !=
991 ui:: MODAL_TYPE_NONE && (*index)->TargetVisibility())
992 return true;
994 return false;
997 ////////////////////////////////////////////////////////////////////////////////
998 // DesktopWindowTreeHost, public:
1000 // static
1001 DesktopWindowTreeHost* DesktopWindowTreeHost::Create(
1002 internal::NativeWidgetDelegate* native_widget_delegate,
1003 DesktopNativeWidgetAura* desktop_native_widget_aura) {
1004 return new DesktopWindowTreeHostWin(native_widget_delegate,
1005 desktop_native_widget_aura);
1008 } // namespace views