1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
8 #include "base/debug/trace_event.h"
9 #include "ui/aura/client/aura_constants.h"
10 #include "ui/aura/client/cursor_client.h"
11 #include "ui/aura/client/focus_client.h"
12 #include "ui/aura/client/window_tree_client.h"
13 #include "ui/aura/window.h"
14 #include "ui/aura/window_observer.h"
15 #include "ui/aura/window_property.h"
16 #include "ui/aura/window_tree_host.h"
17 #include "ui/base/hit_test.h"
18 #include "ui/base/ui_base_switches_util.h"
19 #include "ui/compositor/layer.h"
20 #include "ui/gfx/canvas.h"
21 #include "ui/gfx/display.h"
22 #include "ui/gfx/point_conversions.h"
23 #include "ui/gfx/geometry/rect.h"
24 #include "ui/gfx/screen.h"
25 #include "ui/gfx/size_conversions.h"
26 #include "ui/native_theme/native_theme.h"
27 #include "ui/views/corewm/tooltip.h"
28 #include "ui/views/corewm/tooltip_controller.h"
29 #include "ui/views/drag_utils.h"
30 #include "ui/views/ime/input_method_bridge.h"
31 #include "ui/views/ime/null_input_method.h"
32 #include "ui/views/view_constants_aura.h"
33 #include "ui/views/widget/desktop_aura/desktop_capture_client.h"
34 #include "ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h"
35 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
36 #include "ui/views/widget/desktop_aura/desktop_event_client.h"
37 #include "ui/views/widget/desktop_aura/desktop_focus_rules.h"
38 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
39 #include "ui/views/widget/desktop_aura/desktop_screen_position_client.h"
40 #include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
41 #include "ui/views/widget/drop_helper.h"
42 #include "ui/views/widget/native_widget_aura.h"
43 #include "ui/views/widget/root_view.h"
44 #include "ui/views/widget/tooltip_manager_aura.h"
45 #include "ui/views/widget/widget.h"
46 #include "ui/views/widget/widget_aura_utils.h"
47 #include "ui/views/widget/widget_delegate.h"
48 #include "ui/views/widget/window_reorderer.h"
49 #include "ui/views/window/native_frame_view.h"
50 #include "ui/wm/core/compound_event_filter.h"
51 #include "ui/wm/core/cursor_manager.h"
52 #include "ui/wm/core/focus_controller.h"
53 #include "ui/wm/core/input_method_event_filter.h"
54 #include "ui/wm/core/native_cursor_manager.h"
55 #include "ui/wm/core/shadow_controller.h"
56 #include "ui/wm/core/shadow_types.h"
57 #include "ui/wm/core/visibility_controller.h"
58 #include "ui/wm/core/window_modality_controller.h"
59 #include "ui/wm/public/activation_client.h"
60 #include "ui/wm/public/drag_drop_client.h"
63 #include "ui/base/win/shell.h"
64 #include "ui/gfx/win/dpi.h"
67 DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(VIEWS_EXPORT
,
68 views::DesktopNativeWidgetAura
*);
72 DEFINE_WINDOW_PROPERTY_KEY(DesktopNativeWidgetAura
*,
73 kDesktopNativeWidgetAuraKey
, NULL
);
77 // This class provides functionality to create a top level widget to host a
79 class DesktopNativeWidgetTopLevelHandler
: public aura::WindowObserver
{
81 // This function creates a widget with the bounds passed in which eventually
82 // becomes the parent of the child window passed in.
83 static aura::Window
* CreateParentWindow(aura::Window
* child_window
,
84 const gfx::Rect
& bounds
,
86 bool root_is_always_on_top
) {
87 // This instance will get deleted when the widget is destroyed.
88 DesktopNativeWidgetTopLevelHandler
* top_level_handler
=
89 new DesktopNativeWidgetTopLevelHandler
;
91 child_window
->SetBounds(gfx::Rect(bounds
.size()));
93 Widget::InitParams init_params
;
94 init_params
.type
= full_screen
? Widget::InitParams::TYPE_WINDOW
:
95 Widget::InitParams::TYPE_POPUP
;
96 init_params
.bounds
= bounds
;
97 init_params
.ownership
= Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
;
98 init_params
.layer_type
= aura::WINDOW_LAYER_NOT_DRAWN
;
99 init_params
.activatable
= full_screen
?
100 Widget::InitParams::ACTIVATABLE_YES
:
101 Widget::InitParams::ACTIVATABLE_NO
;
102 init_params
.keep_on_top
= root_is_always_on_top
;
104 // This widget instance will get deleted when the window is
106 top_level_handler
->top_level_widget_
= new Widget();
107 top_level_handler
->top_level_widget_
->Init(init_params
);
109 top_level_handler
->top_level_widget_
->SetFullscreen(full_screen
);
110 top_level_handler
->top_level_widget_
->Show();
112 aura::Window
* native_window
=
113 top_level_handler
->top_level_widget_
->GetNativeView();
114 child_window
->AddObserver(top_level_handler
);
115 native_window
->AddObserver(top_level_handler
);
116 top_level_handler
->child_window_
= child_window
;
117 return native_window
;
120 // aura::WindowObserver overrides
121 virtual void OnWindowDestroying(aura::Window
* window
) override
{
122 window
->RemoveObserver(this);
124 // If the widget is being destroyed by the OS then we should not try and
126 if (top_level_widget_
&&
127 window
== top_level_widget_
->GetNativeView()) {
128 top_level_widget_
= NULL
;
132 if (top_level_widget_
) {
133 DCHECK(top_level_widget_
->GetNativeView());
134 top_level_widget_
->GetNativeView()->RemoveObserver(this);
135 // When we receive a notification that the child of the window created
136 // above is being destroyed we go ahead and initiate the destruction of
137 // the corresponding widget.
138 top_level_widget_
->Close();
139 top_level_widget_
= NULL
;
144 virtual void OnWindowBoundsChanged(aura::Window
* window
,
145 const gfx::Rect
& old_bounds
,
146 const gfx::Rect
& new_bounds
) override
{
147 if (top_level_widget_
&& window
== child_window_
)
148 top_level_widget_
->SetSize(new_bounds
.size());
152 DesktopNativeWidgetTopLevelHandler()
153 : top_level_widget_(NULL
),
154 child_window_(NULL
) {}
156 virtual ~DesktopNativeWidgetTopLevelHandler() {}
158 Widget
* top_level_widget_
;
159 aura::Window
* child_window_
;
161 DISALLOW_COPY_AND_ASSIGN(DesktopNativeWidgetTopLevelHandler
);
164 class DesktopNativeWidgetAuraWindowTreeClient
:
165 public aura::client::WindowTreeClient
{
167 explicit DesktopNativeWidgetAuraWindowTreeClient(
168 aura::Window
* root_window
)
169 : root_window_(root_window
) {
170 aura::client::SetWindowTreeClient(root_window_
, this);
172 virtual ~DesktopNativeWidgetAuraWindowTreeClient() {
173 aura::client::SetWindowTreeClient(root_window_
, NULL
);
176 // Overridden from client::WindowTreeClient:
177 virtual aura::Window
* GetDefaultParent(aura::Window
* context
,
178 aura::Window
* window
,
179 const gfx::Rect
& bounds
) override
{
180 bool is_fullscreen
= window
->GetProperty(aura::client::kShowStateKey
) ==
181 ui::SHOW_STATE_FULLSCREEN
;
182 bool is_menu
= window
->type() == ui::wm::WINDOW_TYPE_MENU
;
184 if (is_fullscreen
|| is_menu
) {
185 bool root_is_always_on_top
= false;
186 internal::NativeWidgetPrivate
* native_widget
=
187 DesktopNativeWidgetAura::ForWindow(root_window_
);
189 root_is_always_on_top
= native_widget
->IsAlwaysOnTop();
191 return DesktopNativeWidgetTopLevelHandler::CreateParentWindow(
192 window
, bounds
, is_fullscreen
, root_is_always_on_top
);
198 aura::Window
* root_window_
;
200 DISALLOW_COPY_AND_ASSIGN(DesktopNativeWidgetAuraWindowTreeClient
);
205 class FocusManagerEventHandler
: public ui::EventHandler
{
207 FocusManagerEventHandler(DesktopNativeWidgetAura
* desktop_native_widget_aura
)
208 : desktop_native_widget_aura_(desktop_native_widget_aura
) {}
210 // Implementation of ui::EventHandler:
211 virtual void OnKeyEvent(ui::KeyEvent
* event
) override
{
212 Widget
* widget
= desktop_native_widget_aura_
->GetWidget();
213 if (widget
&& widget
->GetFocusManager()->GetFocusedView() &&
214 !widget
->GetFocusManager()->OnKeyEvent(*event
)) {
220 DesktopNativeWidgetAura
* desktop_native_widget_aura_
;
222 DISALLOW_COPY_AND_ASSIGN(FocusManagerEventHandler
);
225 class RootWindowDestructionObserver
: public aura::WindowObserver
{
227 explicit RootWindowDestructionObserver(DesktopNativeWidgetAura
* parent
)
229 virtual ~RootWindowDestructionObserver() {}
232 // Overridden from aura::WindowObserver:
233 virtual void OnWindowDestroyed(aura::Window
* window
) override
{
234 parent_
->RootWindowDestroyed();
235 window
->RemoveObserver(this);
239 DesktopNativeWidgetAura
* parent_
;
241 DISALLOW_COPY_AND_ASSIGN(RootWindowDestructionObserver
);
244 ////////////////////////////////////////////////////////////////////////////////
245 // DesktopNativeWidgetAura, public:
247 int DesktopNativeWidgetAura::cursor_reference_count_
= 0;
248 DesktopNativeCursorManager
* DesktopNativeWidgetAura::native_cursor_manager_
=
250 wm::CursorManager
* DesktopNativeWidgetAura::cursor_manager_
= NULL
;
252 DesktopNativeWidgetAura::DesktopNativeWidgetAura(
253 internal::NativeWidgetDelegate
* delegate
)
254 : desktop_window_tree_host_(NULL
),
255 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
),
256 content_window_container_(NULL
),
257 content_window_(new aura::Window(this)),
258 native_widget_delegate_(delegate
),
259 last_drop_operation_(ui::DragDropTypes::DRAG_NONE
),
260 restore_focus_on_activate_(false),
261 cursor_(gfx::kNullCursor
),
262 widget_type_(Widget::InitParams::TYPE_WINDOW
),
263 close_widget_factory_(this) {
264 aura::client::SetFocusChangeObserver(content_window_
, this);
265 aura::client::SetActivationChangeObserver(content_window_
, this);
268 DesktopNativeWidgetAura::~DesktopNativeWidgetAura() {
269 if (ownership_
== Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
)
270 delete native_widget_delegate_
;
276 DesktopNativeWidgetAura
* DesktopNativeWidgetAura::ForWindow(
277 aura::Window
* window
) {
278 return window
->GetProperty(kDesktopNativeWidgetAuraKey
);
281 void DesktopNativeWidgetAura::OnHostClosed() {
282 // Don't invoke Widget::OnNativeWidgetDestroying(), its done by
283 // DesktopWindowTreeHost.
285 // The WindowModalityController is at the front of the event pretarget
286 // handler list. We destroy it first to preserve order symantics.
287 if (window_modality_controller_
)
288 window_modality_controller_
.reset();
290 // Make sure we don't have capture. Otherwise CaptureController and
291 // WindowEventDispatcher are left referencing a deleted Window.
293 aura::Window
* capture_window
= capture_client_
->GetCaptureWindow();
294 if (capture_window
&& host_
->window()->Contains(capture_window
))
295 capture_window
->ReleaseCapture();
298 // DesktopWindowTreeHost owns the ActivationController which ShadowController
299 // references. Make sure we destroy ShadowController early on.
300 shadow_controller_
.reset();
301 tooltip_manager_
.reset();
302 if (tooltip_controller_
.get()) {
303 host_
->window()->RemovePreTargetHandler(tooltip_controller_
.get());
304 aura::client::SetTooltipClient(host_
->window(), NULL
);
305 tooltip_controller_
.reset();
308 root_window_event_filter_
->RemoveHandler(input_method_event_filter_
.get());
310 window_tree_client_
.reset(); // Uses host_->dispatcher() at destruction.
312 capture_client_
.reset(); // Uses host_->dispatcher() at destruction.
314 // FocusController uses |content_window_|. Destroy it now so that we don't
315 // have to worry about the possibility of FocusController attempting to use
316 // |content_window_| after it's been destroyed but before all child windows
317 // have been destroyed.
318 host_
->window()->RemovePreTargetHandler(focus_client_
.get());
319 aura::client::SetFocusClient(host_
->window(), NULL
);
320 aura::client::SetActivationClient(host_
->window(), NULL
);
321 focus_client_
.reset();
323 host_
->RemoveObserver(this);
324 host_
.reset(); // Uses input_method_event_filter_ at destruction.
325 // WindowEventDispatcher owns |desktop_window_tree_host_|.
326 desktop_window_tree_host_
= NULL
;
327 content_window_
= NULL
;
329 native_widget_delegate_
->OnNativeWidgetDestroyed();
330 if (ownership_
== Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
)
334 void DesktopNativeWidgetAura::OnDesktopWindowTreeHostDestroyed(
335 aura::WindowTreeHost
* host
) {
336 // |dispatcher_| is still valid, but DesktopWindowTreeHost is nearly
337 // destroyed. Do cleanup here of members DesktopWindowTreeHost may also use.
338 aura::client::SetDispatcherClient(host
->window(), NULL
);
339 dispatcher_client_
.reset();
341 // We explicitly do NOT clear the cursor client property. Since the cursor
342 // manager is a singleton, it can outlive any window hierarchy, and it's
343 // important that objects attached to this destroying window hierarchy have
344 // an opportunity to deregister their observers from the cursor manager.
345 // They may want to do this when they are notified that they're being
346 // removed from the window hierarchy, which happens soon after this
347 // function when DesktopWindowTreeHost* calls DestroyDispatcher().
348 native_cursor_manager_
->RemoveHost(host
);
350 aura::client::SetScreenPositionClient(host
->window(), NULL
);
351 position_client_
.reset();
353 aura::client::SetDragDropClient(host
->window(), NULL
);
354 drag_drop_client_
.reset();
356 aura::client::SetEventClient(host
->window(), NULL
);
357 event_client_
.reset();
360 void DesktopNativeWidgetAura::HandleActivationChanged(bool active
) {
361 native_widget_delegate_
->OnNativeWidgetActivationChanged(active
);
362 aura::client::ActivationClient
* activation_client
=
363 aura::client::GetActivationClient(host_
->window());
364 if (!activation_client
)
367 if (GetWidget()->HasFocusManager()) {
368 // This function can be called before the focus manager has had a
369 // chance to set the focused view. In which case we should get the
370 // last focused view.
371 View
* view_for_activation
=
372 GetWidget()->GetFocusManager()->GetFocusedView() ?
373 GetWidget()->GetFocusManager()->GetFocusedView() :
374 GetWidget()->GetFocusManager()->GetStoredFocusView();
375 if (!view_for_activation
)
376 view_for_activation
= GetWidget()->GetRootView();
377 activation_client
->ActivateWindow(
378 view_for_activation
->GetWidget()->GetNativeView());
381 // If we're not active we need to deactivate the corresponding
382 // aura::Window. This way if a child widget is active it gets correctly
383 // deactivated (child widgets don't get native desktop activation changes,
384 // only aura activation changes).
385 aura::Window
* active_window
= activation_client
->GetActiveWindow();
387 activation_client
->DeactivateWindow(active_window
);
391 ////////////////////////////////////////////////////////////////////////////////
392 // DesktopNativeWidgetAura, internal::NativeWidgetPrivate implementation:
394 void DesktopNativeWidgetAura::InitNativeWidget(
395 const Widget::InitParams
& params
) {
396 ownership_
= params
.ownership
;
397 widget_type_
= params
.type
;
399 NativeWidgetAura::RegisterNativeWidgetForWindow(this, content_window_
);
400 // Animations on TYPE_WINDOW are handled by the OS. Additionally if we animate
401 // these windows the size of the window gets augmented, effecting restore
402 // bounds and maximized windows in bad ways.
403 if (params
.type
== Widget::InitParams::TYPE_WINDOW
&&
404 !params
.remove_standard_frame
) {
405 content_window_
->SetProperty(aura::client::kAnimationsDisabledKey
, true);
407 content_window_
->SetType(GetAuraWindowTypeForWidgetType(params
.type
));
408 content_window_
->Init(params
.layer_type
);
409 wm::SetShadowType(content_window_
, wm::SHADOW_TYPE_NONE
);
411 content_window_container_
= new aura::Window(NULL
);
412 content_window_container_
->Init(aura::WINDOW_LAYER_NOT_DRAWN
);
413 content_window_container_
->Show();
414 content_window_container_
->AddChild(content_window_
);
416 desktop_window_tree_host_
= params
.desktop_window_tree_host
?
417 params
.desktop_window_tree_host
:
418 DesktopWindowTreeHost::Create(native_widget_delegate_
, this);
419 host_
.reset(desktop_window_tree_host_
->AsWindowTreeHost());
420 desktop_window_tree_host_
->Init(content_window_
, params
);
422 // Mark this window as Desktop root window.
423 host_
->window()->SetProperty(views::kDesktopRootWindow
, true);
426 host_
->window()->AddChild(content_window_container_
);
427 host_
->window()->SetProperty(kDesktopNativeWidgetAuraKey
, this);
429 host_
->window()->AddObserver(new RootWindowDestructionObserver(this));
431 // The WindowsModalityController event filter should be at the head of the
432 // pre target handlers list. This ensures that it handles input events first
433 // when modal windows are at the top of the Zorder.
434 if (widget_type_
== Widget::InitParams::TYPE_WINDOW
)
435 window_modality_controller_
.reset(
436 new wm::WindowModalityController(host_
->window()));
438 // |root_window_event_filter_| must be created before
439 // OnWindowTreeHostCreated() is invoked.
441 // CEF sets focus to the window the user clicks down on.
442 // TODO(beng): see if we can't do this some other way. CEF seems a heavy-
443 // handed way of accomplishing focus.
444 // No event filter for aura::Env. Create CompoundEventFilter per
445 // WindowEventDispatcher.
446 root_window_event_filter_
.reset(new wm::CompoundEventFilter
);
447 host_
->window()->AddPreTargetHandler(root_window_event_filter_
.get());
449 // The host's dispatcher must be added to |native_cursor_manager_| before
450 // OnNativeWidgetCreated() is called.
451 cursor_reference_count_
++;
452 if (!native_cursor_manager_
) {
453 native_cursor_manager_
= new DesktopNativeCursorManager(
454 DesktopCursorLoaderUpdater::Create());
456 if (!cursor_manager_
) {
457 cursor_manager_
= new wm::CursorManager(
458 scoped_ptr
<wm::NativeCursorManager
>(native_cursor_manager_
));
460 native_cursor_manager_
->AddHost(host());
461 aura::client::SetCursorClient(host_
->window(), cursor_manager_
);
463 desktop_window_tree_host_
->OnNativeWidgetCreated(params
);
465 UpdateWindowTransparency();
467 capture_client_
.reset(new DesktopCaptureClient(host_
->window()));
469 wm::FocusController
* focus_controller
=
470 new wm::FocusController(new DesktopFocusRules(content_window_
));
471 focus_client_
.reset(focus_controller
);
472 aura::client::SetFocusClient(host_
->window(), focus_controller
);
473 aura::client::SetActivationClient(host_
->window(), focus_controller
);
474 host_
->window()->AddPreTargetHandler(focus_controller
);
476 dispatcher_client_
.reset(new DesktopDispatcherClient
);
477 aura::client::SetDispatcherClient(host_
->window(),
478 dispatcher_client_
.get());
480 position_client_
.reset(new DesktopScreenPositionClient(host_
->window()));
482 InstallInputMethodEventFilter();
484 drag_drop_client_
= desktop_window_tree_host_
->CreateDragDropClient(
485 native_cursor_manager_
);
486 aura::client::SetDragDropClient(host_
->window(),
487 drag_drop_client_
.get());
489 static_cast<aura::client::FocusClient
*>(focus_client_
.get())->
490 FocusWindow(content_window_
);
492 OnHostResized(host());
494 host_
->AddObserver(this);
496 window_tree_client_
.reset(
497 new DesktopNativeWidgetAuraWindowTreeClient(host_
->window()));
498 drop_helper_
.reset(new DropHelper(GetWidget()->GetRootView()));
499 aura::client::SetDragDropDelegate(content_window_
, this);
501 if (params
.type
!= Widget::InitParams::TYPE_TOOLTIP
) {
502 tooltip_manager_
.reset(new TooltipManagerAura(GetWidget()));
503 tooltip_controller_
.reset(
504 new corewm::TooltipController(
505 desktop_window_tree_host_
->CreateTooltip()));
506 aura::client::SetTooltipClient(host_
->window(),
507 tooltip_controller_
.get());
508 host_
->window()->AddPreTargetHandler(tooltip_controller_
.get());
511 if (params
.opacity
== Widget::InitParams::TRANSLUCENT_WINDOW
) {
512 visibility_controller_
.reset(new wm::VisibilityController
);
513 aura::client::SetVisibilityClient(host_
->window(),
514 visibility_controller_
.get());
515 wm::SetChildWindowVisibilityChangesAnimated(host_
->window());
516 wm::SetChildWindowVisibilityChangesAnimated(
517 content_window_container_
);
520 if (params
.type
== Widget::InitParams::TYPE_WINDOW
) {
521 focus_manager_event_handler_
.reset(new FocusManagerEventHandler(this));
522 host_
->window()->AddPreTargetHandler(focus_manager_event_handler_
.get());
525 event_client_
.reset(new DesktopEventClient
);
526 aura::client::SetEventClient(host_
->window(), event_client_
.get());
528 aura::client::GetFocusClient(content_window_
)->FocusWindow(content_window_
);
530 aura::client::SetActivationDelegate(content_window_
, this);
532 shadow_controller_
.reset(new wm::ShadowController(
533 aura::client::GetActivationClient(host_
->window())));
535 OnSizeConstraintsChanged();
537 window_reorderer_
.reset(new WindowReorderer(content_window_
,
538 GetWidget()->GetRootView()));
541 NonClientFrameView
* DesktopNativeWidgetAura::CreateNonClientFrameView() {
542 return ShouldUseNativeFrame() ? new NativeFrameView(GetWidget()) : NULL
;
545 bool DesktopNativeWidgetAura::ShouldUseNativeFrame() const {
546 return desktop_window_tree_host_
->ShouldUseNativeFrame();
549 bool DesktopNativeWidgetAura::ShouldWindowContentsBeTransparent() const {
550 return desktop_window_tree_host_
->ShouldWindowContentsBeTransparent();
553 void DesktopNativeWidgetAura::FrameTypeChanged() {
554 desktop_window_tree_host_
->FrameTypeChanged();
555 UpdateWindowTransparency();
558 Widget
* DesktopNativeWidgetAura::GetWidget() {
559 return native_widget_delegate_
->AsWidget();
562 const Widget
* DesktopNativeWidgetAura::GetWidget() const {
563 return native_widget_delegate_
->AsWidget();
566 gfx::NativeView
DesktopNativeWidgetAura::GetNativeView() const {
567 return content_window_
;
570 gfx::NativeWindow
DesktopNativeWidgetAura::GetNativeWindow() const {
571 return content_window_
;
574 Widget
* DesktopNativeWidgetAura::GetTopLevelWidget() {
578 const ui::Compositor
* DesktopNativeWidgetAura::GetCompositor() const {
579 return content_window_
? content_window_
->layer()->GetCompositor() : NULL
;
582 ui::Compositor
* DesktopNativeWidgetAura::GetCompositor() {
583 return const_cast<ui::Compositor
*>(
584 const_cast<const DesktopNativeWidgetAura
*>(this)->GetCompositor());
587 ui::Layer
* DesktopNativeWidgetAura::GetLayer() {
588 return content_window_
? content_window_
->layer() : NULL
;
591 void DesktopNativeWidgetAura::ReorderNativeViews() {
592 window_reorderer_
->ReorderChildWindows();
595 void DesktopNativeWidgetAura::ViewRemoved(View
* view
) {
596 DCHECK(drop_helper_
.get() != NULL
);
597 drop_helper_
->ResetTargetViewIfEquals(view
);
600 void DesktopNativeWidgetAura::SetNativeWindowProperty(const char* name
,
603 content_window_
->SetNativeWindowProperty(name
, value
);
606 void* DesktopNativeWidgetAura::GetNativeWindowProperty(const char* name
) const {
607 return content_window_
?
608 content_window_
->GetNativeWindowProperty(name
) : NULL
;
611 TooltipManager
* DesktopNativeWidgetAura::GetTooltipManager() const {
612 return tooltip_manager_
.get();
615 void DesktopNativeWidgetAura::SetCapture() {
616 if (!content_window_
)
619 content_window_
->SetCapture();
622 void DesktopNativeWidgetAura::ReleaseCapture() {
623 if (!content_window_
)
626 content_window_
->ReleaseCapture();
629 bool DesktopNativeWidgetAura::HasCapture() const {
630 return content_window_
&& content_window_
->HasCapture() &&
631 desktop_window_tree_host_
->HasCapture();
634 InputMethod
* DesktopNativeWidgetAura::CreateInputMethod() {
635 if (switches::IsTextInputFocusManagerEnabled())
636 return new NullInputMethod();
638 ui::InputMethod
* host
= input_method_event_filter_
->input_method();
639 return new InputMethodBridge(this, host
, false);
642 internal::InputMethodDelegate
*
643 DesktopNativeWidgetAura::GetInputMethodDelegate() {
647 ui::InputMethod
* DesktopNativeWidgetAura::GetHostInputMethod() {
648 return input_method_event_filter_
->input_method();
651 void DesktopNativeWidgetAura::CenterWindow(const gfx::Size
& size
) {
653 desktop_window_tree_host_
->CenterWindow(size
);
656 void DesktopNativeWidgetAura::GetWindowPlacement(
658 ui::WindowShowState
* maximized
) const {
660 desktop_window_tree_host_
->GetWindowPlacement(bounds
, maximized
);
663 bool DesktopNativeWidgetAura::SetWindowTitle(const base::string16
& title
) {
664 if (!content_window_
)
666 return desktop_window_tree_host_
->SetWindowTitle(title
);
669 void DesktopNativeWidgetAura::SetWindowIcons(const gfx::ImageSkia
& window_icon
,
670 const gfx::ImageSkia
& app_icon
) {
672 desktop_window_tree_host_
->SetWindowIcons(window_icon
, app_icon
);
675 void DesktopNativeWidgetAura::InitModalType(ui::ModalType modal_type
) {
676 // 99% of the time, we should not be asked to create a
677 // DesktopNativeWidgetAura that is modal. We only support window modal
678 // dialogs on the same lines as non AURA.
679 desktop_window_tree_host_
->InitModalType(modal_type
);
682 gfx::Rect
DesktopNativeWidgetAura::GetWindowBoundsInScreen() const {
683 return content_window_
?
684 desktop_window_tree_host_
->GetWindowBoundsInScreen() : gfx::Rect();
687 gfx::Rect
DesktopNativeWidgetAura::GetClientAreaBoundsInScreen() const {
688 return content_window_
?
689 desktop_window_tree_host_
->GetClientAreaBoundsInScreen() : gfx::Rect();
692 gfx::Rect
DesktopNativeWidgetAura::GetRestoredBounds() const {
693 return content_window_
?
694 desktop_window_tree_host_
->GetRestoredBounds() : gfx::Rect();
697 void DesktopNativeWidgetAura::SetBounds(const gfx::Rect
& bounds
) {
698 if (!content_window_
)
701 // This code by default scales the bounds rectangle by 1.
702 // We could probably get rid of this and similar logic from
703 // the DesktopNativeWidgetAura::OnWindowTreeHostResized function.
705 aura::Window
* root
= host_
->window();
707 scale
= gfx::Screen::GetScreenFor(root
)->
708 GetDisplayNearestWindow(root
).device_scale_factor();
710 gfx::Rect bounds_in_pixels
=
711 gfx::ScaleToEnclosingRect(bounds
, scale
, scale
);
712 desktop_window_tree_host_
->AsWindowTreeHost()->SetBounds(bounds_in_pixels
);
715 void DesktopNativeWidgetAura::SetSize(const gfx::Size
& size
) {
717 desktop_window_tree_host_
->SetSize(size
);
720 void DesktopNativeWidgetAura::StackAbove(gfx::NativeView native_view
) {
723 void DesktopNativeWidgetAura::StackAtTop() {
725 desktop_window_tree_host_
->StackAtTop();
728 void DesktopNativeWidgetAura::StackBelow(gfx::NativeView native_view
) {
731 void DesktopNativeWidgetAura::SetShape(gfx::NativeRegion shape
) {
733 desktop_window_tree_host_
->SetShape(shape
);
736 void DesktopNativeWidgetAura::Close() {
737 if (!content_window_
)
740 content_window_
->SuppressPaint();
741 content_window_
->Hide();
743 desktop_window_tree_host_
->Close();
746 void DesktopNativeWidgetAura::CloseNow() {
748 desktop_window_tree_host_
->CloseNow();
751 void DesktopNativeWidgetAura::Show() {
752 if (!content_window_
)
754 desktop_window_tree_host_
->AsWindowTreeHost()->Show();
755 content_window_
->Show();
758 void DesktopNativeWidgetAura::Hide() {
759 if (!content_window_
)
761 desktop_window_tree_host_
->AsWindowTreeHost()->Hide();
762 content_window_
->Hide();
765 void DesktopNativeWidgetAura::ShowMaximizedWithBounds(
766 const gfx::Rect
& restored_bounds
) {
767 if (!content_window_
)
769 desktop_window_tree_host_
->ShowMaximizedWithBounds(restored_bounds
);
770 content_window_
->Show();
773 void DesktopNativeWidgetAura::ShowWithWindowState(ui::WindowShowState state
) {
774 if (!content_window_
)
776 desktop_window_tree_host_
->ShowWindowWithState(state
);
777 content_window_
->Show();
780 bool DesktopNativeWidgetAura::IsVisible() const {
781 return content_window_
&& desktop_window_tree_host_
->IsVisible();
784 void DesktopNativeWidgetAura::Activate() {
786 desktop_window_tree_host_
->Activate();
789 void DesktopNativeWidgetAura::Deactivate() {
791 desktop_window_tree_host_
->Deactivate();
794 bool DesktopNativeWidgetAura::IsActive() const {
795 return content_window_
&& desktop_window_tree_host_
->IsActive();
798 void DesktopNativeWidgetAura::SetAlwaysOnTop(bool always_on_top
) {
800 desktop_window_tree_host_
->SetAlwaysOnTop(always_on_top
);
803 bool DesktopNativeWidgetAura::IsAlwaysOnTop() const {
804 return content_window_
&& desktop_window_tree_host_
->IsAlwaysOnTop();
807 void DesktopNativeWidgetAura::SetVisibleOnAllWorkspaces(bool always_visible
) {
809 desktop_window_tree_host_
->SetVisibleOnAllWorkspaces(always_visible
);
812 void DesktopNativeWidgetAura::Maximize() {
814 desktop_window_tree_host_
->Maximize();
817 void DesktopNativeWidgetAura::Minimize() {
819 desktop_window_tree_host_
->Minimize();
822 bool DesktopNativeWidgetAura::IsMaximized() const {
823 return content_window_
&& desktop_window_tree_host_
->IsMaximized();
826 bool DesktopNativeWidgetAura::IsMinimized() const {
827 return content_window_
&& desktop_window_tree_host_
->IsMinimized();
830 void DesktopNativeWidgetAura::Restore() {
832 desktop_window_tree_host_
->Restore();
835 void DesktopNativeWidgetAura::SetFullscreen(bool fullscreen
) {
837 desktop_window_tree_host_
->SetFullscreen(fullscreen
);
840 bool DesktopNativeWidgetAura::IsFullscreen() const {
841 return content_window_
&& desktop_window_tree_host_
->IsFullscreen();
844 void DesktopNativeWidgetAura::SetOpacity(unsigned char opacity
) {
846 desktop_window_tree_host_
->SetOpacity(opacity
);
849 void DesktopNativeWidgetAura::SetUseDragFrame(bool use_drag_frame
) {
852 void DesktopNativeWidgetAura::FlashFrame(bool flash_frame
) {
854 desktop_window_tree_host_
->FlashFrame(flash_frame
);
857 void DesktopNativeWidgetAura::RunShellDrag(
859 const ui::OSExchangeData
& data
,
860 const gfx::Point
& location
,
862 ui::DragDropTypes::DragEventSource source
) {
863 views::RunShellDrag(content_window_
, data
, location
, operation
, source
);
866 void DesktopNativeWidgetAura::SchedulePaintInRect(const gfx::Rect
& rect
) {
868 content_window_
->SchedulePaintInRect(rect
);
871 void DesktopNativeWidgetAura::SetCursor(gfx::NativeCursor cursor
) {
873 aura::client::CursorClient
* cursor_client
=
874 aura::client::GetCursorClient(host_
->window());
876 cursor_client
->SetCursor(cursor
);
879 bool DesktopNativeWidgetAura::IsMouseEventsEnabled() const {
880 if (!content_window_
)
882 aura::client::CursorClient
* cursor_client
=
883 aura::client::GetCursorClient(host_
->window());
884 return cursor_client
? cursor_client
->IsMouseEventsEnabled() : true;
887 void DesktopNativeWidgetAura::ClearNativeFocus() {
888 desktop_window_tree_host_
->ClearNativeFocus();
890 if (ShouldActivate()) {
891 aura::client::GetFocusClient(content_window_
)->
892 ResetFocusWithinActiveWindow(content_window_
);
896 gfx::Rect
DesktopNativeWidgetAura::GetWorkAreaBoundsInScreen() const {
897 return desktop_window_tree_host_
?
898 desktop_window_tree_host_
->GetWorkAreaBoundsInScreen() : gfx::Rect();
901 Widget::MoveLoopResult
DesktopNativeWidgetAura::RunMoveLoop(
902 const gfx::Vector2d
& drag_offset
,
903 Widget::MoveLoopSource source
,
904 Widget::MoveLoopEscapeBehavior escape_behavior
) {
905 if (!content_window_
)
906 return Widget::MOVE_LOOP_CANCELED
;
907 return desktop_window_tree_host_
->RunMoveLoop(drag_offset
, source
,
911 void DesktopNativeWidgetAura::EndMoveLoop() {
913 desktop_window_tree_host_
->EndMoveLoop();
916 void DesktopNativeWidgetAura::SetVisibilityChangedAnimationsEnabled(
919 desktop_window_tree_host_
->SetVisibilityChangedAnimationsEnabled(value
);
922 ui::NativeTheme
* DesktopNativeWidgetAura::GetNativeTheme() const {
923 return DesktopWindowTreeHost::GetNativeTheme(content_window_
);
926 void DesktopNativeWidgetAura::OnRootViewLayout() {
928 desktop_window_tree_host_
->OnRootViewLayout();
931 bool DesktopNativeWidgetAura::IsTranslucentWindowOpacitySupported() const {
932 return content_window_
&&
933 desktop_window_tree_host_
->IsTranslucentWindowOpacitySupported();
936 void DesktopNativeWidgetAura::OnSizeConstraintsChanged() {
937 content_window_
->SetProperty(aura::client::kCanMaximizeKey
,
938 GetWidget()->widget_delegate()->CanMaximize());
939 content_window_
->SetProperty(aura::client::kCanMinimizeKey
,
940 GetWidget()->widget_delegate()->CanMinimize());
941 content_window_
->SetProperty(aura::client::kCanResizeKey
,
942 GetWidget()->widget_delegate()->CanResize());
943 desktop_window_tree_host_
->SizeConstraintsChanged();
946 void DesktopNativeWidgetAura::RepostNativeEvent(gfx::NativeEvent native_event
) {
947 OnEvent(native_event
);
950 ////////////////////////////////////////////////////////////////////////////////
951 // DesktopNativeWidgetAura, aura::WindowDelegate implementation:
953 gfx::Size
DesktopNativeWidgetAura::GetMinimumSize() const {
954 return native_widget_delegate_
->GetMinimumSize();
957 gfx::Size
DesktopNativeWidgetAura::GetMaximumSize() const {
958 return native_widget_delegate_
->GetMaximumSize();
961 gfx::NativeCursor
DesktopNativeWidgetAura::GetCursor(const gfx::Point
& point
) {
965 int DesktopNativeWidgetAura::GetNonClientComponent(
966 const gfx::Point
& point
) const {
967 return native_widget_delegate_
->GetNonClientComponent(point
);
970 bool DesktopNativeWidgetAura::ShouldDescendIntoChildForEventHandling(
972 const gfx::Point
& location
) {
973 views::WidgetDelegate
* widget_delegate
= GetWidget()->widget_delegate();
974 return !widget_delegate
||
975 widget_delegate
->ShouldDescendIntoChildForEventHandling(child
, location
);
978 bool DesktopNativeWidgetAura::CanFocus() {
982 void DesktopNativeWidgetAura::OnCaptureLost() {
983 native_widget_delegate_
->OnMouseCaptureLost();
986 void DesktopNativeWidgetAura::OnPaint(gfx::Canvas
* canvas
) {
987 native_widget_delegate_
->OnNativeWidgetPaint(canvas
);
990 void DesktopNativeWidgetAura::OnDeviceScaleFactorChanged(
991 float device_scale_factor
) {
994 void DesktopNativeWidgetAura::OnWindowDestroying(aura::Window
* window
) {
995 // Cleanup happens in OnHostClosed().
998 void DesktopNativeWidgetAura::OnWindowDestroyed(aura::Window
* window
) {
999 // Cleanup happens in OnHostClosed(). We own |content_window_| (indirectly by
1000 // way of |dispatcher_|) so there should be no need to do any processing
1004 void DesktopNativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible
) {
1007 bool DesktopNativeWidgetAura::HasHitTestMask() const {
1008 return native_widget_delegate_
->HasHitTestMask();
1011 void DesktopNativeWidgetAura::GetHitTestMask(gfx::Path
* mask
) const {
1012 native_widget_delegate_
->GetHitTestMask(mask
);
1015 ////////////////////////////////////////////////////////////////////////////////
1016 // DesktopNativeWidgetAura, ui::EventHandler implementation:
1018 void DesktopNativeWidgetAura::OnKeyEvent(ui::KeyEvent
* event
) {
1019 if (event
->is_char()) {
1020 // If a ui::InputMethod object is attached to the root window, character
1021 // events are handled inside the object and are not passed to this function.
1022 // If such object is not attached, character events might be sent (e.g. on
1023 // Windows). In this case, we just skip these.
1026 // Renderer may send a key event back to us if the key event wasn't handled,
1027 // and the window may be invisible by that time.
1028 if (!content_window_
->IsVisible())
1031 native_widget_delegate_
->OnKeyEvent(event
);
1032 if (event
->handled())
1035 if (GetWidget()->HasFocusManager() &&
1036 !GetWidget()->GetFocusManager()->OnKeyEvent(*event
))
1037 event
->SetHandled();
1040 void DesktopNativeWidgetAura::OnMouseEvent(ui::MouseEvent
* event
) {
1041 DCHECK(content_window_
->IsVisible());
1042 if (tooltip_manager_
.get())
1043 tooltip_manager_
->UpdateTooltip();
1044 TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget());
1045 native_widget_delegate_
->OnMouseEvent(event
);
1046 // WARNING: we may have been deleted.
1049 void DesktopNativeWidgetAura::OnScrollEvent(ui::ScrollEvent
* event
) {
1050 if (event
->type() == ui::ET_SCROLL
) {
1051 native_widget_delegate_
->OnScrollEvent(event
);
1052 if (event
->handled())
1055 // Convert unprocessed scroll events into wheel events.
1056 ui::MouseWheelEvent
mwe(*static_cast<ui::ScrollEvent
*>(event
));
1057 native_widget_delegate_
->OnMouseEvent(&mwe
);
1059 event
->SetHandled();
1061 native_widget_delegate_
->OnScrollEvent(event
);
1065 void DesktopNativeWidgetAura::OnGestureEvent(ui::GestureEvent
* event
) {
1066 native_widget_delegate_
->OnGestureEvent(event
);
1069 ////////////////////////////////////////////////////////////////////////////////
1070 // DesktopNativeWidgetAura, aura::client::ActivationDelegate implementation:
1072 bool DesktopNativeWidgetAura::ShouldActivate() const {
1073 return native_widget_delegate_
->CanActivate();
1076 ////////////////////////////////////////////////////////////////////////////////
1077 // DesktopNativeWidgetAura, aura::client::ActivationChangeObserver
1080 void DesktopNativeWidgetAura::OnWindowActivated(aura::Window
* gained_active
,
1081 aura::Window
* lost_active
) {
1082 DCHECK(content_window_
== gained_active
|| content_window_
== lost_active
);
1083 if (gained_active
== content_window_
&& restore_focus_on_activate_
) {
1084 restore_focus_on_activate_
= false;
1085 GetWidget()->GetFocusManager()->RestoreFocusedView();
1086 } else if (lost_active
== content_window_
&& GetWidget()->HasFocusManager()) {
1087 DCHECK(!restore_focus_on_activate_
);
1088 restore_focus_on_activate_
= true;
1089 // Pass in false so that ClearNativeFocus() isn't invoked.
1090 GetWidget()->GetFocusManager()->StoreFocusedView(false);
1094 ////////////////////////////////////////////////////////////////////////////////
1095 // DesktopNativeWidgetAura, aura::client::FocusChangeObserver implementation:
1097 void DesktopNativeWidgetAura::OnWindowFocused(aura::Window
* gained_focus
,
1098 aura::Window
* lost_focus
) {
1099 if (content_window_
== gained_focus
) {
1100 desktop_window_tree_host_
->OnNativeWidgetFocus();
1101 native_widget_delegate_
->OnNativeFocus(lost_focus
);
1103 // If focus is moving from a descendant Window to |content_window_| then
1104 // native activation hasn't changed. Still, the InputMethod must be informed
1105 // of the Window focus change.
1106 InputMethod
* input_method
= GetWidget()->GetInputMethod();
1108 input_method
->OnFocus();
1109 } else if (content_window_
== lost_focus
) {
1110 desktop_window_tree_host_
->OnNativeWidgetBlur();
1111 native_widget_delegate_
->OnNativeBlur(gained_focus
);
1115 ////////////////////////////////////////////////////////////////////////////////
1116 // DesktopNativeWidgetAura, views::internal::InputMethodDelegate:
1118 void DesktopNativeWidgetAura::DispatchKeyEventPostIME(const ui::KeyEvent
& key
) {
1119 FocusManager
* focus_manager
=
1120 native_widget_delegate_
->AsWidget()->GetFocusManager();
1121 native_widget_delegate_
->OnKeyEvent(const_cast<ui::KeyEvent
*>(&key
));
1122 if (key
.handled() || !focus_manager
)
1124 focus_manager
->OnKeyEvent(key
);
1127 ////////////////////////////////////////////////////////////////////////////////
1128 // DesktopNativeWidgetAura, aura::WindowDragDropDelegate implementation:
1130 void DesktopNativeWidgetAura::OnDragEntered(const ui::DropTargetEvent
& event
) {
1131 DCHECK(drop_helper_
.get() != NULL
);
1132 last_drop_operation_
= drop_helper_
->OnDragOver(event
.data(),
1133 event
.location(), event
.source_operations());
1136 int DesktopNativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent
& event
) {
1137 DCHECK(drop_helper_
.get() != NULL
);
1138 last_drop_operation_
= drop_helper_
->OnDragOver(event
.data(),
1139 event
.location(), event
.source_operations());
1140 return last_drop_operation_
;
1143 void DesktopNativeWidgetAura::OnDragExited() {
1144 DCHECK(drop_helper_
.get() != NULL
);
1145 drop_helper_
->OnDragExit();
1148 int DesktopNativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent
& event
) {
1149 DCHECK(drop_helper_
.get() != NULL
);
1150 if (ShouldActivate())
1152 return drop_helper_
->OnDrop(event
.data(), event
.location(),
1153 last_drop_operation_
);
1156 ////////////////////////////////////////////////////////////////////////////////
1157 // DesktopNativeWidgetAura, aura::WindowTreeHostObserver implementation:
1159 void DesktopNativeWidgetAura::OnHostCloseRequested(
1160 const aura::WindowTreeHost
* host
) {
1161 GetWidget()->Close();
1164 void DesktopNativeWidgetAura::OnHostResized(const aura::WindowTreeHost
* host
) {
1165 // Don't update the bounds of the child layers when animating closed. If we
1166 // did it would force a paint, which we don't want. We don't want the paint
1167 // as we can't assume any of the children are valid.
1168 if (desktop_window_tree_host_
->IsAnimatingClosed())
1171 gfx::Rect new_bounds
= gfx::Rect(host
->window()->bounds().size());
1172 content_window_
->SetBounds(new_bounds
);
1173 // Can be NULL at start.
1174 if (content_window_container_
)
1175 content_window_container_
->SetBounds(new_bounds
);
1176 native_widget_delegate_
->OnNativeWidgetSizeChanged(new_bounds
.size());
1179 void DesktopNativeWidgetAura::OnHostMoved(const aura::WindowTreeHost
* host
,
1180 const gfx::Point
& new_origin
) {
1181 TRACE_EVENT1("views", "DesktopNativeWidgetAura::OnHostMoved",
1182 "new_origin", new_origin
.ToString());
1184 native_widget_delegate_
->OnNativeWidgetMove();
1187 ////////////////////////////////////////////////////////////////////////////////
1188 // DesktopNativeWidgetAura, private:
1190 void DesktopNativeWidgetAura::InstallInputMethodEventFilter() {
1191 DCHECK(!input_method_event_filter_
.get());
1193 input_method_event_filter_
.reset(new wm::InputMethodEventFilter(
1194 host_
->GetAcceleratedWidget()));
1195 input_method_event_filter_
->SetInputMethodPropertyInRootWindow(
1197 root_window_event_filter_
->AddHandler(input_method_event_filter_
.get());
1200 void DesktopNativeWidgetAura::UpdateWindowTransparency() {
1201 content_window_
->SetTransparent(
1202 desktop_window_tree_host_
->ShouldWindowContentsBeTransparent());
1203 // Regardless of transparency or not, this root content window will always
1204 // fill its bounds completely, so set this flag to true to avoid an
1205 // unecessary clear before update.
1206 content_window_
->SetFillsBoundsCompletely(true);
1209 void DesktopNativeWidgetAura::RootWindowDestroyed() {
1210 cursor_reference_count_
--;
1211 if (cursor_reference_count_
== 0) {
1212 // We are the last DesktopNativeWidgetAura instance, and we are responsible
1213 // for cleaning up |cursor_manager_|.
1214 delete cursor_manager_
;
1215 native_cursor_manager_
= NULL
;
1216 cursor_manager_
= NULL
;
1220 } // namespace views