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/base/dragdrop/os_exchange_data.h"
20 #include "ui/base/ui_base_switches_util.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/ime/input_method_bridge.h"
30 #include "ui/views/ime/null_input_method.h"
31 #include "ui/views/views_delegate.h"
32 #include "ui/views/widget/drop_helper.h"
33 #include "ui/views/widget/native_widget_delegate.h"
34 #include "ui/views/widget/root_view.h"
35 #include "ui/views/widget/tooltip_manager_aura.h"
36 #include "ui/views/widget/widget_aura_utils.h"
37 #include "ui/views/widget/widget_delegate.h"
38 #include "ui/views/widget/window_reorderer.h"
39 #include "ui/wm/core/shadow_types.h"
40 #include "ui/wm/core/window_util.h"
41 #include "ui/wm/public/activation_client.h"
42 #include "ui/wm/public/drag_drop_client.h"
43 #include "ui/wm/public/window_move_client.h"
44 #include "ui/wm/public/window_types.h"
47 #include "base/win/scoped_gdi_object.h"
48 #include "base/win/win_util.h"
49 #include "ui/base/l10n/l10n_util_win.h"
50 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
53 #if defined(USE_X11) && !defined(OS_CHROMEOS)
54 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
57 #if !defined(OS_CHROMEOS)
58 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
59 #include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
66 void SetRestoreBounds(aura::Window
* window
, const gfx::Rect
& bounds
) {
67 window
->SetProperty(aura::client::kRestoreBoundsKey
, new gfx::Rect(bounds
));
72 ////////////////////////////////////////////////////////////////////////////////
73 // NativeWidgetAura, public:
75 NativeWidgetAura::NativeWidgetAura(internal::NativeWidgetDelegate
* delegate
)
76 : delegate_(delegate
),
77 window_(new aura::Window(this)),
78 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
),
79 close_widget_factory_(this),
81 cursor_(gfx::kNullCursor
),
82 saved_window_state_(ui::SHOW_STATE_DEFAULT
) {
83 aura::client::SetFocusChangeObserver(window_
, this);
84 aura::client::SetActivationChangeObserver(window_
, this);
88 void NativeWidgetAura::RegisterNativeWidgetForWindow(
89 internal::NativeWidgetPrivate
* native_widget
,
90 aura::Window
* window
) {
91 window
->set_user_data(native_widget
);
94 ////////////////////////////////////////////////////////////////////////////////
95 // NativeWidgetAura, internal::NativeWidgetPrivate implementation:
97 void NativeWidgetAura::InitNativeWidget(const Widget::InitParams
& params
) {
98 // Aura needs to know which desktop (Ash or regular) will manage this widget.
99 // See Widget::InitParams::context for details.
100 DCHECK(params
.parent
|| params
.context
);
102 ownership_
= params
.ownership
;
104 RegisterNativeWidgetForWindow(this, window_
);
105 window_
->SetType(GetAuraWindowTypeForWidgetType(params
.type
));
106 window_
->SetProperty(aura::client::kShowStateKey
, params
.show_state
);
107 if (params
.type
== Widget::InitParams::TYPE_BUBBLE
)
108 aura::client::SetHideOnDeactivate(window_
, true);
109 window_
->SetTransparent(
110 params
.opacity
== Widget::InitParams::TRANSLUCENT_WINDOW
);
111 window_
->Init(params
.layer_type
);
112 if (params
.shadow_type
== Widget::InitParams::SHADOW_TYPE_NONE
)
113 SetShadowType(window_
, wm::SHADOW_TYPE_NONE
);
114 else if (params
.shadow_type
== Widget::InitParams::SHADOW_TYPE_DROP
)
115 SetShadowType(window_
, wm::SHADOW_TYPE_RECTANGULAR
);
116 if (params
.type
== Widget::InitParams::TYPE_CONTROL
)
119 delegate_
->OnNativeWidgetCreated(false);
121 gfx::Rect window_bounds
= params
.bounds
;
122 gfx::NativeView parent
= params
.parent
;
123 gfx::NativeView context
= params
.context
;
125 // Set up the transient child before the window is added. This way the
126 // LayoutManager knows the window has a transient parent.
127 if (parent
&& parent
->type() != ui::wm::WINDOW_TYPE_UNKNOWN
) {
128 wm::AddTransientChild(parent
, window_
);
133 // SetAlwaysOnTop before SetParent so that always-on-top container is used.
134 SetAlwaysOnTop(params
.keep_on_top
);
135 // Make sure we have a real |window_bounds|.
136 if (parent
&& window_bounds
== gfx::Rect()) {
137 // If a parent is specified but no bounds are given,
138 // use the origin of the parent's display so that the widget
139 // will be added to the same display as the parent.
140 gfx::Rect bounds
= gfx::Screen::GetScreenFor(parent
)->
141 GetDisplayNearestWindow(parent
).bounds();
142 window_bounds
.set_origin(bounds
.origin());
146 // Set properties before addeing to the parent so that its layout manager
147 // sees the correct values.
148 window_
->SetProperty(aura::client::kCanMaximizeKey
,
149 GetWidget()->widget_delegate()->CanMaximize());
150 window_
->SetProperty(aura::client::kCanResizeKey
,
151 GetWidget()->widget_delegate()->CanResize());
154 parent
->AddChild(window_
);
156 aura::client::ParentWindowWithContext(
157 window_
, context
->GetRootWindow(), window_bounds
);
160 // Start observing property changes.
161 window_
->AddObserver(this);
163 // Wait to set the bounds until we have a parent. That way we can know our
164 // true state/bounds (the LayoutManager may enforce a particular
167 SetRestoreBounds(window_
, window_bounds
);
169 SetBounds(window_bounds
);
170 window_
->set_ignore_events(!params
.accept_events
);
171 DCHECK(GetWidget()->GetRootView());
172 if (params
.type
!= Widget::InitParams::TYPE_TOOLTIP
)
173 tooltip_manager_
.reset(new views::TooltipManagerAura(GetWidget()));
175 drop_helper_
.reset(new DropHelper(GetWidget()->GetRootView()));
176 if (params
.type
!= Widget::InitParams::TYPE_TOOLTIP
&&
177 params
.type
!= Widget::InitParams::TYPE_POPUP
) {
178 aura::client::SetDragDropDelegate(window_
, this);
181 aura::client::SetActivationDelegate(window_
, this);
183 window_reorderer_
.reset(new WindowReorderer(window_
,
184 GetWidget()->GetRootView()));
187 NonClientFrameView
* NativeWidgetAura::CreateNonClientFrameView() {
191 bool NativeWidgetAura::ShouldUseNativeFrame() const {
192 // There is only one frame type for aura.
196 bool NativeWidgetAura::ShouldWindowContentsBeTransparent() const {
200 void NativeWidgetAura::FrameTypeChanged() {
201 // This is called when the Theme has changed; forward the event to the root
203 GetWidget()->ThemeChanged();
204 GetWidget()->GetRootView()->SchedulePaint();
207 Widget
* NativeWidgetAura::GetWidget() {
208 return delegate_
->AsWidget();
211 const Widget
* NativeWidgetAura::GetWidget() const {
212 return delegate_
->AsWidget();
215 gfx::NativeView
NativeWidgetAura::GetNativeView() const {
219 gfx::NativeWindow
NativeWidgetAura::GetNativeWindow() const {
223 Widget
* NativeWidgetAura::GetTopLevelWidget() {
224 NativeWidgetPrivate
* native_widget
= GetTopLevelNativeWidget(GetNativeView());
225 return native_widget
? native_widget
->GetWidget() : NULL
;
228 const ui::Compositor
* NativeWidgetAura::GetCompositor() const {
229 return window_
? window_
->layer()->GetCompositor() : NULL
;
232 ui::Compositor
* NativeWidgetAura::GetCompositor() {
233 return window_
? window_
->layer()->GetCompositor() : NULL
;
236 ui::Layer
* NativeWidgetAura::GetLayer() {
237 return window_
? window_
->layer() : NULL
;
240 void NativeWidgetAura::ReorderNativeViews() {
241 window_reorderer_
->ReorderChildWindows();
244 void NativeWidgetAura::ViewRemoved(View
* view
) {
245 DCHECK(drop_helper_
.get() != NULL
);
246 drop_helper_
->ResetTargetViewIfEquals(view
);
249 void NativeWidgetAura::SetNativeWindowProperty(const char* name
, void* value
) {
251 window_
->SetNativeWindowProperty(name
, value
);
254 void* NativeWidgetAura::GetNativeWindowProperty(const char* name
) const {
255 return window_
? window_
->GetNativeWindowProperty(name
) : NULL
;
258 TooltipManager
* NativeWidgetAura::GetTooltipManager() const {
259 return tooltip_manager_
.get();
262 void NativeWidgetAura::SetCapture() {
264 window_
->SetCapture();
267 void NativeWidgetAura::ReleaseCapture() {
269 window_
->ReleaseCapture();
272 bool NativeWidgetAura::HasCapture() const {
273 return window_
&& window_
->HasCapture();
276 InputMethod
* NativeWidgetAura::CreateInputMethod() {
280 if (switches::IsTextInputFocusManagerEnabled())
281 return new NullInputMethod();
283 aura::Window
* root_window
= window_
->GetRootWindow();
284 ui::InputMethod
* host
=
285 root_window
->GetProperty(aura::client::kRootWindowInputMethodKey
);
286 return new InputMethodBridge(this, host
, true);
289 internal::InputMethodDelegate
* NativeWidgetAura::GetInputMethodDelegate() {
293 ui::InputMethod
* NativeWidgetAura::GetHostInputMethod() {
294 aura::Window
* root_window
= window_
->GetRootWindow();
295 return root_window
->GetProperty(aura::client::kRootWindowInputMethodKey
);
298 void NativeWidgetAura::CenterWindow(const gfx::Size
& size
) {
302 gfx::Rect
parent_bounds(window_
->parent()->GetBoundsInRootWindow());
303 // When centering window, we take the intersection of the host and
304 // the parent. We assume the root window represents the visible
305 // rect of a single screen.
306 gfx::Rect work_area
= gfx::Screen::GetScreenFor(window_
)->
307 GetDisplayNearestWindow(window_
).work_area();
309 aura::client::ScreenPositionClient
* screen_position_client
=
310 aura::client::GetScreenPositionClient(window_
->GetRootWindow());
311 if (screen_position_client
) {
312 gfx::Point origin
= work_area
.origin();
313 screen_position_client
->ConvertPointFromScreen(window_
->GetRootWindow(),
315 work_area
.set_origin(origin
);
318 parent_bounds
.Intersect(work_area
);
320 // If |window_|'s transient parent's bounds are big enough to fit it, then we
321 // center it with respect to the transient parent.
322 if (wm::GetTransientParent(window_
)) {
323 gfx::Rect transient_parent_rect
=
324 wm::GetTransientParent(window_
)->GetBoundsInRootWindow();
325 transient_parent_rect
.Intersect(work_area
);
326 if (transient_parent_rect
.height() >= size
.height() &&
327 transient_parent_rect
.width() >= size
.width())
328 parent_bounds
= transient_parent_rect
;
331 gfx::Rect
window_bounds(
332 parent_bounds
.x() + (parent_bounds
.width() - size
.width()) / 2,
333 parent_bounds
.y() + (parent_bounds
.height() - size
.height()) / 2,
336 // Don't size the window bigger than the parent, otherwise the user may not be
337 // able to close or move it.
338 window_bounds
.AdjustToFit(parent_bounds
);
340 // Convert the bounds back relative to the parent.
341 gfx::Point origin
= window_bounds
.origin();
342 aura::Window::ConvertPointToTarget(window_
->GetRootWindow(),
343 window_
->parent(), &origin
);
344 window_bounds
.set_origin(origin
);
345 window_
->SetBounds(window_bounds
);
348 void NativeWidgetAura::GetWindowPlacement(
350 ui::WindowShowState
* show_state
) const {
351 // The interface specifies returning restored bounds, not current bounds.
352 *bounds
= GetRestoredBounds();
353 *show_state
= window_
? window_
->GetProperty(aura::client::kShowStateKey
) :
354 ui::SHOW_STATE_DEFAULT
;
357 bool NativeWidgetAura::SetWindowTitle(const base::string16
& title
) {
360 if (window_
->title() == title
)
362 window_
->SetTitle(title
);
366 void NativeWidgetAura::SetWindowIcons(const gfx::ImageSkia
& window_icon
,
367 const gfx::ImageSkia
& app_icon
) {
368 // Aura doesn't have window icons.
371 void NativeWidgetAura::InitModalType(ui::ModalType modal_type
) {
372 if (modal_type
!= ui::MODAL_TYPE_NONE
)
373 window_
->SetProperty(aura::client::kModalKey
, modal_type
);
376 gfx::Rect
NativeWidgetAura::GetWindowBoundsInScreen() const {
377 return window_
? window_
->GetBoundsInScreen() : gfx::Rect();
380 gfx::Rect
NativeWidgetAura::GetClientAreaBoundsInScreen() const {
381 // View-to-screen coordinate system transformations depend on this returning
382 // the full window bounds, for example View::ConvertPointToScreen().
383 return window_
? window_
->GetBoundsInScreen() : gfx::Rect();
386 gfx::Rect
NativeWidgetAura::GetRestoredBounds() const {
390 // Restored bounds should only be relevant if the window is minimized or
391 // maximized. However, in some places the code expects GetRestoredBounds()
392 // to return the current window bounds if the window is not in either state.
393 if (IsMinimized() || IsMaximized() || IsFullscreen()) {
394 // Restore bounds are in screen coordinates, no need to convert.
395 gfx::Rect
* restore_bounds
=
396 window_
->GetProperty(aura::client::kRestoreBoundsKey
);
398 return *restore_bounds
;
400 return window_
->GetBoundsInScreen();
403 void NativeWidgetAura::SetBounds(const gfx::Rect
& bounds
) {
407 aura::Window
* root
= window_
->GetRootWindow();
409 aura::client::ScreenPositionClient
* screen_position_client
=
410 aura::client::GetScreenPositionClient(root
);
411 if (screen_position_client
) {
412 gfx::Display dst_display
=
413 gfx::Screen::GetScreenFor(window_
)->GetDisplayMatching(bounds
);
414 screen_position_client
->SetBounds(window_
, bounds
, dst_display
);
418 window_
->SetBounds(bounds
);
421 void NativeWidgetAura::SetSize(const gfx::Size
& size
) {
423 window_
->SetBounds(gfx::Rect(window_
->bounds().origin(), size
));
426 void NativeWidgetAura::StackAbove(gfx::NativeView native_view
) {
427 if (window_
&& window_
->parent() &&
428 window_
->parent() == native_view
->parent())
429 window_
->parent()->StackChildAbove(window_
, native_view
);
432 void NativeWidgetAura::StackAtTop() {
434 window_
->parent()->StackChildAtTop(window_
);
437 void NativeWidgetAura::StackBelow(gfx::NativeView native_view
) {
438 if (window_
&& window_
->parent() &&
439 window_
->parent() == native_view
->parent())
440 window_
->parent()->StackChildBelow(window_
, native_view
);
443 void NativeWidgetAura::SetShape(gfx::NativeRegion region
) {
445 window_
->layer()->SetAlphaShape(make_scoped_ptr(region
));
450 void NativeWidgetAura::Close() {
451 // |window_| may already be deleted by parent window. This can happen
452 // when this widget is child widget or has transient parent
453 // and ownership is WIDGET_OWNS_NATIVE_WIDGET.
455 ownership_
== Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
);
457 window_
->SuppressPaint();
459 window_
->SetProperty(aura::client::kModalKey
, ui::MODAL_TYPE_NONE
);
462 if (!close_widget_factory_
.HasWeakPtrs()) {
463 base::MessageLoop::current()->PostTask(
465 base::Bind(&NativeWidgetAura::CloseNow
,
466 close_widget_factory_
.GetWeakPtr()));
470 void NativeWidgetAura::CloseNow() {
474 void NativeWidgetAura::Show() {
475 ShowWithWindowState(ui::SHOW_STATE_NORMAL
);
478 void NativeWidgetAura::Hide() {
483 void NativeWidgetAura::ShowMaximizedWithBounds(
484 const gfx::Rect
& restored_bounds
) {
485 SetRestoreBounds(window_
, restored_bounds
);
486 ShowWithWindowState(ui::SHOW_STATE_MAXIMIZED
);
489 void NativeWidgetAura::ShowWithWindowState(ui::WindowShowState state
) {
493 if (state
== ui::SHOW_STATE_MAXIMIZED
|| state
== ui::SHOW_STATE_FULLSCREEN
)
494 window_
->SetProperty(aura::client::kShowStateKey
, state
);
496 if (delegate_
->CanActivate()) {
497 if (state
!= ui::SHOW_STATE_INACTIVE
)
499 // SetInitialFocus() should be always be called, even for
500 // SHOW_STATE_INACTIVE. If the window has to stay inactive, the method will
501 // do the right thing.
502 SetInitialFocus(state
);
506 bool NativeWidgetAura::IsVisible() const {
507 return window_
&& window_
->IsVisible();
510 void NativeWidgetAura::Activate() {
514 // We don't necessarily have a root window yet. This can happen with
515 // constrained windows.
516 if (window_
->GetRootWindow()) {
517 aura::client::GetActivationClient(window_
->GetRootWindow())->ActivateWindow(
520 if (window_
->GetProperty(aura::client::kDrawAttentionKey
))
521 window_
->SetProperty(aura::client::kDrawAttentionKey
, false);
524 void NativeWidgetAura::Deactivate() {
527 aura::client::GetActivationClient(window_
->GetRootWindow())->DeactivateWindow(
531 bool NativeWidgetAura::IsActive() const {
532 return window_
&& wm::IsActiveWindow(window_
);
535 void NativeWidgetAura::SetAlwaysOnTop(bool on_top
) {
537 window_
->SetProperty(aura::client::kAlwaysOnTopKey
, on_top
);
540 bool NativeWidgetAura::IsAlwaysOnTop() const {
541 return window_
&& window_
->GetProperty(aura::client::kAlwaysOnTopKey
);
544 void NativeWidgetAura::SetVisibleOnAllWorkspaces(bool always_visible
) {
545 // Not implemented on chromeos or for child widgets.
548 void NativeWidgetAura::Maximize() {
550 window_
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
553 void NativeWidgetAura::Minimize() {
555 window_
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MINIMIZED
);
558 bool NativeWidgetAura::IsMaximized() const {
559 return window_
&& window_
->GetProperty(aura::client::kShowStateKey
) ==
560 ui::SHOW_STATE_MAXIMIZED
;
563 bool NativeWidgetAura::IsMinimized() const {
564 return window_
&& window_
->GetProperty(aura::client::kShowStateKey
) ==
565 ui::SHOW_STATE_MINIMIZED
;
568 void NativeWidgetAura::Restore() {
570 window_
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
573 void NativeWidgetAura::SetFullscreen(bool fullscreen
) {
574 if (!window_
|| IsFullscreen() == fullscreen
)
575 return; // Nothing to do.
577 // Save window state before entering full screen so that it could restored
578 // when exiting full screen.
580 saved_window_state_
= window_
->GetProperty(aura::client::kShowStateKey
);
582 window_
->SetProperty(
583 aura::client::kShowStateKey
,
584 fullscreen
? ui::SHOW_STATE_FULLSCREEN
: saved_window_state_
);
587 bool NativeWidgetAura::IsFullscreen() const {
588 return window_
&& window_
->GetProperty(aura::client::kShowStateKey
) ==
589 ui::SHOW_STATE_FULLSCREEN
;
592 void NativeWidgetAura::SetOpacity(unsigned char opacity
) {
594 window_
->layer()->SetOpacity(opacity
/ 255.0);
597 void NativeWidgetAura::SetUseDragFrame(bool use_drag_frame
) {
601 void NativeWidgetAura::FlashFrame(bool flash
) {
603 window_
->SetProperty(aura::client::kDrawAttentionKey
, flash
);
606 void NativeWidgetAura::RunShellDrag(View
* view
,
607 const ui::OSExchangeData
& data
,
608 const gfx::Point
& location
,
610 ui::DragDropTypes::DragEventSource source
) {
612 views::RunShellDrag(window_
, data
, location
, operation
, source
);
615 void NativeWidgetAura::SchedulePaintInRect(const gfx::Rect
& rect
) {
617 window_
->SchedulePaintInRect(rect
);
620 void NativeWidgetAura::SetCursor(gfx::NativeCursor cursor
) {
622 aura::client::CursorClient
* cursor_client
=
623 aura::client::GetCursorClient(window_
->GetRootWindow());
625 cursor_client
->SetCursor(cursor
);
628 bool NativeWidgetAura::IsMouseEventsEnabled() const {
631 aura::client::CursorClient
* cursor_client
=
632 aura::client::GetCursorClient(window_
->GetRootWindow());
633 return cursor_client
? cursor_client
->IsMouseEventsEnabled() : true;
636 void NativeWidgetAura::ClearNativeFocus() {
637 aura::client::FocusClient
* client
= aura::client::GetFocusClient(window_
);
638 if (window_
&& client
&& window_
->Contains(client
->GetFocusedWindow()))
639 client
->ResetFocusWithinActiveWindow(window_
);
642 gfx::Rect
NativeWidgetAura::GetWorkAreaBoundsInScreen() const {
645 return gfx::Screen::GetScreenFor(window_
)->
646 GetDisplayNearestWindow(window_
).work_area();
649 Widget::MoveLoopResult
NativeWidgetAura::RunMoveLoop(
650 const gfx::Vector2d
& drag_offset
,
651 Widget::MoveLoopSource source
,
652 Widget::MoveLoopEscapeBehavior escape_behavior
) {
653 // |escape_behavior| is only needed on windows when running the native message
655 if (!window_
|| !window_
->GetRootWindow())
656 return Widget::MOVE_LOOP_CANCELED
;
657 aura::client::WindowMoveClient
* move_client
=
658 aura::client::GetWindowMoveClient(window_
->GetRootWindow());
660 return Widget::MOVE_LOOP_CANCELED
;
663 aura::client::WindowMoveSource window_move_source
=
664 source
== Widget::MOVE_LOOP_SOURCE_MOUSE
?
665 aura::client::WINDOW_MOVE_SOURCE_MOUSE
:
666 aura::client::WINDOW_MOVE_SOURCE_TOUCH
;
667 if (move_client
->RunMoveLoop(window_
, drag_offset
, window_move_source
) ==
668 aura::client::MOVE_SUCCESSFUL
) {
669 return Widget::MOVE_LOOP_SUCCESSFUL
;
671 return Widget::MOVE_LOOP_CANCELED
;
674 void NativeWidgetAura::EndMoveLoop() {
675 if (!window_
|| !window_
->GetRootWindow())
677 aura::client::WindowMoveClient
* move_client
=
678 aura::client::GetWindowMoveClient(window_
->GetRootWindow());
680 move_client
->EndMoveLoop();
683 void NativeWidgetAura::SetVisibilityChangedAnimationsEnabled(bool value
) {
685 window_
->SetProperty(aura::client::kAnimationsDisabledKey
, !value
);
688 ui::NativeTheme
* NativeWidgetAura::GetNativeTheme() const {
689 #if !defined(OS_CHROMEOS)
690 return DesktopWindowTreeHost::GetNativeTheme(window_
);
692 return ui::NativeThemeAura::instance();
696 void NativeWidgetAura::OnRootViewLayout() {
699 bool NativeWidgetAura::IsTranslucentWindowOpacitySupported() const {
703 void NativeWidgetAura::RepostNativeEvent(gfx::NativeEvent native_event
) {
704 OnEvent(native_event
);
707 ////////////////////////////////////////////////////////////////////////////////
708 // NativeWidgetAura, views::InputMethodDelegate implementation:
710 void NativeWidgetAura::DispatchKeyEventPostIME(const ui::KeyEvent
& key
) {
711 FocusManager
* focus_manager
= GetWidget()->GetFocusManager();
712 delegate_
->OnKeyEvent(const_cast<ui::KeyEvent
*>(&key
));
713 if (key
.handled() || !focus_manager
)
715 focus_manager
->OnKeyEvent(key
);
718 ////////////////////////////////////////////////////////////////////////////////
719 // NativeWidgetAura, aura::WindowDelegate implementation:
721 gfx::Size
NativeWidgetAura::GetMinimumSize() const {
722 return delegate_
->GetMinimumSize();
725 gfx::Size
NativeWidgetAura::GetMaximumSize() const {
726 // If a window have a maximum size, the window should not be
728 DCHECK(delegate_
->GetMaximumSize().IsEmpty() ||
729 !window_
->GetProperty(aura::client::kCanMaximizeKey
));
730 return delegate_
->GetMaximumSize();
733 void NativeWidgetAura::OnBoundsChanged(const gfx::Rect
& old_bounds
,
734 const gfx::Rect
& new_bounds
) {
735 // Assume that if the old bounds was completely empty a move happened. This
736 // handles the case of a maximize animation acquiring the layer (acquiring a
737 // layer results in clearing the bounds).
738 if (old_bounds
.origin() != new_bounds
.origin() ||
739 (old_bounds
== gfx::Rect(0, 0, 0, 0) && !new_bounds
.IsEmpty())) {
740 delegate_
->OnNativeWidgetMove();
742 if (old_bounds
.size() != new_bounds
.size())
743 delegate_
->OnNativeWidgetSizeChanged(new_bounds
.size());
746 gfx::NativeCursor
NativeWidgetAura::GetCursor(const gfx::Point
& point
) {
750 int NativeWidgetAura::GetNonClientComponent(const gfx::Point
& point
) const {
751 return delegate_
->GetNonClientComponent(point
);
754 bool NativeWidgetAura::ShouldDescendIntoChildForEventHandling(
756 const gfx::Point
& location
) {
757 views::WidgetDelegate
* widget_delegate
= GetWidget()->widget_delegate();
758 if (widget_delegate
&&
759 !widget_delegate
->ShouldDescendIntoChildForEventHandling(child
, location
))
762 // Don't descend into |child| if there is a view with a Layer that contains
763 // the point and is stacked above |child|s layer.
764 typedef std::vector
<ui::Layer
*> Layers
;
765 const Layers
& root_layers(delegate_
->GetRootLayers());
766 if (root_layers
.empty())
769 Layers::const_iterator
child_layer_iter(
770 std::find(window_
->layer()->children().begin(),
771 window_
->layer()->children().end(), child
->layer()));
772 if (child_layer_iter
== window_
->layer()->children().end())
775 for (std::vector
<ui::Layer
*>::const_reverse_iterator i
= root_layers
.rbegin();
776 i
!= root_layers
.rend(); ++i
) {
777 ui::Layer
* layer
= *i
;
778 if (layer
->visible() && layer
->bounds().Contains(location
)) {
779 Layers::const_iterator
root_layer_iter(
780 std::find(window_
->layer()->children().begin(),
781 window_
->layer()->children().end(), layer
));
782 if (root_layer_iter
> child_layer_iter
)
789 bool NativeWidgetAura::CanFocus() {
790 return ShouldActivate();
793 void NativeWidgetAura::OnCaptureLost() {
794 delegate_
->OnMouseCaptureLost();
797 void NativeWidgetAura::OnPaint(gfx::Canvas
* canvas
) {
798 delegate_
->OnNativeWidgetPaint(canvas
);
801 void NativeWidgetAura::OnDeviceScaleFactorChanged(float device_scale_factor
) {
802 // Repainting with new scale factor will paint the content at the right scale.
805 void NativeWidgetAura::OnWindowDestroying(aura::Window
* window
) {
806 window_
->RemoveObserver(this);
807 delegate_
->OnNativeWidgetDestroying();
809 // If the aura::Window is destroyed, we can no longer show tooltips.
810 tooltip_manager_
.reset();
813 void NativeWidgetAura::OnWindowDestroyed(aura::Window
* window
) {
815 delegate_
->OnNativeWidgetDestroyed();
816 if (ownership_
== Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
)
820 void NativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible
) {
821 delegate_
->OnNativeWidgetVisibilityChanged(visible
);
824 bool NativeWidgetAura::HasHitTestMask() const {
825 return delegate_
->HasHitTestMask();
828 void NativeWidgetAura::GetHitTestMask(gfx::Path
* mask
) const {
830 delegate_
->GetHitTestMask(mask
);
833 ////////////////////////////////////////////////////////////////////////////////
834 // NativeWidgetAura, aura::WindowObserver implementation:
836 void NativeWidgetAura::OnWindowPropertyChanged(aura::Window
* window
,
839 if (key
== aura::client::kShowStateKey
)
840 delegate_
->OnNativeWidgetWindowShowStateChanged();
843 ////////////////////////////////////////////////////////////////////////////////
844 // NativeWidgetAura, ui::EventHandler implementation:
846 void NativeWidgetAura::OnKeyEvent(ui::KeyEvent
* event
) {
848 if (event
->is_char()) {
849 // If a ui::InputMethod object is attached to the root window, character
850 // events are handled inside the object and are not passed to this function.
851 // If such object is not attached, character events might be sent (e.g. on
852 // Windows). In this case, we just skip these.
855 // Renderer may send a key event back to us if the key event wasn't handled,
856 // and the window may be invisible by that time.
857 if (!window_
->IsVisible())
859 GetWidget()->GetInputMethod()->DispatchKeyEvent(*event
);
860 if (switches::IsTextInputFocusManagerEnabled()) {
861 FocusManager
* focus_manager
= GetWidget()->GetFocusManager();
862 delegate_
->OnKeyEvent(event
);
863 if (!event
->handled() && focus_manager
)
864 focus_manager
->OnKeyEvent(*event
);
869 void NativeWidgetAura::OnMouseEvent(ui::MouseEvent
* event
) {
871 DCHECK(window_
->IsVisible());
872 if (event
->type() == ui::ET_MOUSEWHEEL
) {
873 delegate_
->OnMouseEvent(event
);
874 if (event
->handled())
878 if (tooltip_manager_
.get())
879 tooltip_manager_
->UpdateTooltip();
880 TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget());
881 delegate_
->OnMouseEvent(event
);
884 void NativeWidgetAura::OnScrollEvent(ui::ScrollEvent
* event
) {
885 delegate_
->OnScrollEvent(event
);
888 void NativeWidgetAura::OnGestureEvent(ui::GestureEvent
* event
) {
890 DCHECK(window_
->IsVisible() || event
->IsEndingEvent());
891 delegate_
->OnGestureEvent(event
);
894 ////////////////////////////////////////////////////////////////////////////////
895 // NativeWidgetAura, aura::client::ActivationDelegate implementation:
897 bool NativeWidgetAura::ShouldActivate() const {
898 return delegate_
->CanActivate();
901 ////////////////////////////////////////////////////////////////////////////////
902 // NativeWidgetAura, aura::client::ActivationChangeObserver implementation:
904 void NativeWidgetAura::OnWindowActivated(aura::Window
* gained_active
,
905 aura::Window
* lost_active
) {
906 DCHECK(window_
== gained_active
|| window_
== lost_active
);
907 if (GetWidget()->GetFocusManager()) {
908 if (window_
== gained_active
)
909 GetWidget()->GetFocusManager()->RestoreFocusedView();
910 else if (window_
== lost_active
)
911 GetWidget()->GetFocusManager()->StoreFocusedView(true);
913 delegate_
->OnNativeWidgetActivationChanged(window_
== gained_active
);
916 ////////////////////////////////////////////////////////////////////////////////
917 // NativeWidgetAura, aura::client::FocusChangeObserver:
919 void NativeWidgetAura::OnWindowFocused(aura::Window
* gained_focus
,
920 aura::Window
* lost_focus
) {
921 if (window_
== gained_focus
) {
922 // In aura, it is possible for child native widgets to take input and focus,
923 // this differs from the behavior on windows.
924 if (GetWidget()->GetInputMethod()) // Null in tests.
925 GetWidget()->GetInputMethod()->OnFocus();
926 delegate_
->OnNativeFocus(lost_focus
);
927 } else if (window_
== lost_focus
) {
928 // GetInputMethod() recreates the input method if it's previously been
929 // destroyed. If we get called during destruction, the input method will be
930 // gone, and creating a new one and telling it that we lost the focus will
931 // trigger a DCHECK (the new input method doesn't think that we have the
932 // focus and doesn't expect a blur). OnBlur() shouldn't be called during
933 // destruction unless WIDGET_OWNS_NATIVE_WIDGET is set (which is just the
936 if (GetWidget()->GetInputMethod())
937 GetWidget()->GetInputMethod()->OnBlur();
939 DCHECK_EQ(ownership_
, Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
);
942 delegate_
->OnNativeBlur(gained_focus
);
946 ////////////////////////////////////////////////////////////////////////////////
947 // NativeWidgetAura, aura::WindowDragDropDelegate implementation:
949 void NativeWidgetAura::OnDragEntered(const ui::DropTargetEvent
& event
) {
950 DCHECK(drop_helper_
.get() != NULL
);
951 last_drop_operation_
= drop_helper_
->OnDragOver(event
.data(),
952 event
.location(), event
.source_operations());
955 int NativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent
& event
) {
956 DCHECK(drop_helper_
.get() != NULL
);
957 last_drop_operation_
= drop_helper_
->OnDragOver(event
.data(),
958 event
.location(), event
.source_operations());
959 return last_drop_operation_
;
962 void NativeWidgetAura::OnDragExited() {
963 DCHECK(drop_helper_
.get() != NULL
);
964 drop_helper_
->OnDragExit();
967 int NativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent
& event
) {
968 DCHECK(drop_helper_
.get() != NULL
);
969 return drop_helper_
->OnDrop(event
.data(), event
.location(),
970 last_drop_operation_
);
973 ////////////////////////////////////////////////////////////////////////////////
974 // NativeWidgetAura, protected:
976 NativeWidgetAura::~NativeWidgetAura() {
978 if (ownership_
== Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
)
984 ////////////////////////////////////////////////////////////////////////////////
985 // NativeWidgetAura, private:
987 void NativeWidgetAura::SetInitialFocus(ui::WindowShowState show_state
) {
988 // The window does not get keyboard messages unless we focus it.
989 if (!GetWidget()->SetInitialFocus(show_state
))
993 ////////////////////////////////////////////////////////////////////////////////
997 #if defined(OS_WIN) || (defined(USE_X11) && !defined(OS_CHROMEOS))
998 void CloseWindow(aura::Window
* window
) {
1000 Widget
* widget
= Widget::GetWidgetForNativeView(window
);
1001 if (widget
&& widget
->is_secondary_widget())
1002 // To avoid the delay in shutdown caused by using Close which may wait
1003 // for animations, use CloseNow. Because this is only used on secondary
1004 // widgets it seems relatively safe to skip the extra processing of
1012 BOOL CALLBACK
WindowCallbackProc(HWND hwnd
, LPARAM lParam
) {
1013 aura::Window
* root_window
=
1014 DesktopWindowTreeHostWin::GetContentWindowForHWND(hwnd
);
1015 CloseWindow(root_window
);
1022 void Widget::CloseAllSecondaryWidgets() {
1024 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc
, 0);
1027 #if defined(USE_X11) && !defined(OS_CHROMEOS)
1028 std::vector
<aura::Window
*> open_windows
=
1029 DesktopWindowTreeHostX11::GetAllOpenWindows();
1030 std::for_each(open_windows
.begin(), open_windows
.end(), CloseWindow
);
1031 DesktopWindowTreeHostX11::CleanUpWindowList();
1035 bool Widget::ConvertRect(const Widget
* source
,
1036 const Widget
* target
,
1041 namespace internal
{
1043 ////////////////////////////////////////////////////////////////////////////////
1044 // internal::NativeWidgetPrivate, public:
1047 NativeWidgetPrivate
* NativeWidgetPrivate::CreateNativeWidget(
1048 internal::NativeWidgetDelegate
* delegate
) {
1049 return new NativeWidgetAura(delegate
);
1053 NativeWidgetPrivate
* NativeWidgetPrivate::GetNativeWidgetForNativeView(
1054 gfx::NativeView native_view
) {
1055 // Cast must match type supplied to RegisterNativeWidgetForWindow().
1056 return reinterpret_cast<NativeWidgetPrivate
*>(native_view
->user_data());
1060 NativeWidgetPrivate
* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
1061 gfx::NativeWindow native_window
) {
1062 // Cast must match type supplied to RegisterNativeWidgetForWindow().
1063 return reinterpret_cast<NativeWidgetPrivate
*>(native_window
->user_data());
1067 NativeWidgetPrivate
* NativeWidgetPrivate::GetTopLevelNativeWidget(
1068 gfx::NativeView native_view
) {
1069 aura::Window
* window
= native_view
;
1070 NativeWidgetPrivate
* top_level_native_widget
= NULL
;
1072 NativeWidgetPrivate
* native_widget
= GetNativeWidgetForNativeView(window
);
1074 top_level_native_widget
= native_widget
;
1075 window
= window
->parent();
1077 return top_level_native_widget
;
1081 void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view
,
1082 Widget::Widgets
* children
) {
1084 // Code expects widget for |native_view| to be added to |children|.
1085 NativeWidgetPrivate
* native_widget
= static_cast<NativeWidgetPrivate
*>(
1086 GetNativeWidgetForNativeView(native_view
));
1087 if (native_widget
&& native_widget
->GetWidget())
1088 children
->insert(native_widget
->GetWidget());
1091 const aura::Window::Windows
& child_windows
= native_view
->children();
1092 for (aura::Window::Windows::const_iterator i
= child_windows
.begin();
1093 i
!= child_windows
.end(); ++i
) {
1094 GetAllChildWidgets((*i
), children
);
1099 void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view
,
1100 Widget::Widgets
* owned
) {
1101 const aura::Window::Windows
& transient_children
=
1102 wm::GetTransientChildren(native_view
);
1103 for (aura::Window::Windows::const_iterator i
= transient_children
.begin();
1104 i
!= transient_children
.end(); ++i
) {
1105 NativeWidgetPrivate
* native_widget
= static_cast<NativeWidgetPrivate
*>(
1106 GetNativeWidgetForNativeView(*i
));
1107 if (native_widget
&& native_widget
->GetWidget())
1108 owned
->insert(native_widget
->GetWidget());
1109 GetAllOwnedWidgets((*i
), owned
);
1114 void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view
,
1115 gfx::NativeView new_parent
) {
1116 DCHECK(native_view
!= new_parent
);
1118 gfx::NativeView previous_parent
= native_view
->parent();
1119 if (previous_parent
== new_parent
)
1122 Widget::Widgets widgets
;
1123 GetAllChildWidgets(native_view
, &widgets
);
1125 // First notify all the widgets that they are being disassociated
1126 // from their previous parent.
1127 for (Widget::Widgets::iterator it
= widgets
.begin();
1128 it
!= widgets
.end(); ++it
) {
1129 (*it
)->NotifyNativeViewHierarchyWillChange();
1133 new_parent
->AddChild(native_view
);
1135 // The following looks weird, but it's the equivalent of what aura has
1136 // always done. (The previous behaviour of aura::Window::SetParent() used
1137 // NULL as a special value that meant ask the WindowTreeClient where things
1140 // This probably isn't strictly correct, but its an invariant that a Window
1141 // in use will be attached to a RootWindow, so we can't just call
1142 // RemoveChild here. The only possible thing that could assign a RootWindow
1143 // in this case is the stacking client of the current RootWindow. This
1144 // matches our previous behaviour; the global stacking client would almost
1145 // always reattach the window to the same RootWindow.
1146 aura::Window
* root_window
= native_view
->GetRootWindow();
1147 aura::client::ParentWindowWithContext(
1148 native_view
, root_window
, root_window
->GetBoundsInScreen());
1151 // And now, notify them that they have a brand new parent.
1152 for (Widget::Widgets::iterator it
= widgets
.begin();
1153 it
!= widgets
.end(); ++it
) {
1154 (*it
)->NotifyNativeViewHierarchyChanged();
1159 bool NativeWidgetPrivate::IsMouseButtonDown() {
1160 return aura::Env::GetInstance()->IsMouseButtonDown();
1164 gfx::FontList
NativeWidgetPrivate::GetWindowTitleFontList() {
1166 NONCLIENTMETRICS ncm
;
1167 base::win::GetNonClientMetrics(&ncm
);
1168 l10n_util::AdjustUIFont(&(ncm
.lfCaptionFont
));
1169 base::win::ScopedHFONT
caption_font(CreateFontIndirect(&(ncm
.lfCaptionFont
)));
1170 return gfx::FontList(gfx::Font(caption_font
));
1172 return gfx::FontList();
1176 } // namespace internal
1177 } // namespace views