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/native_widget_aura.h"
8 #include "base/strings/string_util.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/client/screen_position_client.h"
14 #include "ui/aura/client/window_tree_client.h"
15 #include "ui/aura/env.h"
16 #include "ui/aura/window.h"
17 #include "ui/aura/window_event_dispatcher.h"
18 #include "ui/aura/window_observer.h"
19 #include "ui/aura/window_tree_host.h"
20 #include "ui/base/dragdrop/os_exchange_data.h"
21 #include "ui/base/ui_base_types.h"
22 #include "ui/compositor/layer.h"
23 #include "ui/events/event.h"
24 #include "ui/gfx/canvas.h"
25 #include "ui/gfx/font_list.h"
26 #include "ui/gfx/screen.h"
27 #include "ui/native_theme/native_theme_aura.h"
28 #include "ui/views/drag_utils.h"
29 #include "ui/views/views_delegate.h"
30 #include "ui/views/widget/drop_helper.h"
31 #include "ui/views/widget/native_widget_delegate.h"
32 #include "ui/views/widget/root_view.h"
33 #include "ui/views/widget/tooltip_manager_aura.h"
34 #include "ui/views/widget/widget_aura_utils.h"
35 #include "ui/views/widget/widget_delegate.h"
36 #include "ui/views/widget/window_reorderer.h"
37 #include "ui/wm/core/shadow_types.h"
38 #include "ui/wm/core/window_animations.h"
39 #include "ui/wm/core/window_util.h"
40 #include "ui/wm/public/activation_client.h"
41 #include "ui/wm/public/drag_drop_client.h"
42 #include "ui/wm/public/window_move_client.h"
43 #include "ui/wm/public/window_types.h"
46 #include "base/win/scoped_gdi_object.h"
47 #include "base/win/win_util.h"
48 #include "ui/base/l10n/l10n_util_win.h"
49 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
52 #if defined(USE_X11) && !defined(OS_CHROMEOS)
53 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
56 #if !defined(OS_CHROMEOS)
57 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
58 #include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
65 void SetRestoreBounds(aura::Window
* window
, const gfx::Rect
& bounds
) {
66 window
->SetProperty(aura::client::kRestoreBoundsKey
, new gfx::Rect(bounds
));
71 ////////////////////////////////////////////////////////////////////////////////
72 // NativeWidgetAura, public:
74 NativeWidgetAura::NativeWidgetAura(internal::NativeWidgetDelegate
* delegate
)
75 : delegate_(delegate
),
76 window_(new aura::Window(this)),
77 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
),
79 cursor_(gfx::kNullCursor
),
80 saved_window_state_(ui::SHOW_STATE_DEFAULT
),
81 close_widget_factory_(this) {
82 aura::client::SetFocusChangeObserver(window_
, this);
83 aura::client::SetActivationChangeObserver(window_
, this);
87 void NativeWidgetAura::RegisterNativeWidgetForWindow(
88 internal::NativeWidgetPrivate
* native_widget
,
89 aura::Window
* window
) {
90 window
->set_user_data(native_widget
);
93 ////////////////////////////////////////////////////////////////////////////////
94 // NativeWidgetAura, internal::NativeWidgetPrivate implementation:
96 void NativeWidgetAura::InitNativeWidget(const Widget::InitParams
& params
) {
97 // Aura needs to know which desktop (Ash or regular) will manage this widget.
98 // See Widget::InitParams::context for details.
99 DCHECK(params
.parent
|| params
.context
);
101 ownership_
= params
.ownership
;
103 RegisterNativeWidgetForWindow(this, window_
);
104 window_
->SetType(GetAuraWindowTypeForWidgetType(params
.type
));
105 window_
->SetProperty(aura::client::kShowStateKey
, params
.show_state
);
106 if (params
.type
== Widget::InitParams::TYPE_BUBBLE
)
107 aura::client::SetHideOnDeactivate(window_
, true);
108 window_
->SetTransparent(
109 params
.opacity
== Widget::InitParams::TRANSLUCENT_WINDOW
);
110 window_
->Init(params
.layer_type
);
111 if (params
.shadow_type
== Widget::InitParams::SHADOW_TYPE_NONE
)
112 SetShadowType(window_
, wm::SHADOW_TYPE_NONE
);
113 else if (params
.shadow_type
== Widget::InitParams::SHADOW_TYPE_DROP
)
114 SetShadowType(window_
, wm::SHADOW_TYPE_RECTANGULAR
);
115 if (params
.type
== Widget::InitParams::TYPE_CONTROL
)
118 delegate_
->OnNativeWidgetCreated(false);
120 gfx::Rect window_bounds
= params
.bounds
;
121 gfx::NativeView parent
= params
.parent
;
122 gfx::NativeView context
= params
.context
;
124 // Set up the transient child before the window is added. This way the
125 // LayoutManager knows the window has a transient parent.
126 if (parent
&& parent
->type() != ui::wm::WINDOW_TYPE_UNKNOWN
) {
127 wm::AddTransientChild(parent
, window_
);
132 // SetAlwaysOnTop before SetParent so that always-on-top container is used.
133 SetAlwaysOnTop(params
.keep_on_top
);
134 // Make sure we have a real |window_bounds|.
135 if (parent
&& window_bounds
== gfx::Rect()) {
136 // If a parent is specified but no bounds are given,
137 // use the origin of the parent's display so that the widget
138 // will be added to the same display as the parent.
139 gfx::Rect bounds
= gfx::Screen::GetScreenFor(parent
)->
140 GetDisplayNearestWindow(parent
).bounds();
141 window_bounds
.set_origin(bounds
.origin());
145 // Set properties before adding to the parent so that its layout manager sees
146 // the correct values.
147 OnSizeConstraintsChanged();
150 parent
->AddChild(window_
);
152 aura::client::ParentWindowWithContext(
153 window_
, context
->GetRootWindow(), window_bounds
);
156 // Start observing property changes.
157 window_
->AddObserver(this);
159 // Wait to set the bounds until we have a parent. That way we can know our
160 // true state/bounds (the LayoutManager may enforce a particular
163 SetRestoreBounds(window_
, window_bounds
);
165 SetBounds(window_bounds
);
166 window_
->set_ignore_events(!params
.accept_events
);
167 DCHECK(GetWidget()->GetRootView());
168 if (params
.type
!= Widget::InitParams::TYPE_TOOLTIP
)
169 tooltip_manager_
.reset(new views::TooltipManagerAura(GetWidget()));
171 drop_helper_
.reset(new DropHelper(GetWidget()->GetRootView()));
172 if (params
.type
!= Widget::InitParams::TYPE_TOOLTIP
&&
173 params
.type
!= Widget::InitParams::TYPE_POPUP
) {
174 aura::client::SetDragDropDelegate(window_
, this);
177 aura::client::SetActivationDelegate(window_
, this);
179 window_reorderer_
.reset(new WindowReorderer(window_
,
180 GetWidget()->GetRootView()));
183 NonClientFrameView
* NativeWidgetAura::CreateNonClientFrameView() {
187 bool NativeWidgetAura::ShouldUseNativeFrame() const {
188 // There is only one frame type for aura.
192 bool NativeWidgetAura::ShouldWindowContentsBeTransparent() const {
196 void NativeWidgetAura::FrameTypeChanged() {
197 // This is called when the Theme has changed; forward the event to the root
199 GetWidget()->ThemeChanged();
200 GetWidget()->GetRootView()->SchedulePaint();
203 Widget
* NativeWidgetAura::GetWidget() {
204 return delegate_
->AsWidget();
207 const Widget
* NativeWidgetAura::GetWidget() const {
208 return delegate_
->AsWidget();
211 gfx::NativeView
NativeWidgetAura::GetNativeView() const {
215 gfx::NativeWindow
NativeWidgetAura::GetNativeWindow() const {
219 Widget
* NativeWidgetAura::GetTopLevelWidget() {
220 NativeWidgetPrivate
* native_widget
= GetTopLevelNativeWidget(GetNativeView());
221 return native_widget
? native_widget
->GetWidget() : NULL
;
224 const ui::Compositor
* NativeWidgetAura::GetCompositor() const {
225 return window_
? window_
->layer()->GetCompositor() : NULL
;
228 const ui::Layer
* NativeWidgetAura::GetLayer() const {
229 return window_
? window_
->layer() : NULL
;
232 void NativeWidgetAura::ReorderNativeViews() {
233 window_reorderer_
->ReorderChildWindows();
236 void NativeWidgetAura::ViewRemoved(View
* view
) {
237 DCHECK(drop_helper_
.get() != NULL
);
238 drop_helper_
->ResetTargetViewIfEquals(view
);
241 void NativeWidgetAura::SetNativeWindowProperty(const char* name
, void* value
) {
243 window_
->SetNativeWindowProperty(name
, value
);
246 void* NativeWidgetAura::GetNativeWindowProperty(const char* name
) const {
247 return window_
? window_
->GetNativeWindowProperty(name
) : NULL
;
250 TooltipManager
* NativeWidgetAura::GetTooltipManager() const {
251 return tooltip_manager_
.get();
254 void NativeWidgetAura::SetCapture() {
256 window_
->SetCapture();
259 void NativeWidgetAura::ReleaseCapture() {
261 window_
->ReleaseCapture();
264 bool NativeWidgetAura::HasCapture() const {
265 return window_
&& window_
->HasCapture();
268 ui::InputMethod
* NativeWidgetAura::GetInputMethod() {
271 aura::Window
* root_window
= window_
->GetRootWindow();
272 return root_window
? root_window
->GetHost()->GetInputMethod() : nullptr;
275 void NativeWidgetAura::CenterWindow(const gfx::Size
& size
) {
279 gfx::Rect
parent_bounds(window_
->parent()->GetBoundsInRootWindow());
280 // When centering window, we take the intersection of the host and
281 // the parent. We assume the root window represents the visible
282 // rect of a single screen.
283 gfx::Rect work_area
= gfx::Screen::GetScreenFor(window_
)->
284 GetDisplayNearestWindow(window_
).work_area();
286 aura::client::ScreenPositionClient
* screen_position_client
=
287 aura::client::GetScreenPositionClient(window_
->GetRootWindow());
288 if (screen_position_client
) {
289 gfx::Point origin
= work_area
.origin();
290 screen_position_client
->ConvertPointFromScreen(window_
->GetRootWindow(),
292 work_area
.set_origin(origin
);
295 parent_bounds
.Intersect(work_area
);
297 // If |window_|'s transient parent's bounds are big enough to fit it, then we
298 // center it with respect to the transient parent.
299 if (wm::GetTransientParent(window_
)) {
300 gfx::Rect transient_parent_rect
=
301 wm::GetTransientParent(window_
)->GetBoundsInRootWindow();
302 transient_parent_rect
.Intersect(work_area
);
303 if (transient_parent_rect
.height() >= size
.height() &&
304 transient_parent_rect
.width() >= size
.width())
305 parent_bounds
= transient_parent_rect
;
308 gfx::Rect
window_bounds(
309 parent_bounds
.x() + (parent_bounds
.width() - size
.width()) / 2,
310 parent_bounds
.y() + (parent_bounds
.height() - size
.height()) / 2,
313 // Don't size the window bigger than the parent, otherwise the user may not be
314 // able to close or move it.
315 window_bounds
.AdjustToFit(parent_bounds
);
317 // Convert the bounds back relative to the parent.
318 gfx::Point origin
= window_bounds
.origin();
319 aura::Window::ConvertPointToTarget(window_
->GetRootWindow(),
320 window_
->parent(), &origin
);
321 window_bounds
.set_origin(origin
);
322 window_
->SetBounds(window_bounds
);
325 void NativeWidgetAura::GetWindowPlacement(
327 ui::WindowShowState
* show_state
) const {
328 // The interface specifies returning restored bounds, not current bounds.
329 *bounds
= GetRestoredBounds();
330 *show_state
= window_
? window_
->GetProperty(aura::client::kShowStateKey
) :
331 ui::SHOW_STATE_DEFAULT
;
334 bool NativeWidgetAura::SetWindowTitle(const base::string16
& title
) {
337 if (window_
->title() == title
)
339 window_
->SetTitle(title
);
343 void NativeWidgetAura::SetWindowIcons(const gfx::ImageSkia
& window_icon
,
344 const gfx::ImageSkia
& app_icon
) {
345 // Aura doesn't have window icons.
348 void NativeWidgetAura::InitModalType(ui::ModalType modal_type
) {
349 if (modal_type
!= ui::MODAL_TYPE_NONE
)
350 window_
->SetProperty(aura::client::kModalKey
, modal_type
);
353 gfx::Rect
NativeWidgetAura::GetWindowBoundsInScreen() const {
354 return window_
? window_
->GetBoundsInScreen() : gfx::Rect();
357 gfx::Rect
NativeWidgetAura::GetClientAreaBoundsInScreen() const {
358 // View-to-screen coordinate system transformations depend on this returning
359 // the full window bounds, for example View::ConvertPointToScreen().
360 return window_
? window_
->GetBoundsInScreen() : gfx::Rect();
363 gfx::Rect
NativeWidgetAura::GetRestoredBounds() const {
367 // Restored bounds should only be relevant if the window is minimized,
368 // maximized, fullscreen or docked. However, in some places the code expects
369 // GetRestoredBounds() to return the current window bounds if the window is
370 // not in either state.
371 if (IsMinimized() || IsMaximized() || IsFullscreen()) {
372 // Restore bounds are in screen coordinates, no need to convert.
373 gfx::Rect
* restore_bounds
=
374 window_
->GetProperty(aura::client::kRestoreBoundsKey
);
376 return *restore_bounds
;
378 gfx::Rect bounds
= window_
->GetBoundsInScreen();
380 // Restore bounds are in screen coordinates, no need to convert.
381 gfx::Rect
* restore_bounds
=
382 window_
->GetProperty(aura::client::kRestoreBoundsKey
);
383 // Use current window horizontal offset origin in order to preserve docked
384 // alignment but preserve restored size and vertical offset for the time
385 // when the |window_| gets undocked.
386 if (restore_bounds
) {
387 bounds
.set_size(restore_bounds
->size());
388 bounds
.set_y(restore_bounds
->y());
394 void NativeWidgetAura::SetBounds(const gfx::Rect
& bounds
) {
398 aura::Window
* root
= window_
->GetRootWindow();
400 aura::client::ScreenPositionClient
* screen_position_client
=
401 aura::client::GetScreenPositionClient(root
);
402 if (screen_position_client
) {
403 gfx::Display dst_display
=
404 gfx::Screen::GetScreenFor(window_
)->GetDisplayMatching(bounds
);
405 screen_position_client
->SetBounds(window_
, bounds
, dst_display
);
409 window_
->SetBounds(bounds
);
412 void NativeWidgetAura::SetSize(const gfx::Size
& size
) {
414 window_
->SetBounds(gfx::Rect(window_
->bounds().origin(), size
));
417 void NativeWidgetAura::StackAbove(gfx::NativeView native_view
) {
418 if (window_
&& window_
->parent() &&
419 window_
->parent() == native_view
->parent())
420 window_
->parent()->StackChildAbove(window_
, native_view
);
423 void NativeWidgetAura::StackAtTop() {
425 window_
->parent()->StackChildAtTop(window_
);
428 void NativeWidgetAura::StackBelow(gfx::NativeView native_view
) {
429 if (window_
&& window_
->parent() &&
430 window_
->parent() == native_view
->parent())
431 window_
->parent()->StackChildBelow(window_
, native_view
);
434 void NativeWidgetAura::SetShape(SkRegion
* region
) {
436 window_
->layer()->SetAlphaShape(make_scoped_ptr(region
));
441 void NativeWidgetAura::Close() {
442 // |window_| may already be deleted by parent window. This can happen
443 // when this widget is child widget or has transient parent
444 // and ownership is WIDGET_OWNS_NATIVE_WIDGET.
446 ownership_
== Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
);
448 window_
->SuppressPaint();
450 window_
->SetProperty(aura::client::kModalKey
, ui::MODAL_TYPE_NONE
);
453 if (!close_widget_factory_
.HasWeakPtrs()) {
454 base::MessageLoop::current()->PostTask(
456 base::Bind(&NativeWidgetAura::CloseNow
,
457 close_widget_factory_
.GetWeakPtr()));
461 void NativeWidgetAura::CloseNow() {
465 void NativeWidgetAura::Show() {
466 ShowWithWindowState(ui::SHOW_STATE_NORMAL
);
469 void NativeWidgetAura::Hide() {
474 void NativeWidgetAura::ShowMaximizedWithBounds(
475 const gfx::Rect
& restored_bounds
) {
476 SetRestoreBounds(window_
, restored_bounds
);
477 ShowWithWindowState(ui::SHOW_STATE_MAXIMIZED
);
480 void NativeWidgetAura::ShowWithWindowState(ui::WindowShowState state
) {
484 if (state
== ui::SHOW_STATE_MAXIMIZED
|| state
== ui::SHOW_STATE_FULLSCREEN
||
485 state
== ui::SHOW_STATE_DOCKED
) {
486 window_
->SetProperty(aura::client::kShowStateKey
, state
);
489 if (delegate_
->CanActivate()) {
490 if (state
!= ui::SHOW_STATE_INACTIVE
)
492 // SetInitialFocus() should be always be called, even for
493 // SHOW_STATE_INACTIVE. If the window has to stay inactive, the method will
494 // do the right thing.
495 SetInitialFocus(state
);
499 bool NativeWidgetAura::IsVisible() const {
500 return window_
&& window_
->IsVisible();
503 void NativeWidgetAura::Activate() {
507 // We don't necessarily have a root window yet. This can happen with
508 // constrained windows.
509 if (window_
->GetRootWindow()) {
510 aura::client::GetActivationClient(window_
->GetRootWindow())->ActivateWindow(
513 if (window_
->GetProperty(aura::client::kDrawAttentionKey
))
514 window_
->SetProperty(aura::client::kDrawAttentionKey
, false);
517 void NativeWidgetAura::Deactivate() {
520 aura::client::GetActivationClient(window_
->GetRootWindow())->DeactivateWindow(
524 bool NativeWidgetAura::IsActive() const {
525 return window_
&& wm::IsActiveWindow(window_
);
528 void NativeWidgetAura::SetAlwaysOnTop(bool on_top
) {
530 window_
->SetProperty(aura::client::kAlwaysOnTopKey
, on_top
);
533 bool NativeWidgetAura::IsAlwaysOnTop() const {
534 return window_
&& window_
->GetProperty(aura::client::kAlwaysOnTopKey
);
537 void NativeWidgetAura::SetVisibleOnAllWorkspaces(bool always_visible
) {
538 // Not implemented on chromeos or for child widgets.
541 void NativeWidgetAura::Maximize() {
543 window_
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
546 void NativeWidgetAura::Minimize() {
548 window_
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MINIMIZED
);
551 bool NativeWidgetAura::IsMaximized() const {
552 return window_
&& window_
->GetProperty(aura::client::kShowStateKey
) ==
553 ui::SHOW_STATE_MAXIMIZED
;
556 bool NativeWidgetAura::IsMinimized() const {
557 return window_
&& window_
->GetProperty(aura::client::kShowStateKey
) ==
558 ui::SHOW_STATE_MINIMIZED
;
561 void NativeWidgetAura::Restore() {
563 window_
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
566 void NativeWidgetAura::SetFullscreen(bool fullscreen
) {
567 if (!window_
|| IsFullscreen() == fullscreen
)
568 return; // Nothing to do.
570 // Save window state before entering full screen so that it could restored
571 // when exiting full screen.
573 saved_window_state_
= window_
->GetProperty(aura::client::kShowStateKey
);
575 window_
->SetProperty(
576 aura::client::kShowStateKey
,
577 fullscreen
? ui::SHOW_STATE_FULLSCREEN
: saved_window_state_
);
580 bool NativeWidgetAura::IsFullscreen() const {
581 return window_
&& window_
->GetProperty(aura::client::kShowStateKey
) ==
582 ui::SHOW_STATE_FULLSCREEN
;
585 void NativeWidgetAura::SetOpacity(unsigned char opacity
) {
587 window_
->layer()->SetOpacity(opacity
/ 255.0);
590 void NativeWidgetAura::SetUseDragFrame(bool use_drag_frame
) {
594 void NativeWidgetAura::FlashFrame(bool flash
) {
596 window_
->SetProperty(aura::client::kDrawAttentionKey
, flash
);
599 void NativeWidgetAura::RunShellDrag(View
* view
,
600 const ui::OSExchangeData
& data
,
601 const gfx::Point
& location
,
603 ui::DragDropTypes::DragEventSource source
) {
605 views::RunShellDrag(window_
, data
, location
, operation
, source
);
608 void NativeWidgetAura::SchedulePaintInRect(const gfx::Rect
& rect
) {
610 window_
->SchedulePaintInRect(rect
);
613 void NativeWidgetAura::SetCursor(gfx::NativeCursor cursor
) {
615 aura::client::CursorClient
* cursor_client
=
616 aura::client::GetCursorClient(window_
->GetRootWindow());
618 cursor_client
->SetCursor(cursor
);
621 bool NativeWidgetAura::IsMouseEventsEnabled() const {
624 aura::client::CursorClient
* cursor_client
=
625 aura::client::GetCursorClient(window_
->GetRootWindow());
626 return cursor_client
? cursor_client
->IsMouseEventsEnabled() : true;
629 void NativeWidgetAura::ClearNativeFocus() {
630 aura::client::FocusClient
* client
= aura::client::GetFocusClient(window_
);
631 if (window_
&& client
&& window_
->Contains(client
->GetFocusedWindow()))
632 client
->ResetFocusWithinActiveWindow(window_
);
635 gfx::Rect
NativeWidgetAura::GetWorkAreaBoundsInScreen() const {
638 return gfx::Screen::GetScreenFor(window_
)->
639 GetDisplayNearestWindow(window_
).work_area();
642 Widget::MoveLoopResult
NativeWidgetAura::RunMoveLoop(
643 const gfx::Vector2d
& drag_offset
,
644 Widget::MoveLoopSource source
,
645 Widget::MoveLoopEscapeBehavior escape_behavior
) {
646 // |escape_behavior| is only needed on windows when running the native message
648 if (!window_
|| !window_
->GetRootWindow())
649 return Widget::MOVE_LOOP_CANCELED
;
650 aura::client::WindowMoveClient
* move_client
=
651 aura::client::GetWindowMoveClient(window_
->GetRootWindow());
653 return Widget::MOVE_LOOP_CANCELED
;
656 aura::client::WindowMoveSource window_move_source
=
657 source
== Widget::MOVE_LOOP_SOURCE_MOUSE
?
658 aura::client::WINDOW_MOVE_SOURCE_MOUSE
:
659 aura::client::WINDOW_MOVE_SOURCE_TOUCH
;
660 if (move_client
->RunMoveLoop(window_
, drag_offset
, window_move_source
) ==
661 aura::client::MOVE_SUCCESSFUL
) {
662 return Widget::MOVE_LOOP_SUCCESSFUL
;
664 return Widget::MOVE_LOOP_CANCELED
;
667 void NativeWidgetAura::EndMoveLoop() {
668 if (!window_
|| !window_
->GetRootWindow())
670 aura::client::WindowMoveClient
* move_client
=
671 aura::client::GetWindowMoveClient(window_
->GetRootWindow());
673 move_client
->EndMoveLoop();
676 void NativeWidgetAura::SetVisibilityChangedAnimationsEnabled(bool value
) {
678 window_
->SetProperty(aura::client::kAnimationsDisabledKey
, !value
);
681 void NativeWidgetAura::SetVisibilityAnimationDuration(
682 const base::TimeDelta
& duration
) {
683 wm::SetWindowVisibilityAnimationDuration(window_
, duration
);
686 void NativeWidgetAura::SetVisibilityAnimationTransition(
687 Widget::VisibilityTransition transition
) {
688 wm::WindowVisibilityAnimationTransition wm_transition
= wm::ANIMATE_NONE
;
689 switch (transition
) {
690 case Widget::ANIMATE_SHOW
:
691 wm_transition
= wm::ANIMATE_SHOW
;
693 case Widget::ANIMATE_HIDE
:
694 wm_transition
= wm::ANIMATE_HIDE
;
696 case Widget::ANIMATE_BOTH
:
697 wm_transition
= wm::ANIMATE_BOTH
;
699 case Widget::ANIMATE_NONE
:
700 wm_transition
= wm::ANIMATE_NONE
;
703 wm::SetWindowVisibilityAnimationTransition(window_
, wm_transition
);
706 ui::NativeTheme
* NativeWidgetAura::GetNativeTheme() const {
707 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
708 return DesktopWindowTreeHost::GetNativeTheme(window_
);
710 return ui::NativeThemeAura::instance();
714 void NativeWidgetAura::OnRootViewLayout() {
717 bool NativeWidgetAura::IsTranslucentWindowOpacitySupported() const {
721 void NativeWidgetAura::OnSizeConstraintsChanged() {
722 window_
->SetProperty(aura::client::kCanMaximizeKey
,
723 GetWidget()->widget_delegate()->CanMaximize());
724 window_
->SetProperty(aura::client::kCanMinimizeKey
,
725 GetWidget()->widget_delegate()->CanMinimize());
726 window_
->SetProperty(aura::client::kCanResizeKey
,
727 GetWidget()->widget_delegate()->CanResize());
730 void NativeWidgetAura::RepostNativeEvent(gfx::NativeEvent native_event
) {
731 OnEvent(native_event
);
734 ////////////////////////////////////////////////////////////////////////////////
735 // NativeWidgetAura, aura::WindowDelegate implementation:
737 gfx::Size
NativeWidgetAura::GetMinimumSize() const {
738 return delegate_
->GetMinimumSize();
741 gfx::Size
NativeWidgetAura::GetMaximumSize() const {
742 // If a window have a maximum size, the window should not be
744 DCHECK(delegate_
->GetMaximumSize().IsEmpty() ||
745 !window_
->GetProperty(aura::client::kCanMaximizeKey
));
746 return delegate_
->GetMaximumSize();
749 void NativeWidgetAura::OnBoundsChanged(const gfx::Rect
& old_bounds
,
750 const gfx::Rect
& new_bounds
) {
751 // Assume that if the old bounds was completely empty a move happened. This
752 // handles the case of a maximize animation acquiring the layer (acquiring a
753 // layer results in clearing the bounds).
754 if (old_bounds
.origin() != new_bounds
.origin() ||
755 (old_bounds
== gfx::Rect(0, 0, 0, 0) && !new_bounds
.IsEmpty())) {
756 delegate_
->OnNativeWidgetMove();
758 if (old_bounds
.size() != new_bounds
.size())
759 delegate_
->OnNativeWidgetSizeChanged(new_bounds
.size());
762 gfx::NativeCursor
NativeWidgetAura::GetCursor(const gfx::Point
& point
) {
766 int NativeWidgetAura::GetNonClientComponent(const gfx::Point
& point
) const {
767 return delegate_
->GetNonClientComponent(point
);
770 bool NativeWidgetAura::ShouldDescendIntoChildForEventHandling(
772 const gfx::Point
& location
) {
773 views::WidgetDelegate
* widget_delegate
= GetWidget()->widget_delegate();
774 if (widget_delegate
&&
775 !widget_delegate
->ShouldDescendIntoChildForEventHandling(child
, location
))
778 // Don't descend into |child| if there is a view with a Layer that contains
779 // the point and is stacked above |child|s layer.
780 typedef std::vector
<ui::Layer
*> Layers
;
781 const Layers
& root_layers(delegate_
->GetRootLayers());
782 if (root_layers
.empty())
785 Layers::const_iterator
child_layer_iter(
786 std::find(window_
->layer()->children().begin(),
787 window_
->layer()->children().end(), child
->layer()));
788 if (child_layer_iter
== window_
->layer()->children().end())
791 for (std::vector
<ui::Layer
*>::const_reverse_iterator i
= root_layers
.rbegin();
792 i
!= root_layers
.rend(); ++i
) {
793 ui::Layer
* layer
= *i
;
794 if (layer
->visible() && layer
->bounds().Contains(location
)) {
795 Layers::const_iterator
root_layer_iter(
796 std::find(window_
->layer()->children().begin(),
797 window_
->layer()->children().end(), layer
));
798 if (root_layer_iter
> child_layer_iter
)
805 bool NativeWidgetAura::CanFocus() {
806 return ShouldActivate();
809 void NativeWidgetAura::OnCaptureLost() {
810 delegate_
->OnMouseCaptureLost();
813 void NativeWidgetAura::OnPaint(const ui::PaintContext
& context
) {
814 delegate_
->OnNativeWidgetPaint(context
);
817 void NativeWidgetAura::OnDeviceScaleFactorChanged(float device_scale_factor
) {
818 GetWidget()->DeviceScaleFactorChanged(device_scale_factor
);
821 void NativeWidgetAura::OnWindowDestroying(aura::Window
* window
) {
822 window_
->RemoveObserver(this);
823 delegate_
->OnNativeWidgetDestroying();
825 // If the aura::Window is destroyed, we can no longer show tooltips.
826 tooltip_manager_
.reset();
829 void NativeWidgetAura::OnWindowDestroyed(aura::Window
* window
) {
831 delegate_
->OnNativeWidgetDestroyed();
832 if (ownership_
== Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
)
836 void NativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible
) {
837 delegate_
->OnNativeWidgetVisibilityChanged(visible
);
840 bool NativeWidgetAura::HasHitTestMask() const {
841 return delegate_
->HasHitTestMask();
844 void NativeWidgetAura::GetHitTestMask(gfx::Path
* mask
) const {
846 delegate_
->GetHitTestMask(mask
);
849 ////////////////////////////////////////////////////////////////////////////////
850 // NativeWidgetAura, aura::WindowObserver implementation:
852 void NativeWidgetAura::OnWindowPropertyChanged(aura::Window
* window
,
855 if (key
== aura::client::kShowStateKey
)
856 delegate_
->OnNativeWidgetWindowShowStateChanged();
859 ////////////////////////////////////////////////////////////////////////////////
860 // NativeWidgetAura, ui::EventHandler implementation:
862 void NativeWidgetAura::OnKeyEvent(ui::KeyEvent
* event
) {
864 // Renderer may send a key event back to us if the key event wasn't handled,
865 // and the window may be invisible by that time.
866 if (!window_
->IsVisible())
869 FocusManager
* focus_manager
= GetWidget()->GetFocusManager();
870 delegate_
->OnKeyEvent(event
);
871 if (!event
->handled() && focus_manager
)
872 focus_manager
->OnKeyEvent(*event
);
876 void NativeWidgetAura::OnMouseEvent(ui::MouseEvent
* event
) {
878 DCHECK(window_
->IsVisible());
879 if (event
->type() == ui::ET_MOUSEWHEEL
) {
880 delegate_
->OnMouseEvent(event
);
881 if (event
->handled())
885 if (tooltip_manager_
.get())
886 tooltip_manager_
->UpdateTooltip();
887 TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget());
888 delegate_
->OnMouseEvent(event
);
891 void NativeWidgetAura::OnScrollEvent(ui::ScrollEvent
* event
) {
892 delegate_
->OnScrollEvent(event
);
895 void NativeWidgetAura::OnGestureEvent(ui::GestureEvent
* event
) {
897 DCHECK(window_
->IsVisible() || event
->IsEndingEvent());
898 delegate_
->OnGestureEvent(event
);
901 ////////////////////////////////////////////////////////////////////////////////
902 // NativeWidgetAura, aura::client::ActivationDelegate implementation:
904 bool NativeWidgetAura::ShouldActivate() const {
905 return delegate_
->CanActivate();
908 ////////////////////////////////////////////////////////////////////////////////
909 // NativeWidgetAura, aura::client::ActivationChangeObserver implementation:
911 void NativeWidgetAura::OnWindowActivated(
912 aura::client::ActivationChangeObserver::ActivationReason
,
913 aura::Window
* gained_active
,
914 aura::Window
* lost_active
) {
915 DCHECK(window_
== gained_active
|| window_
== lost_active
);
916 if (GetWidget()->GetFocusManager()) {
917 if (window_
== gained_active
)
918 GetWidget()->GetFocusManager()->RestoreFocusedView();
919 else if (window_
== lost_active
)
920 GetWidget()->GetFocusManager()->StoreFocusedView(true);
922 delegate_
->OnNativeWidgetActivationChanged(window_
== gained_active
);
925 ////////////////////////////////////////////////////////////////////////////////
926 // NativeWidgetAura, aura::client::FocusChangeObserver:
928 void NativeWidgetAura::OnWindowFocused(aura::Window
* gained_focus
,
929 aura::Window
* lost_focus
) {
930 if (window_
== gained_focus
)
931 delegate_
->OnNativeFocus();
932 else if (window_
== lost_focus
)
933 delegate_
->OnNativeBlur();
936 ////////////////////////////////////////////////////////////////////////////////
937 // NativeWidgetAura, aura::WindowDragDropDelegate implementation:
939 void NativeWidgetAura::OnDragEntered(const ui::DropTargetEvent
& event
) {
940 DCHECK(drop_helper_
.get() != NULL
);
941 last_drop_operation_
= drop_helper_
->OnDragOver(event
.data(),
942 event
.location(), event
.source_operations());
945 int NativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent
& event
) {
946 DCHECK(drop_helper_
.get() != NULL
);
947 last_drop_operation_
= drop_helper_
->OnDragOver(event
.data(),
948 event
.location(), event
.source_operations());
949 return last_drop_operation_
;
952 void NativeWidgetAura::OnDragExited() {
953 DCHECK(drop_helper_
.get() != NULL
);
954 drop_helper_
->OnDragExit();
957 int NativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent
& event
) {
958 DCHECK(drop_helper_
.get() != NULL
);
959 return drop_helper_
->OnDrop(event
.data(), event
.location(),
960 last_drop_operation_
);
963 ////////////////////////////////////////////////////////////////////////////////
964 // NativeWidgetAura, protected:
966 NativeWidgetAura::~NativeWidgetAura() {
968 if (ownership_
== Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
)
974 ////////////////////////////////////////////////////////////////////////////////
975 // NativeWidgetAura, private:
977 bool NativeWidgetAura::IsDocked() const {
979 window_
->GetProperty(aura::client::kShowStateKey
) ==
980 ui::SHOW_STATE_DOCKED
;
983 void NativeWidgetAura::SetInitialFocus(ui::WindowShowState show_state
) {
984 // The window does not get keyboard messages unless we focus it.
985 if (!GetWidget()->SetInitialFocus(show_state
))
989 ////////////////////////////////////////////////////////////////////////////////
993 #if defined(OS_WIN) || (defined(USE_X11) && !defined(OS_CHROMEOS))
994 void CloseWindow(aura::Window
* window
) {
996 Widget
* widget
= Widget::GetWidgetForNativeView(window
);
997 if (widget
&& widget
->is_secondary_widget())
998 // To avoid the delay in shutdown caused by using Close which may wait
999 // for animations, use CloseNow. Because this is only used on secondary
1000 // widgets it seems relatively safe to skip the extra processing of
1008 BOOL CALLBACK
WindowCallbackProc(HWND hwnd
, LPARAM lParam
) {
1009 aura::Window
* root_window
=
1010 DesktopWindowTreeHostWin::GetContentWindowForHWND(hwnd
);
1011 CloseWindow(root_window
);
1018 void Widget::CloseAllSecondaryWidgets() {
1020 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc
, 0);
1023 #if defined(USE_X11) && !defined(OS_CHROMEOS)
1024 DesktopWindowTreeHostX11::CleanUpWindowList(CloseWindow
);
1028 bool Widget::ConvertRect(const Widget
* source
,
1029 const Widget
* target
,
1034 namespace internal
{
1036 ////////////////////////////////////////////////////////////////////////////////
1037 // internal::NativeWidgetPrivate, public:
1040 NativeWidgetPrivate
* NativeWidgetPrivate::CreateNativeWidget(
1041 internal::NativeWidgetDelegate
* delegate
) {
1042 return new NativeWidgetAura(delegate
);
1046 NativeWidgetPrivate
* NativeWidgetPrivate::GetNativeWidgetForNativeView(
1047 gfx::NativeView native_view
) {
1048 // Cast must match type supplied to RegisterNativeWidgetForWindow().
1049 return reinterpret_cast<NativeWidgetPrivate
*>(native_view
->user_data());
1053 NativeWidgetPrivate
* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
1054 gfx::NativeWindow native_window
) {
1055 // Cast must match type supplied to RegisterNativeWidgetForWindow().
1056 return reinterpret_cast<NativeWidgetPrivate
*>(native_window
->user_data());
1060 NativeWidgetPrivate
* NativeWidgetPrivate::GetTopLevelNativeWidget(
1061 gfx::NativeView native_view
) {
1062 aura::Window
* window
= native_view
;
1063 NativeWidgetPrivate
* top_level_native_widget
= NULL
;
1065 NativeWidgetPrivate
* native_widget
= GetNativeWidgetForNativeView(window
);
1067 top_level_native_widget
= native_widget
;
1068 window
= window
->parent();
1070 return top_level_native_widget
;
1074 void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view
,
1075 Widget::Widgets
* children
) {
1077 // Code expects widget for |native_view| to be added to |children|.
1078 NativeWidgetPrivate
* native_widget
= static_cast<NativeWidgetPrivate
*>(
1079 GetNativeWidgetForNativeView(native_view
));
1080 if (native_widget
&& native_widget
->GetWidget())
1081 children
->insert(native_widget
->GetWidget());
1084 const aura::Window::Windows
& child_windows
= native_view
->children();
1085 for (aura::Window::Windows::const_iterator i
= child_windows
.begin();
1086 i
!= child_windows
.end(); ++i
) {
1087 GetAllChildWidgets((*i
), children
);
1092 void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view
,
1093 Widget::Widgets
* owned
) {
1094 // Add all owned widgets.
1095 for (aura::Window
* transient_child
: wm::GetTransientChildren(native_view
)) {
1096 NativeWidgetPrivate
* native_widget
= static_cast<NativeWidgetPrivate
*>(
1097 GetNativeWidgetForNativeView(transient_child
));
1098 if (native_widget
&& native_widget
->GetWidget())
1099 owned
->insert(native_widget
->GetWidget());
1100 GetAllOwnedWidgets(transient_child
, owned
);
1103 // Add all child windows.
1104 for (aura::Window
* child
: native_view
->children())
1105 GetAllChildWidgets(child
, owned
);
1109 void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view
,
1110 gfx::NativeView new_parent
) {
1111 DCHECK(native_view
!= new_parent
);
1113 gfx::NativeView previous_parent
= native_view
->parent();
1114 if (previous_parent
== new_parent
)
1117 Widget::Widgets widgets
;
1118 GetAllChildWidgets(native_view
, &widgets
);
1120 // First notify all the widgets that they are being disassociated
1121 // from their previous parent.
1122 for (Widget::Widgets::iterator it
= widgets
.begin();
1123 it
!= widgets
.end(); ++it
) {
1124 (*it
)->NotifyNativeViewHierarchyWillChange();
1128 new_parent
->AddChild(native_view
);
1130 // The following looks weird, but it's the equivalent of what aura has
1131 // always done. (The previous behaviour of aura::Window::SetParent() used
1132 // NULL as a special value that meant ask the WindowTreeClient where things
1135 // This probably isn't strictly correct, but its an invariant that a Window
1136 // in use will be attached to a RootWindow, so we can't just call
1137 // RemoveChild here. The only possible thing that could assign a RootWindow
1138 // in this case is the stacking client of the current RootWindow. This
1139 // matches our previous behaviour; the global stacking client would almost
1140 // always reattach the window to the same RootWindow.
1141 aura::Window
* root_window
= native_view
->GetRootWindow();
1142 aura::client::ParentWindowWithContext(
1143 native_view
, root_window
, root_window
->GetBoundsInScreen());
1146 // And now, notify them that they have a brand new parent.
1147 for (Widget::Widgets::iterator it
= widgets
.begin();
1148 it
!= widgets
.end(); ++it
) {
1149 (*it
)->NotifyNativeViewHierarchyChanged();
1154 bool NativeWidgetPrivate::IsMouseButtonDown() {
1155 return aura::Env::GetInstance()->IsMouseButtonDown();
1159 gfx::FontList
NativeWidgetPrivate::GetWindowTitleFontList() {
1161 NONCLIENTMETRICS_XP ncm
;
1162 base::win::GetNonClientMetrics(&ncm
);
1163 l10n_util::AdjustUIFont(&(ncm
.lfCaptionFont
));
1164 base::win::ScopedHFONT
caption_font(CreateFontIndirect(&(ncm
.lfCaptionFont
)));
1165 return gfx::FontList(gfx::Font(caption_font
));
1167 return gfx::FontList();
1171 } // namespace internal
1172 } // namespace views