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/activation_client.h"
11 #include "ui/aura/client/aura_constants.h"
12 #include "ui/aura/client/cursor_client.h"
13 #include "ui/aura/client/drag_drop_client.h"
14 #include "ui/aura/client/focus_client.h"
15 #include "ui/aura/client/screen_position_client.h"
16 #include "ui/aura/client/window_move_client.h"
17 #include "ui/aura/client/window_tree_client.h"
18 #include "ui/aura/client/window_types.h"
19 #include "ui/aura/env.h"
20 #include "ui/aura/root_window.h"
21 #include "ui/aura/window.h"
22 #include "ui/aura/window_observer.h"
23 #include "ui/base/dragdrop/os_exchange_data.h"
24 #include "ui/base/ui_base_types.h"
25 #include "ui/compositor/layer.h"
26 #include "ui/events/event.h"
27 #include "ui/gfx/canvas.h"
28 #include "ui/gfx/font.h"
29 #include "ui/gfx/screen.h"
30 #include "ui/native_theme/native_theme_aura.h"
31 #include "ui/views/drag_utils.h"
32 #include "ui/views/ime/input_method_bridge.h"
33 #include "ui/views/views_delegate.h"
34 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
35 #include "ui/views/widget/drop_helper.h"
36 #include "ui/views/widget/native_widget_delegate.h"
37 #include "ui/views/widget/root_view.h"
38 #include "ui/views/widget/tooltip_manager_aura.h"
39 #include "ui/views/widget/widget_aura_utils.h"
40 #include "ui/views/widget/widget_delegate.h"
41 #include "ui/views/widget/window_reorderer.h"
44 #include "base/win/scoped_gdi_object.h"
45 #include "base/win/win_util.h"
46 #include "ui/base/l10n/l10n_util_win.h"
47 #include "ui/views/widget/desktop_aura/desktop_root_window_host_win.h"
50 #if defined(USE_X11) && !defined(OS_CHROMEOS)
51 #include "ui/views/widget/desktop_aura/desktop_root_window_host_x11.h"
54 #if !defined(OS_CHROMEOS)
55 #include "ui/views/widget/desktop_aura/desktop_root_window_host.h"
62 void SetRestoreBounds(aura::Window
* window
, const gfx::Rect
& bounds
) {
63 window
->SetProperty(aura::client::kRestoreBoundsKey
, new gfx::Rect(bounds
));
68 ////////////////////////////////////////////////////////////////////////////////
69 // NativeWidgetAura, public:
71 NativeWidgetAura::NativeWidgetAura(internal::NativeWidgetDelegate
* delegate
)
72 : delegate_(delegate
),
73 window_(new aura::Window(this)),
74 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
),
75 close_widget_factory_(this),
78 cursor_(gfx::kNullCursor
),
79 saved_window_state_(ui::SHOW_STATE_DEFAULT
) {
80 aura::client::SetFocusChangeObserver(window_
, this);
81 aura::client::SetActivationChangeObserver(window_
, this);
85 gfx::Font
NativeWidgetAura::GetWindowTitleFont() {
88 base::win::GetNonClientMetrics(&ncm
);
89 l10n_util::AdjustUIFont(&(ncm
.lfCaptionFont
));
90 base::win::ScopedHFONT
caption_font(CreateFontIndirect(&(ncm
.lfCaptionFont
)));
91 return gfx::Font(caption_font
);
98 void NativeWidgetAura::RegisterNativeWidgetForWindow(
99 internal::NativeWidgetPrivate
* native_widget
,
100 aura::Window
* window
) {
101 window
->set_user_data(native_widget
);
104 ////////////////////////////////////////////////////////////////////////////////
105 // NativeWidgetAura, internal::NativeWidgetPrivate implementation:
107 void NativeWidgetAura::InitNativeWidget(const Widget::InitParams
& params
) {
108 // Aura needs to know which desktop (Ash or regular) will manage this widget.
109 // See Widget::InitParams::context for details.
110 DCHECK(params
.parent
|| params
.context
);
112 ownership_
= params
.ownership
;
114 RegisterNativeWidgetForWindow(this, window_
);
115 window_
->SetType(GetAuraWindowTypeForWidgetType(params
.type
));
116 window_
->SetProperty(aura::client::kShowStateKey
, params
.show_state
);
117 if (params
.type
== Widget::InitParams::TYPE_BUBBLE
)
118 aura::client::SetHideOnDeactivate(window_
, true);
119 window_
->SetTransparent(
120 params
.opacity
== Widget::InitParams::TRANSLUCENT_WINDOW
);
121 window_
->Init(params
.layer_type
);
122 if (params
.type
== Widget::InitParams::TYPE_CONTROL
)
125 delegate_
->OnNativeWidgetCreated(false);
127 gfx::Rect window_bounds
= params
.bounds
;
128 gfx::NativeView parent
= params
.parent
;
129 gfx::NativeView context
= params
.context
;
131 // Set up the transient child before the window is added. This way the
132 // LayoutManager knows the window has a transient parent.
133 if (parent
&& parent
->type() != aura::client::WINDOW_TYPE_UNKNOWN
) {
134 parent
->AddTransientChild(window_
);
139 // SetAlwaysOnTop before SetParent so that always-on-top container is used.
140 SetAlwaysOnTop(params
.keep_on_top
);
141 // Make sure we have a real |window_bounds|.
142 if (parent
&& window_bounds
== gfx::Rect()) {
143 // If a parent is specified but no bounds are given,
144 // use the origin of the parent's display so that the widget
145 // will be added to the same display as the parent.
146 gfx::Rect bounds
= gfx::Screen::GetScreenFor(parent
)->
147 GetDisplayNearestWindow(parent
).bounds();
148 window_bounds
.set_origin(bounds
.origin());
153 parent
->AddChild(window_
);
155 aura::client::ParentWindowWithContext(
156 window_
, context
->GetRootWindow(), window_bounds
);
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 can_activate_
= params
.can_activate
&&
168 params
.type
!= Widget::InitParams::TYPE_CONTROL
&&
169 params
.type
!= Widget::InitParams::TYPE_TOOLTIP
;
170 DCHECK(GetWidget()->GetRootView());
171 if (params
.type
!= Widget::InitParams::TYPE_TOOLTIP
)
172 tooltip_manager_
.reset(new views::TooltipManagerAura(GetWidget()));
174 drop_helper_
.reset(new DropHelper(GetWidget()->GetRootView()));
175 if (params
.type
!= Widget::InitParams::TYPE_TOOLTIP
&&
176 params
.type
!= Widget::InitParams::TYPE_POPUP
) {
177 aura::client::SetDragDropDelegate(window_
, this);
180 aura::client::SetActivationDelegate(window_
, this);
182 window_
->SetProperty(aura::client::kCanMaximizeKey
,
183 GetWidget()->widget_delegate()->CanMaximize());
184 window_
->SetProperty(aura::client::kCanResizeKey
,
185 GetWidget()->widget_delegate()->CanResize());
187 window_reorderer_
.reset(new WindowReorderer(window_
,
188 GetWidget()->GetRootView()));
191 NonClientFrameView
* NativeWidgetAura::CreateNonClientFrameView() {
195 bool NativeWidgetAura::ShouldUseNativeFrame() const {
196 // There is only one frame type for aura.
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() {
279 aura::Window
* root_window
= window_
->GetRootWindow();
280 ui::InputMethod
* host
=
281 root_window
->GetProperty(aura::client::kRootWindowInputMethodKey
);
282 return new InputMethodBridge(this, host
, true);
285 internal::InputMethodDelegate
* NativeWidgetAura::GetInputMethodDelegate() {
289 void NativeWidgetAura::CenterWindow(const gfx::Size
& size
) {
293 gfx::Rect
parent_bounds(window_
->parent()->GetBoundsInRootWindow());
294 // When centering window, we take the intersection of the host and
295 // the parent. We assume the root window represents the visible
296 // rect of a single screen.
297 gfx::Rect work_area
= gfx::Screen::GetScreenFor(window_
)->
298 GetDisplayNearestWindow(window_
).work_area();
300 aura::client::ScreenPositionClient
* screen_position_client
=
301 aura::client::GetScreenPositionClient(window_
->GetRootWindow());
302 if (screen_position_client
) {
303 gfx::Point origin
= work_area
.origin();
304 screen_position_client
->ConvertPointFromScreen(window_
->GetRootWindow(),
306 work_area
.set_origin(origin
);
309 parent_bounds
.Intersect(work_area
);
311 // If |window_|'s transient parent's bounds are big enough to fit it, then we
312 // center it with respect to the transient parent.
313 if (window_
->transient_parent()) {
314 gfx::Rect transient_parent_rect
= window_
->transient_parent()->
315 GetBoundsInRootWindow();
316 transient_parent_rect
.Intersect(work_area
);
317 if (transient_parent_rect
.height() >= size
.height() &&
318 transient_parent_rect
.width() >= size
.width())
319 parent_bounds
= transient_parent_rect
;
322 gfx::Rect
window_bounds(
323 parent_bounds
.x() + (parent_bounds
.width() - size
.width()) / 2,
324 parent_bounds
.y() + (parent_bounds
.height() - size
.height()) / 2,
327 // Don't size the window bigger than the parent, otherwise the user may not be
328 // able to close or move it.
329 window_bounds
.AdjustToFit(parent_bounds
);
331 // Convert the bounds back relative to the parent.
332 gfx::Point origin
= window_bounds
.origin();
333 aura::Window::ConvertPointToTarget(window_
->GetRootWindow(),
334 window_
->parent(), &origin
);
335 window_bounds
.set_origin(origin
);
336 window_
->SetBounds(window_bounds
);
339 void NativeWidgetAura::GetWindowPlacement(
341 ui::WindowShowState
* show_state
) const {
342 // The interface specifies returning restored bounds, not current bounds.
343 *bounds
= GetRestoredBounds();
344 *show_state
= window_
? window_
->GetProperty(aura::client::kShowStateKey
) :
345 ui::SHOW_STATE_DEFAULT
;
348 void NativeWidgetAura::SetWindowTitle(const string16
& title
) {
350 window_
->set_title(title
);
353 void NativeWidgetAura::SetWindowIcons(const gfx::ImageSkia
& window_icon
,
354 const gfx::ImageSkia
& app_icon
) {
355 // Aura doesn't have window icons.
358 void NativeWidgetAura::InitModalType(ui::ModalType modal_type
) {
359 if (modal_type
!= ui::MODAL_TYPE_NONE
)
360 window_
->SetProperty(aura::client::kModalKey
, modal_type
);
363 gfx::Rect
NativeWidgetAura::GetWindowBoundsInScreen() const {
364 return window_
? window_
->GetBoundsInScreen() : gfx::Rect();
367 gfx::Rect
NativeWidgetAura::GetClientAreaBoundsInScreen() const {
368 // View-to-screen coordinate system transformations depend on this returning
369 // the full window bounds, for example View::ConvertPointToScreen().
370 return window_
? window_
->GetBoundsInScreen() : gfx::Rect();
373 gfx::Rect
NativeWidgetAura::GetRestoredBounds() const {
377 // Restored bounds should only be relevant if the window is minimized or
378 // maximized. However, in some places the code expects GetRestoredBounds()
379 // to return the current window bounds if the window is not in either state.
380 if (IsMinimized() || IsMaximized() || IsFullscreen()) {
381 // Restore bounds are in screen coordinates, no need to convert.
382 gfx::Rect
* restore_bounds
=
383 window_
->GetProperty(aura::client::kRestoreBoundsKey
);
385 return *restore_bounds
;
387 return window_
->GetBoundsInScreen();
390 void NativeWidgetAura::SetBounds(const gfx::Rect
& bounds
) {
394 aura::Window
* root
= window_
->GetRootWindow();
396 aura::client::ScreenPositionClient
* screen_position_client
=
397 aura::client::GetScreenPositionClient(root
);
398 if (screen_position_client
) {
399 gfx::Display dst_display
=
400 gfx::Screen::GetScreenFor(window_
)->GetDisplayMatching(bounds
);
401 screen_position_client
->SetBounds(window_
, bounds
, dst_display
);
405 window_
->SetBounds(bounds
);
408 void NativeWidgetAura::SetSize(const gfx::Size
& size
) {
410 window_
->SetBounds(gfx::Rect(window_
->bounds().origin(), size
));
413 void NativeWidgetAura::StackAbove(gfx::NativeView native_view
) {
414 if (window_
&& window_
->parent() &&
415 window_
->parent() == native_view
->parent())
416 window_
->parent()->StackChildAbove(window_
, native_view
);
419 void NativeWidgetAura::StackAtTop() {
421 window_
->parent()->StackChildAtTop(window_
);
424 void NativeWidgetAura::StackBelow(gfx::NativeView native_view
) {
425 if (window_
&& window_
->parent() &&
426 window_
->parent() == native_view
->parent())
427 window_
->parent()->StackChildBelow(window_
, native_view
);
430 void NativeWidgetAura::SetShape(gfx::NativeRegion region
) {
431 // No need for this. Just delete and ignore.
435 void NativeWidgetAura::Close() {
436 // |window_| may already be deleted by parent window. This can happen
437 // when this widget is child widget or has transient parent
438 // and ownership is WIDGET_OWNS_NATIVE_WIDGET.
440 ownership_
== Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
);
442 window_
->SuppressPaint();
444 window_
->SetProperty(aura::client::kModalKey
, ui::MODAL_TYPE_NONE
);
447 if (!close_widget_factory_
.HasWeakPtrs()) {
448 base::MessageLoop::current()->PostTask(
450 base::Bind(&NativeWidgetAura::CloseNow
,
451 close_widget_factory_
.GetWeakPtr()));
455 void NativeWidgetAura::CloseNow() {
459 void NativeWidgetAura::Show() {
460 ShowWithWindowState(ui::SHOW_STATE_INACTIVE
);
463 void NativeWidgetAura::Hide() {
468 void NativeWidgetAura::ShowMaximizedWithBounds(
469 const gfx::Rect
& restored_bounds
) {
470 SetRestoreBounds(window_
, restored_bounds
);
471 ShowWithWindowState(ui::SHOW_STATE_MAXIMIZED
);
474 void NativeWidgetAura::ShowWithWindowState(ui::WindowShowState state
) {
478 if (state
== ui::SHOW_STATE_MAXIMIZED
|| state
== ui::SHOW_STATE_FULLSCREEN
)
479 window_
->SetProperty(aura::client::kShowStateKey
, state
);
482 if (state
!= ui::SHOW_STATE_INACTIVE
)
484 // SetInitialFocus() should be always be called, even for
485 // SHOW_STATE_INACTIVE. When a frameless modal dialog is created by
486 // a widget of TYPE_WINDOW_FRAMELESS, Widget::Show() will call into
487 // this function with the window state SHOW_STATE_INACTIVE,
488 // SetInitialFoucs() has to be called so that the dialog can get focus.
489 // This also matches NativeWidgetWin which invokes SetInitialFocus
490 // regardless of show state.
495 bool NativeWidgetAura::IsVisible() const {
496 return window_
&& window_
->IsVisible();
499 void NativeWidgetAura::Activate() {
503 // We don't necessarily have a root window yet. This can happen with
504 // constrained windows.
505 if (window_
->GetRootWindow()) {
506 aura::client::GetActivationClient(window_
->GetRootWindow())->ActivateWindow(
509 if (window_
->GetProperty(aura::client::kDrawAttentionKey
))
510 window_
->SetProperty(aura::client::kDrawAttentionKey
, false);
513 void NativeWidgetAura::Deactivate() {
516 aura::client::GetActivationClient(window_
->GetRootWindow())->DeactivateWindow(
520 bool NativeWidgetAura::IsActive() const {
524 // We may up here during destruction of the root, in which case
525 // GetRootWindow() returns NULL (~RootWindow() has run and we're in ~Window).
526 aura::Window
* root
= window_
->GetRootWindow();
528 aura::client::GetActivationClient(root
)->GetActiveWindow() == window_
;
531 void NativeWidgetAura::SetAlwaysOnTop(bool on_top
) {
533 window_
->SetProperty(aura::client::kAlwaysOnTopKey
, on_top
);
536 bool NativeWidgetAura::IsAlwaysOnTop() const {
537 return window_
&& window_
->GetProperty(aura::client::kAlwaysOnTopKey
);
540 void NativeWidgetAura::Maximize() {
542 window_
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
545 void NativeWidgetAura::Minimize() {
547 window_
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MINIMIZED
);
550 bool NativeWidgetAura::IsMaximized() const {
551 return window_
&& window_
->GetProperty(aura::client::kShowStateKey
) ==
552 ui::SHOW_STATE_MAXIMIZED
;
555 bool NativeWidgetAura::IsMinimized() const {
556 return window_
&& window_
->GetProperty(aura::client::kShowStateKey
) ==
557 ui::SHOW_STATE_MINIMIZED
;
560 void NativeWidgetAura::Restore() {
562 window_
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
565 void NativeWidgetAura::SetFullscreen(bool fullscreen
) {
566 if (!window_
|| IsFullscreen() == fullscreen
)
567 return; // Nothing to do.
569 // Save window state before entering full screen so that it could restored
570 // when exiting full screen.
572 saved_window_state_
= window_
->GetProperty(aura::client::kShowStateKey
);
574 window_
->SetProperty(
575 aura::client::kShowStateKey
,
576 fullscreen
? ui::SHOW_STATE_FULLSCREEN
: saved_window_state_
);
579 bool NativeWidgetAura::IsFullscreen() const {
580 return window_
&& window_
->GetProperty(aura::client::kShowStateKey
) ==
581 ui::SHOW_STATE_FULLSCREEN
;
584 void NativeWidgetAura::SetOpacity(unsigned char opacity
) {
586 window_
->layer()->SetOpacity(opacity
/ 255.0);
589 void NativeWidgetAura::SetUseDragFrame(bool use_drag_frame
) {
593 void NativeWidgetAura::FlashFrame(bool flash
) {
595 window_
->SetProperty(aura::client::kDrawAttentionKey
, flash
);
598 void NativeWidgetAura::RunShellDrag(View
* view
,
599 const ui::OSExchangeData
& data
,
600 const gfx::Point
& location
,
602 ui::DragDropTypes::DragEventSource source
) {
604 views::RunShellDrag(window_
, data
, location
, operation
, source
);
607 void NativeWidgetAura::SchedulePaintInRect(const gfx::Rect
& rect
) {
609 window_
->SchedulePaintInRect(rect
);
612 void NativeWidgetAura::SetCursor(gfx::NativeCursor cursor
) {
614 aura::client::CursorClient
* cursor_client
=
615 aura::client::GetCursorClient(window_
->GetRootWindow());
617 cursor_client
->SetCursor(cursor
);
620 bool NativeWidgetAura::IsMouseEventsEnabled() const {
623 aura::client::CursorClient
* cursor_client
=
624 aura::client::GetCursorClient(window_
->GetRootWindow());
625 return cursor_client
? cursor_client
->IsMouseEventsEnabled() : true;
628 void NativeWidgetAura::ClearNativeFocus() {
629 aura::client::FocusClient
* client
= aura::client::GetFocusClient(window_
);
630 if (window_
&& client
&& window_
->Contains(client
->GetFocusedWindow()))
631 client
->ResetFocusWithinActiveWindow(window_
);
634 gfx::Rect
NativeWidgetAura::GetWorkAreaBoundsInScreen() const {
637 return gfx::Screen::GetScreenFor(window_
)->
638 GetDisplayNearestWindow(window_
).work_area();
641 Widget::MoveLoopResult
NativeWidgetAura::RunMoveLoop(
642 const gfx::Vector2d
& drag_offset
,
643 Widget::MoveLoopSource source
,
644 Widget::MoveLoopEscapeBehavior escape_behavior
) {
645 // |escape_behavior| is only needed on windows when running the native message
647 if (window_
&& window_
->parent() &&
648 aura::client::GetWindowMoveClient(window_
->parent())) {
650 aura::client::WindowMoveSource window_move_source
=
651 source
== Widget::MOVE_LOOP_SOURCE_MOUSE
?
652 aura::client::WINDOW_MOVE_SOURCE_MOUSE
:
653 aura::client::WINDOW_MOVE_SOURCE_TOUCH
;
654 if (aura::client::GetWindowMoveClient(window_
->parent())->RunMoveLoop(
655 window_
, drag_offset
, window_move_source
) ==
656 aura::client::MOVE_SUCCESSFUL
) {
657 return Widget::MOVE_LOOP_SUCCESSFUL
;
660 return Widget::MOVE_LOOP_CANCELED
;
663 void NativeWidgetAura::EndMoveLoop() {
664 if (window_
&& window_
->parent() &&
665 aura::client::GetWindowMoveClient(window_
->parent())) {
666 aura::client::GetWindowMoveClient(window_
->parent())->EndMoveLoop();
670 void NativeWidgetAura::SetVisibilityChangedAnimationsEnabled(bool value
) {
672 window_
->SetProperty(aura::client::kAnimationsDisabledKey
, !value
);
675 ui::NativeTheme
* NativeWidgetAura::GetNativeTheme() const {
676 #if !defined(OS_CHROMEOS)
677 return DesktopRootWindowHost::GetNativeTheme(window_
);
679 return ui::NativeThemeAura::instance();
683 void NativeWidgetAura::OnRootViewLayout() const {
686 ////////////////////////////////////////////////////////////////////////////////
687 // NativeWidgetAura, views::InputMethodDelegate implementation:
689 void NativeWidgetAura::DispatchKeyEventPostIME(const ui::KeyEvent
& key
) {
690 FocusManager
* focus_manager
= GetWidget()->GetFocusManager();
691 delegate_
->OnKeyEvent(const_cast<ui::KeyEvent
*>(&key
));
692 if (key
.handled() || !focus_manager
)
694 focus_manager
->OnKeyEvent(key
);
697 ////////////////////////////////////////////////////////////////////////////////
698 // NativeWidgetAura, aura::WindowDelegate implementation:
700 gfx::Size
NativeWidgetAura::GetMinimumSize() const {
701 return delegate_
->GetMinimumSize();
704 gfx::Size
NativeWidgetAura::GetMaximumSize() const {
705 return delegate_
->GetMaximumSize();
708 void NativeWidgetAura::OnBoundsChanged(const gfx::Rect
& old_bounds
,
709 const gfx::Rect
& new_bounds
) {
710 if (old_bounds
.origin() != new_bounds
.origin())
711 delegate_
->OnNativeWidgetMove();
712 if (old_bounds
.size() != new_bounds
.size())
713 delegate_
->OnNativeWidgetSizeChanged(new_bounds
.size());
716 gfx::NativeCursor
NativeWidgetAura::GetCursor(const gfx::Point
& point
) {
720 int NativeWidgetAura::GetNonClientComponent(const gfx::Point
& point
) const {
721 return delegate_
->GetNonClientComponent(point
);
724 bool NativeWidgetAura::ShouldDescendIntoChildForEventHandling(
726 const gfx::Point
& location
) {
727 views::WidgetDelegate
* widget_delegate
= GetWidget()->widget_delegate();
728 if (widget_delegate
&&
729 !widget_delegate
->ShouldDescendIntoChildForEventHandling(child
, location
))
732 // Don't descend into |child| if there is a view with a Layer that contains
733 // the point and is stacked above |child|s layer.
734 typedef std::vector
<ui::Layer
*> Layers
;
735 const Layers
& root_layers(delegate_
->GetRootLayers());
736 if (root_layers
.empty())
739 Layers::const_iterator
child_layer_iter(
740 std::find(window_
->layer()->children().begin(),
741 window_
->layer()->children().end(), child
->layer()));
742 if (child_layer_iter
== window_
->layer()->children().end())
745 for (std::vector
<ui::Layer
*>::const_reverse_iterator i
= root_layers
.rbegin();
746 i
!= root_layers
.rend(); ++i
) {
747 ui::Layer
* layer
= *i
;
748 if (layer
->visible() && layer
->bounds().Contains(location
)) {
749 Layers::const_iterator
root_layer_iter(
750 std::find(window_
->layer()->children().begin(),
751 window_
->layer()->children().end(), layer
));
752 if (root_layer_iter
> child_layer_iter
)
759 bool NativeWidgetAura::CanFocus() {
760 return can_activate_
;
763 void NativeWidgetAura::OnCaptureLost() {
764 delegate_
->OnMouseCaptureLost();
767 void NativeWidgetAura::OnPaint(gfx::Canvas
* canvas
) {
768 delegate_
->OnNativeWidgetPaint(canvas
);
771 void NativeWidgetAura::OnDeviceScaleFactorChanged(float device_scale_factor
) {
772 // Repainting with new scale factor will paint the content at the right scale.
775 void NativeWidgetAura::OnWindowDestroying() {
776 delegate_
->OnNativeWidgetDestroying();
778 // If the aura::Window is destroyed, we can no longer show tooltips.
779 tooltip_manager_
.reset();
782 void NativeWidgetAura::OnWindowDestroyed() {
784 delegate_
->OnNativeWidgetDestroyed();
785 if (ownership_
== Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
)
789 void NativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible
) {
790 delegate_
->OnNativeWidgetVisibilityChanged(visible
);
793 bool NativeWidgetAura::HasHitTestMask() const {
794 return delegate_
->HasHitTestMask();
797 void NativeWidgetAura::GetHitTestMask(gfx::Path
* mask
) const {
799 delegate_
->GetHitTestMask(mask
);
802 void NativeWidgetAura::DidRecreateLayer(ui::Layer
*old_layer
,
803 ui::Layer
*new_layer
) {
806 ////////////////////////////////////////////////////////////////////////////////
807 // NativeWidgetAura, ui::EventHandler implementation:
809 void NativeWidgetAura::OnKeyEvent(ui::KeyEvent
* event
) {
811 if (event
->is_char()) {
812 // If a ui::InputMethod object is attached to the root window, character
813 // events are handled inside the object and are not passed to this function.
814 // If such object is not attached, character events might be sent (e.g. on
815 // Windows). In this case, we just skip these.
818 // Renderer may send a key event back to us if the key event wasn't handled,
819 // and the window may be invisible by that time.
820 if (!window_
->IsVisible())
822 GetWidget()->GetInputMethod()->DispatchKeyEvent(*event
);
826 void NativeWidgetAura::OnMouseEvent(ui::MouseEvent
* event
) {
828 DCHECK(window_
->IsVisible());
829 if (event
->type() == ui::ET_MOUSEWHEEL
) {
830 delegate_
->OnMouseEvent(event
);
831 if (event
->handled())
835 if (tooltip_manager_
.get())
836 tooltip_manager_
->UpdateTooltip();
837 TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget());
838 delegate_
->OnMouseEvent(event
);
841 void NativeWidgetAura::OnScrollEvent(ui::ScrollEvent
* event
) {
842 delegate_
->OnScrollEvent(event
);
845 void NativeWidgetAura::OnTouchEvent(ui::TouchEvent
* event
) {
847 DCHECK(window_
->IsVisible());
848 delegate_
->OnTouchEvent(event
);
851 void NativeWidgetAura::OnGestureEvent(ui::GestureEvent
* event
) {
853 DCHECK(window_
->IsVisible());
854 delegate_
->OnGestureEvent(event
);
857 ////////////////////////////////////////////////////////////////////////////////
858 // NativeWidgetAura, aura::client::ActivationDelegate implementation:
860 bool NativeWidgetAura::ShouldActivate() const {
861 return can_activate_
&& delegate_
->CanActivate();
864 ////////////////////////////////////////////////////////////////////////////////
865 // NativeWidgetAura, aura::client::ActivationChangeObserver implementation:
867 void NativeWidgetAura::OnWindowActivated(aura::Window
* gained_active
,
868 aura::Window
* lost_active
) {
869 DCHECK(window_
== gained_active
|| window_
== lost_active
);
870 if (GetWidget()->GetFocusManager()) {
871 if (window_
== gained_active
)
872 GetWidget()->GetFocusManager()->RestoreFocusedView();
873 else if (window_
== lost_active
)
874 GetWidget()->GetFocusManager()->StoreFocusedView(true);
876 delegate_
->OnNativeWidgetActivationChanged(window_
== gained_active
);
877 if (IsVisible() && GetWidget()->non_client_view())
878 GetWidget()->non_client_view()->SchedulePaint();
881 ////////////////////////////////////////////////////////////////////////////////
882 // NativeWidgetAura, aura::client::FocusChangeObserver:
884 void NativeWidgetAura::OnWindowFocused(aura::Window
* gained_focus
,
885 aura::Window
* lost_focus
) {
886 if (window_
== gained_focus
) {
887 // In aura, it is possible for child native widgets to take input and focus,
888 // this differs from the behavior on windows.
889 if (GetWidget()->GetInputMethod()) // Null in tests.
890 GetWidget()->GetInputMethod()->OnFocus();
891 delegate_
->OnNativeFocus(lost_focus
);
892 } else if (window_
== lost_focus
) {
893 // GetInputMethod() recreates the input method if it's previously been
894 // destroyed. If we get called during destruction, the input method will be
895 // gone, and creating a new one and telling it that we lost the focus will
896 // trigger a DCHECK (the new input method doesn't think that we have the
897 // focus and doesn't expect a blur). OnBlur() shouldn't be called during
898 // destruction unless WIDGET_OWNS_NATIVE_WIDGET is set (which is just the
901 if (GetWidget()->GetInputMethod())
902 GetWidget()->GetInputMethod()->OnBlur();
904 DCHECK_EQ(ownership_
, Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
);
907 aura::client::FocusClient
* client
= aura::client::GetFocusClient(window_
);
908 if (client
) // NULL during destruction of aura::Window.
909 delegate_
->OnNativeBlur(client
->GetFocusedWindow());
913 ////////////////////////////////////////////////////////////////////////////////
914 // NativeWidgetAura, aura::WindowDragDropDelegate implementation:
916 void NativeWidgetAura::OnDragEntered(const ui::DropTargetEvent
& event
) {
917 DCHECK(drop_helper_
.get() != NULL
);
918 last_drop_operation_
= drop_helper_
->OnDragOver(event
.data(),
919 event
.location(), event
.source_operations());
922 int NativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent
& event
) {
923 DCHECK(drop_helper_
.get() != NULL
);
924 last_drop_operation_
= drop_helper_
->OnDragOver(event
.data(),
925 event
.location(), event
.source_operations());
926 return last_drop_operation_
;
929 void NativeWidgetAura::OnDragExited() {
930 DCHECK(drop_helper_
.get() != NULL
);
931 drop_helper_
->OnDragExit();
934 int NativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent
& event
) {
935 DCHECK(drop_helper_
.get() != NULL
);
936 return drop_helper_
->OnDrop(event
.data(), event
.location(),
937 last_drop_operation_
);
940 ////////////////////////////////////////////////////////////////////////////////
941 // NativeWidgetAura, NativeWidget implementation:
943 ui::EventHandler
* NativeWidgetAura::GetEventHandler() {
947 ////////////////////////////////////////////////////////////////////////////////
948 // NativeWidgetAura, protected:
950 NativeWidgetAura::~NativeWidgetAura() {
952 if (ownership_
== Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
)
958 ////////////////////////////////////////////////////////////////////////////////
959 // NativeWidgetAura, private:
961 void NativeWidgetAura::SetInitialFocus() {
962 // The window does not get keyboard messages unless we focus it.
963 if (!GetWidget()->SetInitialFocus())
967 ////////////////////////////////////////////////////////////////////////////////
971 void Widget::NotifyLocaleChanged() {
972 // Deliberately not implemented.
976 void CloseWindow(aura::Window
* window
) {
978 Widget
* widget
= Widget::GetWidgetForNativeView(window
);
979 if (widget
&& widget
->is_secondary_widget())
980 // To avoid the delay in shutdown caused by using Close which may wait
981 // for animations, use CloseNow. Because this is only used on secondary
982 // widgets it seems relatively safe to skip the extra processing of
988 BOOL CALLBACK
WindowCallbackProc(HWND hwnd
, LPARAM lParam
) {
989 aura::Window
* root_window
=
990 DesktopRootWindowHostWin::GetContentWindowForHWND(hwnd
);
991 CloseWindow(root_window
);
998 void Widget::CloseAllSecondaryWidgets() {
1000 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc
, 0);
1003 #if defined(USE_X11) && !defined(OS_CHROMEOS)
1004 std::vector
<aura::Window
*> open_windows
=
1005 DesktopRootWindowHostX11::GetAllOpenWindows();
1006 std::for_each(open_windows
.begin(), open_windows
.end(), CloseWindow
);
1007 DesktopRootWindowHostX11::CleanUpWindowList();
1011 bool Widget::ConvertRect(const Widget
* source
,
1012 const Widget
* target
,
1017 namespace internal
{
1019 ////////////////////////////////////////////////////////////////////////////////
1020 // internal::NativeWidgetPrivate, public:
1023 NativeWidgetPrivate
* NativeWidgetPrivate::CreateNativeWidget(
1024 internal::NativeWidgetDelegate
* delegate
) {
1025 return new NativeWidgetAura(delegate
);
1029 NativeWidgetPrivate
* NativeWidgetPrivate::GetNativeWidgetForNativeView(
1030 gfx::NativeView native_view
) {
1031 // Cast must match type supplied to RegisterNativeWidgetForWindow().
1032 return reinterpret_cast<NativeWidgetPrivate
*>(native_view
->user_data());
1036 NativeWidgetPrivate
* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
1037 gfx::NativeWindow native_window
) {
1038 // Cast must match type supplied to RegisterNativeWidgetForWindow().
1039 return reinterpret_cast<NativeWidgetPrivate
*>(native_window
->user_data());
1043 NativeWidgetPrivate
* NativeWidgetPrivate::GetTopLevelNativeWidget(
1044 gfx::NativeView native_view
) {
1045 aura::Window
* window
= native_view
;
1046 NativeWidgetPrivate
* top_level_native_widget
= NULL
;
1048 NativeWidgetPrivate
* native_widget
= GetNativeWidgetForNativeView(window
);
1050 top_level_native_widget
= native_widget
;
1051 window
= window
->parent();
1053 return top_level_native_widget
;
1057 void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view
,
1058 Widget::Widgets
* children
) {
1060 // Code expects widget for |native_view| to be added to |children|.
1061 NativeWidgetPrivate
* native_widget
= static_cast<NativeWidgetPrivate
*>(
1062 GetNativeWidgetForNativeView(native_view
));
1063 if (native_widget
&& native_widget
->GetWidget())
1064 children
->insert(native_widget
->GetWidget());
1067 const aura::Window::Windows
& child_windows
= native_view
->children();
1068 for (aura::Window::Windows::const_iterator i
= child_windows
.begin();
1069 i
!= child_windows
.end(); ++i
) {
1070 GetAllChildWidgets((*i
), children
);
1075 void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view
,
1076 Widget::Widgets
* owned
) {
1077 const aura::Window::Windows
& transient_children
=
1078 native_view
->transient_children();
1079 for (aura::Window::Windows::const_iterator i
= transient_children
.begin();
1080 i
!= transient_children
.end(); ++i
) {
1081 NativeWidgetPrivate
* native_widget
= static_cast<NativeWidgetPrivate
*>(
1082 GetNativeWidgetForNativeView(*i
));
1083 if (native_widget
&& native_widget
->GetWidget())
1084 owned
->insert(native_widget
->GetWidget());
1085 GetAllOwnedWidgets((*i
), owned
);
1090 void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view
,
1091 gfx::NativeView new_parent
) {
1092 DCHECK(native_view
!= new_parent
);
1094 gfx::NativeView previous_parent
= native_view
->parent();
1095 if (previous_parent
== new_parent
)
1098 Widget::Widgets widgets
;
1099 GetAllChildWidgets(native_view
, &widgets
);
1101 // First notify all the widgets that they are being disassociated
1102 // from their previous parent.
1103 for (Widget::Widgets::iterator it
= widgets
.begin();
1104 it
!= widgets
.end(); ++it
) {
1105 (*it
)->NotifyNativeViewHierarchyWillChange();
1109 new_parent
->AddChild(native_view
);
1111 // The following looks weird, but it's the equivalent of what aura has
1112 // always done. (The previous behaviour of aura::Window::SetParent() used
1113 // NULL as a special value that meant ask the WindowTreeClient where things
1116 // This probably isn't strictly correct, but its an invariant that a Window
1117 // in use will be attached to a RootWindow, so we can't just call
1118 // RemoveChild here. The only possible thing that could assign a RootWindow
1119 // in this case is the stacking client of the current RootWindow. This
1120 // matches our previous behaviour; the global stacking client would almost
1121 // always reattach the window to the same RootWindow.
1122 aura::Window
* root_window
= native_view
->GetRootWindow();
1123 aura::client::ParentWindowWithContext(
1124 native_view
, root_window
, root_window
->GetBoundsInScreen());
1127 // And now, notify them that they have a brand new parent.
1128 for (Widget::Widgets::iterator it
= widgets
.begin();
1129 it
!= widgets
.end(); ++it
) {
1130 (*it
)->NotifyNativeViewHierarchyChanged();
1135 bool NativeWidgetPrivate::IsMouseButtonDown() {
1136 return aura::Env::GetInstance()->IsMouseButtonDown();
1140 bool NativeWidgetPrivate::IsTouchDown() {
1141 return aura::Env::GetInstance()->is_touch_down();
1144 } // namespace internal
1145 } // namespace views