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.
10 #include "ash/accelerators/focus_manager_factory.h"
11 #include "ash/ash_switches.h"
12 #include "ash/desktop_background/desktop_background_controller.h"
13 #include "ash/desktop_background/desktop_background_resources.h"
14 #include "ash/desktop_background/desktop_background_view.h"
15 #include "ash/drag_drop/drag_drop_controller.h"
16 #include "ash/focus_cycler.h"
17 #include "ash/high_contrast/high_contrast_controller.h"
18 #include "ash/launcher/launcher.h"
19 #include "ash/magnifier/magnification_controller.h"
20 #include "ash/monitor/monitor_controller.h"
21 #include "ash/monitor/multi_monitor_manager.h"
22 #include "ash/screen_ash.h"
23 #include "ash/shell_context_menu.h"
24 #include "ash/shell_delegate.h"
25 #include "ash/shell_factory.h"
26 #include "ash/shell_window_ids.h"
27 #include "ash/system/bluetooth/bluetooth_observer.h"
28 #include "ash/system/network/network_observer.h"
29 #include "ash/system/tray/system_tray.h"
30 #include "ash/system/tray/system_tray_delegate.h"
31 #include "ash/tooltips/tooltip_controller.h"
32 #include "ash/touch/touch_observer_hud.h"
33 #include "ash/wm/activation_controller.h"
34 #include "ash/wm/app_list_controller.h"
35 #include "ash/wm/base_layout_manager.h"
36 #include "ash/wm/custom_frame_view_ash.h"
37 #include "ash/wm/dialog_frame_view.h"
38 #include "ash/wm/event_client_impl.h"
39 #include "ash/wm/key_rewriter_event_filter.h"
40 #include "ash/wm/panel_layout_manager.h"
41 #include "ash/wm/panel_window_event_filter.h"
42 #include "ash/wm/partial_screenshot_event_filter.h"
43 #include "ash/wm/power_button_controller.h"
44 #include "ash/wm/resize_shadow_controller.h"
45 #include "ash/wm/root_window_layout_manager.h"
46 #include "ash/wm/screen_dimmer.h"
47 #include "ash/wm/shadow_controller.h"
48 #include "ash/wm/shelf_layout_manager.h"
49 #include "ash/wm/stacking_controller.h"
50 #include "ash/wm/status_area_layout_manager.h"
51 #include "ash/wm/system_gesture_event_filter.h"
52 #include "ash/wm/system_modal_container_layout_manager.h"
53 #include "ash/wm/toplevel_window_event_filter.h"
54 #include "ash/wm/video_detector.h"
55 #include "ash/wm/visibility_controller.h"
56 #include "ash/wm/window_cycle_controller.h"
57 #include "ash/wm/window_modality_controller.h"
58 #include "ash/wm/window_util.h"
59 #include "ash/wm/workspace/workspace_event_filter.h"
60 #include "ash/wm/workspace/workspace_layout_manager.h"
61 #include "ash/wm/workspace/workspace_manager.h"
62 #include "ash/wm/workspace_controller.h"
63 #include "base/bind.h"
64 #include "base/command_line.h"
65 #include "grit/ui_resources.h"
66 #include "third_party/skia/include/core/SkBitmap.h"
67 #include "ui/aura/client/aura_constants.h"
68 #include "ui/aura/env.h"
69 #include "ui/aura/layout_manager.h"
70 #include "ui/aura/monitor_manager.h"
71 #include "ui/aura/root_window.h"
72 #include "ui/aura/shared/input_method_event_filter.h"
73 #include "ui/aura/shared/root_window_event_filter.h"
74 #include "ui/aura/ui_controls_aura.h"
75 #include "ui/aura/window.h"
76 #include "ui/compositor/layer.h"
77 #include "ui/compositor/layer_animator.h"
78 #include "ui/gfx/monitor.h"
79 #include "ui/gfx/screen.h"
80 #include "ui/gfx/size.h"
81 #include "ui/ui_controls/ui_controls.h"
82 #include "ui/views/focus/focus_manager_factory.h"
83 #include "ui/views/widget/native_widget_aura.h"
84 #include "ui/views/widget/widget.h"
86 #if !defined(OS_MACOSX)
87 #include "ash/accelerators/accelerator_controller.h"
88 #include "ash/accelerators/accelerator_filter.h"
89 #include "ash/accelerators/nested_dispatcher_controller.h"
99 // Creates a new window for use as a container.
100 aura::Window
* CreateContainer(int window_id
,
102 aura::Window
* parent
) {
103 aura::Window
* container
= new aura::Window(NULL
);
104 container
->set_id(window_id
);
105 container
->SetName(name
);
106 container
->Init(ui::LAYER_NOT_DRAWN
);
107 parent
->AddChild(container
);
108 if (window_id
!= internal::kShellWindowId_UnparentedControlContainer
)
113 // Creates each of the special window containers that holds windows of various
114 // types in the shell UI.
115 void CreateSpecialContainers(aura::RootWindow
* root_window
) {
116 // These containers are just used by PowerButtonController to animate groups
117 // of containers simultaneously without messing up the current transformations
118 // on those containers. These are direct children of the root window; all of
119 // the other containers are their children.
120 aura::Window
* non_lock_screen_containers
= CreateContainer(
121 internal::kShellWindowId_NonLockScreenContainersContainer
,
122 "NonLockScreenContainersContainer",
124 aura::Window
* lock_screen_containers
= CreateContainer(
125 internal::kShellWindowId_LockScreenContainersContainer
,
126 "LockScreenContainersContainer",
128 aura::Window
* lock_screen_related_containers
= CreateContainer(
129 internal::kShellWindowId_LockScreenRelatedContainersContainer
,
130 "LockScreenRelatedContainersContainer",
133 CreateContainer(internal::kShellWindowId_UnparentedControlContainer
,
134 "UnparentedControlContainer",
135 non_lock_screen_containers
);
137 aura::Window
* desktop_background_containers
= CreateContainer(
138 internal::kShellWindowId_DesktopBackgroundContainer
,
139 "DesktopBackgroundContainer",
140 non_lock_screen_containers
);
141 SetChildWindowVisibilityChangesAnimated(desktop_background_containers
);
143 aura::Window
* default_container
= CreateContainer(
144 internal::kShellWindowId_DefaultContainer
,
146 non_lock_screen_containers
);
147 default_container
->SetEventFilter(
148 new ToplevelWindowEventFilter(default_container
));
149 SetChildWindowVisibilityChangesAnimated(default_container
);
151 aura::Window
* always_on_top_container
= CreateContainer(
152 internal::kShellWindowId_AlwaysOnTopContainer
,
153 "AlwaysOnTopContainer",
154 non_lock_screen_containers
);
155 always_on_top_container
->SetEventFilter(
156 new ToplevelWindowEventFilter(always_on_top_container
));
157 SetChildWindowVisibilityChangesAnimated(always_on_top_container
);
159 CreateContainer(internal::kShellWindowId_PanelContainer
,
161 non_lock_screen_containers
);
163 CreateContainer(internal::kShellWindowId_AppListContainer
,
165 non_lock_screen_containers
);
167 CreateContainer(internal::kShellWindowId_LauncherContainer
,
169 non_lock_screen_containers
);
171 aura::Window
* modal_container
= CreateContainer(
172 internal::kShellWindowId_SystemModalContainer
,
173 "SystemModalContainer",
174 non_lock_screen_containers
);
175 modal_container
->SetEventFilter(
176 new ToplevelWindowEventFilter(modal_container
));
177 modal_container
->SetLayoutManager(
178 new internal::SystemModalContainerLayoutManager(modal_container
));
179 SetChildWindowVisibilityChangesAnimated(modal_container
);
181 // TODO(beng): Figure out if we can make this use
182 // SystemModalContainerEventFilter instead of stops_event_propagation.
183 aura::Window
* lock_container
= CreateContainer(
184 internal::kShellWindowId_LockScreenContainer
,
185 "LockScreenContainer",
186 lock_screen_containers
);
187 lock_container
->SetLayoutManager(
188 new internal::BaseLayoutManager(root_window
));
189 // TODO(beng): stopsevents
191 aura::Window
* lock_modal_container
= CreateContainer(
192 internal::kShellWindowId_LockSystemModalContainer
,
193 "LockSystemModalContainer",
194 lock_screen_containers
);
195 lock_modal_container
->SetEventFilter(
196 new ToplevelWindowEventFilter(lock_modal_container
));
197 lock_modal_container
->SetLayoutManager(
198 new internal::SystemModalContainerLayoutManager(lock_modal_container
));
199 SetChildWindowVisibilityChangesAnimated(lock_modal_container
);
201 CreateContainer(internal::kShellWindowId_StatusContainer
,
203 lock_screen_related_containers
);
205 aura::Window
* menu_container
= CreateContainer(
206 internal::kShellWindowId_MenuContainer
,
208 lock_screen_related_containers
);
209 SetChildWindowVisibilityChangesAnimated(menu_container
);
211 aura::Window
* drag_drop_container
= CreateContainer(
212 internal::kShellWindowId_DragImageAndTooltipContainer
,
213 "DragImageAndTooltipContainer",
214 lock_screen_related_containers
);
215 SetChildWindowVisibilityChangesAnimated(drag_drop_container
);
217 aura::Window
* settings_bubble_container
= CreateContainer(
218 internal::kShellWindowId_SettingBubbleContainer
,
219 "SettingBubbleContainer",
220 lock_screen_related_containers
);
221 SetChildWindowVisibilityChangesAnimated(settings_bubble_container
);
223 CreateContainer(internal::kShellWindowId_OverlayContainer
,
225 lock_screen_related_containers
);
228 // This dummy class is used for shell unit tests. We dont have chrome delegate
230 class DummyUserWallpaperDelegate
: public UserWallpaperDelegate
{
232 DummyUserWallpaperDelegate() {}
234 virtual ~DummyUserWallpaperDelegate() {}
236 virtual const int GetUserWallpaperIndex() OVERRIDE
{
240 virtual void OpenSetWallpaperPage() OVERRIDE
{
243 virtual bool CanOpenSetWallpaperPage() OVERRIDE
{
248 DISALLOW_COPY_AND_ASSIGN(DummyUserWallpaperDelegate
);
251 class DummySystemTrayDelegate
: public SystemTrayDelegate
{
253 DummySystemTrayDelegate()
256 cellular_enabled_(true),
257 bluetooth_enabled_(true),
259 caps_lock_enabled_(false) {
262 virtual ~DummySystemTrayDelegate() {}
265 virtual bool GetTrayVisibilityOnStartup() OVERRIDE
{ return true; }
267 // Overridden from SystemTrayDelegate:
268 virtual const std::string
GetUserDisplayName() const OVERRIDE
{
269 return "Ãœber tray Ãœber tray Ãœber tray Ãœber tray";
272 virtual const std::string
GetUserEmail() const OVERRIDE
{
276 virtual const SkBitmap
& GetUserImage() const OVERRIDE
{
280 virtual user::LoginStatus
GetUserLoginStatus() const OVERRIDE
{
281 return user::LOGGED_IN_USER
;
284 virtual bool SystemShouldUpgrade() const OVERRIDE
{
288 virtual int GetSystemUpdateIconResource() const OVERRIDE
{
289 return IDR_AURA_UBER_TRAY_UPDATE
;
292 virtual base::HourClockType
GetHourClockType() const OVERRIDE
{
293 return base::k24HourClock
;
296 virtual PowerSupplyStatus
GetPowerSupplyStatus() const OVERRIDE
{
297 return PowerSupplyStatus();
300 virtual void RequestStatusUpdate() const OVERRIDE
{
303 virtual void ShowSettings() OVERRIDE
{
306 virtual void ShowDateSettings() OVERRIDE
{
309 virtual void ShowNetworkSettings() OVERRIDE
{
312 virtual void ShowBluetoothSettings() OVERRIDE
{
315 virtual void ShowDriveSettings() OVERRIDE
{
318 virtual void ShowIMESettings() OVERRIDE
{
321 virtual void ShowHelp() OVERRIDE
{
324 virtual bool IsAudioMuted() const OVERRIDE
{
328 virtual void SetAudioMuted(bool muted
) OVERRIDE
{
332 virtual float GetVolumeLevel() const OVERRIDE
{
336 virtual void SetVolumeLevel(float volume
) OVERRIDE
{
340 virtual bool IsCapsLockOn() const OVERRIDE
{
341 return caps_lock_enabled_
;
344 virtual void SetCapsLockEnabled(bool enabled
) OVERRIDE
{
345 caps_lock_enabled_
= enabled
;
348 virtual bool IsInAccessibilityMode() const OVERRIDE
{
352 virtual void SetEnableSpokenFeedback(bool enable
) OVERRIDE
{}
354 virtual void ShutDown() OVERRIDE
{}
356 virtual void SignOut() OVERRIDE
{
357 MessageLoop::current()->Quit();
360 virtual void RequestLockScreen() OVERRIDE
{}
362 virtual void RequestRestart() OVERRIDE
{}
364 virtual void GetAvailableBluetoothDevices(
365 BluetoothDeviceList
* list
) OVERRIDE
{
368 virtual void ToggleBluetoothConnection(const std::string
& address
) OVERRIDE
{
371 virtual void GetCurrentIME(IMEInfo
* info
) OVERRIDE
{
374 virtual void GetAvailableIMEList(IMEInfoList
* list
) OVERRIDE
{
377 virtual void GetCurrentIMEProperties(IMEPropertyInfoList
* list
) OVERRIDE
{
380 virtual void SwitchIME(const std::string
& ime_id
) OVERRIDE
{
383 virtual void ActivateIMEProperty(const std::string
& key
) OVERRIDE
{
386 virtual void CancelDriveOperation(const FilePath
&) OVERRIDE
{
389 virtual void GetDriveOperationStatusList(
390 ash::DriveOperationStatusList
*) OVERRIDE
{
393 virtual void GetMostRelevantNetworkIcon(NetworkIconInfo
* info
,
394 bool large
) OVERRIDE
{
397 virtual void GetAvailableNetworks(
398 std::vector
<NetworkIconInfo
>* list
) OVERRIDE
{
401 virtual void ConnectToNetwork(const std::string
& network_id
) OVERRIDE
{
404 virtual void GetNetworkAddresses(std::string
* ip_address
,
405 std::string
* ethernet_mac_address
,
406 std::string
* wifi_mac_address
) OVERRIDE
{
407 *ip_address
= "127.0.0.1";
408 *ethernet_mac_address
= "00:11:22:33:44:55";
409 *wifi_mac_address
= "66:77:88:99:00:11";
412 virtual void RequestNetworkScan() OVERRIDE
{
415 virtual void AddBluetoothDevice() OVERRIDE
{
418 virtual void ToggleAirplaneMode() OVERRIDE
{
421 virtual void ToggleWifi() OVERRIDE
{
422 wifi_enabled_
= !wifi_enabled_
;
423 ash::NetworkObserver
* observer
=
424 ash::Shell::GetInstance()->tray()->network_observer();
426 ash::NetworkIconInfo info
;
427 observer
->OnNetworkRefresh(info
);
431 virtual void ToggleMobile() OVERRIDE
{
432 cellular_enabled_
= !cellular_enabled_
;
433 ash::NetworkObserver
* observer
=
434 ash::Shell::GetInstance()->tray()->network_observer();
436 ash::NetworkIconInfo info
;
437 observer
->OnNetworkRefresh(info
);
441 virtual void ToggleBluetooth() OVERRIDE
{
442 bluetooth_enabled_
= !bluetooth_enabled_
;
443 ash::BluetoothObserver
* observer
=
444 ash::Shell::GetInstance()->tray()->bluetooth_observer();
446 observer
->OnBluetoothRefresh();
449 virtual void ShowOtherWifi() OVERRIDE
{
452 virtual void ShowOtherCellular() OVERRIDE
{
455 virtual bool IsNetworkConnected() OVERRIDE
{
459 virtual bool GetWifiAvailable() OVERRIDE
{
463 virtual bool GetMobileAvailable() OVERRIDE
{
467 virtual bool GetBluetoothAvailable() OVERRIDE
{
471 virtual bool GetWifiEnabled() OVERRIDE
{
472 return wifi_enabled_
;
475 virtual bool GetMobileEnabled() OVERRIDE
{
476 return cellular_enabled_
;
479 virtual bool GetBluetoothEnabled() OVERRIDE
{
480 return bluetooth_enabled_
;
483 virtual bool GetMobileScanSupported() OVERRIDE
{
487 virtual bool GetCellularCarrierInfo(std::string
* carrier_id
,
488 std::string
* topup_url
,
489 std::string
* setup_url
) OVERRIDE
{
493 virtual void ShowCellularURL(const std::string
& url
) OVERRIDE
{
496 virtual void ChangeProxySettings() OVERRIDE
{
501 bool cellular_enabled_
;
502 bool bluetooth_enabled_
;
504 bool caps_lock_enabled_
;
505 SkBitmap null_image_
;
507 DISALLOW_COPY_AND_ASSIGN(DummySystemTrayDelegate
);
513 Shell
* Shell::instance_
= NULL
;
515 bool Shell::initially_hide_cursor_
= false;
517 ////////////////////////////////////////////////////////////////////////////////
520 Shell::TestApi::TestApi(Shell
* shell
) : shell_(shell
) {}
522 internal::RootWindowLayoutManager
* Shell::TestApi::root_window_layout() {
523 return shell_
->root_window_layout_
;
526 aura::shared::InputMethodEventFilter
*
527 Shell::TestApi::input_method_event_filter() {
528 return shell_
->input_method_filter_
.get();
531 internal::SystemGestureEventFilter
*
532 Shell::TestApi::system_gesture_event_filter() {
533 return shell_
->system_gesture_filter_
.get();
536 internal::WorkspaceController
* Shell::TestApi::workspace_controller() {
537 return shell_
->workspace_controller_
.get();
540 ////////////////////////////////////////////////////////////////////////////////
543 Shell::Shell(ShellDelegate
* delegate
)
544 : root_window_(aura::MonitorManager::CreateRootWindowForPrimaryMonitor()),
545 screen_(new ScreenAsh(root_window_
.get())),
549 panel_layout_manager_(NULL
),
550 root_window_layout_(NULL
) {
551 gfx::Screen::SetInstance(screen_
);
552 ui_controls::InstallUIControlsAura(CreateUIControlsAura(root_window_
.get()));
556 views::FocusManagerFactory::Install(NULL
);
558 RemoveRootWindowEventFilter(key_rewriter_filter_
.get());
559 RemoveRootWindowEventFilter(partial_screenshot_filter_
.get());
560 RemoveRootWindowEventFilter(input_method_filter_
.get());
561 RemoveRootWindowEventFilter(window_modality_controller_
.get());
562 RemoveRootWindowEventFilter(system_gesture_filter_
.get());
563 #if !defined(OS_MACOSX)
564 RemoveRootWindowEventFilter(accelerator_filter_
.get());
566 if (touch_observer_hud_
.get())
567 RemoveRootWindowEventFilter(touch_observer_hud_
.get());
569 // Close background widget now so that the focus manager of the
570 // widget gets deleted in the final message loop run.
571 root_window_layout_
->SetBackgroundWidget(NULL
);
573 // TooltipController is deleted with the Shell so removing its references.
574 RemoveRootWindowEventFilter(tooltip_controller_
.get());
575 aura::client::SetTooltipClient(GetRootWindow(), NULL
);
577 // Make sure we delete WorkspaceController before launcher is
578 // deleted as it has a reference to launcher model.
579 workspace_controller_
.reset();
581 // The system tray needs to be reset before all the windows are destroyed.
583 tray_delegate_
.reset();
585 // Desroy secondary monitor's widgets before all the windows are destroyed.
586 monitor_controller_
.reset();
588 // Delete containers now so that child windows does not access
589 // observers when they are destructed.
590 aura::RootWindow
* root_window
= GetRootWindow();
591 while (!root_window
->children().empty()) {
592 aura::Window
* child
= root_window
->children()[0];
596 // These need a valid Shell instance to clean up properly, so explicitly
597 // delete them before invalidating the instance.
599 activation_controller_
.reset();
600 drag_drop_controller_
.reset();
601 event_client_
.reset();
602 magnification_controller_
.reset();
603 monitor_controller_
.reset();
604 power_button_controller_
.reset();
605 resize_shadow_controller_
.reset();
606 screen_dimmer_
.reset();
607 shadow_controller_
.reset();
608 tooltip_controller_
.reset();
609 window_cycle_controller_
.reset();
611 // Launcher widget has a InputMethodBridge that references to
612 // input_method_filter_'s input_method_. So explicitly release launcher_
613 // before input_method_filter_. And this needs to be after we delete all
614 // containers in case there are still live browser windows which access
615 // LauncherModel during close.
618 DCHECK(instance_
== this);
623 Shell
* Shell::CreateInstance(ShellDelegate
* delegate
) {
625 aura::Env::GetInstance()->SetMonitorManager(
626 new internal::MultiMonitorManager());
627 instance_
= new Shell(delegate
);
633 Shell
* Shell::GetInstance() {
639 bool Shell::HasInstance() {
644 void Shell::DeleteInstance() {
650 aura::RootWindow
* Shell::GetRootWindow() {
651 return GetInstance()->root_window_
.get();
655 // Install the custom factory first so that views::FocusManagers for Tray,
656 // Launcher, and WallPaper could be created by the factory.
657 views::FocusManagerFactory::Install(new AshFocusManagerFactory
);
659 aura::RootWindow
* root_window
= GetRootWindow();
660 root_filter_
= new aura::shared::RootWindowEventFilter(root_window
);
661 #if !defined(OS_MACOSX)
662 nested_dispatcher_controller_
.reset(new NestedDispatcherController
);
663 accelerator_controller_
.reset(new AcceleratorController
);
665 shell_context_menu_
.reset(new internal::ShellContextMenu
);
666 // Pass ownership of the filter to the root window.
667 GetRootWindow()->SetEventFilter(root_filter_
);
669 // KeyRewriterEventFilter must be the first one.
670 DCHECK(!GetRootWindowEventFilterCount());
671 key_rewriter_filter_
.reset(new internal::KeyRewriterEventFilter
);
672 AddRootWindowEventFilter(key_rewriter_filter_
.get());
674 // PartialScreenshotEventFilter must be the second one to capture key
675 // events when the taking partial screenshot UI is there.
676 DCHECK_EQ(1U, GetRootWindowEventFilterCount());
677 partial_screenshot_filter_
.reset(new internal::PartialScreenshotEventFilter
);
678 AddRootWindowEventFilter(partial_screenshot_filter_
.get());
679 AddShellObserver(partial_screenshot_filter_
.get());
681 // InputMethodEventFilter must be the third one. It has to be added before
682 // AcceleratorFilter.
683 DCHECK_EQ(2U, GetRootWindowEventFilterCount());
684 input_method_filter_
.reset(
685 new aura::shared::InputMethodEventFilter(root_window
));
686 AddRootWindowEventFilter(input_method_filter_
.get());
687 #if !defined(OS_MACOSX)
688 accelerator_filter_
.reset(new internal::AcceleratorFilter
);
689 AddRootWindowEventFilter(accelerator_filter_
.get());
692 system_gesture_filter_
.reset(new internal::SystemGestureEventFilter
);
693 AddRootWindowEventFilter(system_gesture_filter_
.get());
695 root_window
->SetCursor(ui::kCursorPointer
);
696 if (initially_hide_cursor_
)
697 root_window
->ShowCursor(false);
699 activation_controller_
.reset(new internal::ActivationController
);
701 CreateSpecialContainers(root_window
);
703 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
705 if (command_line
->HasSwitch(switches::kAshTouchHud
)) {
706 touch_observer_hud_
.reset(new internal::TouchObserverHUD
);
707 AddRootWindowEventFilter(touch_observer_hud_
.get());
710 stacking_controller_
.reset(new internal::StackingController
);
712 root_window_layout_
= new internal::RootWindowLayoutManager(root_window
);
713 root_window
->SetLayoutManager(root_window_layout_
);
715 event_client_
.reset(new internal::EventClientImpl(root_window
));
717 tray_
.reset(new SystemTray());
719 tray_delegate_
.reset(delegate_
->CreateSystemTrayDelegate(tray_
.get()));
720 if (!tray_delegate_
.get())
721 tray_delegate_
.reset(new DummySystemTrayDelegate());
722 tray_
->CreateItems();
723 tray_
->CreateWidget();
725 // This controller needs to be set before SetupManagedWindowMode.
726 desktop_background_controller_
.reset(new DesktopBackgroundController
);
728 user_wallpaper_delegate_
.reset(delegate_
->CreateUserWallpaperDelegate());
729 if (!user_wallpaper_delegate_
.get())
730 user_wallpaper_delegate_
.reset(new DummyUserWallpaperDelegate());
732 InitLayoutManagers();
734 if (!command_line
->HasSwitch(switches::kAuraNoShadows
)) {
735 resize_shadow_controller_
.reset(new internal::ResizeShadowController());
736 shadow_controller_
.reset(new internal::ShadowController());
739 focus_cycler_
.reset(new internal::FocusCycler());
740 focus_cycler_
->AddWidget(tray_
->widget());
742 if (!delegate_
.get() || delegate_
->IsUserLoggedIn())
746 root_window
->layout_manager()->OnWindowResized();
748 // It needs to be created after OnWindowResized has been called, otherwise the
749 // widget will not paint when restoring after a browser crash.
750 desktop_background_controller_
->SetLoggedInUserWallpaper();
752 window_modality_controller_
.reset(new internal::WindowModalityController
);
753 AddRootWindowEventFilter(window_modality_controller_
.get());
755 visibility_controller_
.reset(new internal::VisibilityController
);
757 tooltip_controller_
.reset(new internal::TooltipController
);
758 AddRootWindowEventFilter(tooltip_controller_
.get());
760 drag_drop_controller_
.reset(new internal::DragDropController
);
761 magnification_controller_
.reset(new internal::MagnificationController
);
762 high_contrast_controller_
.reset(new HighContrastController
);
763 power_button_controller_
.reset(new PowerButtonController
);
764 AddShellObserver(power_button_controller_
.get());
765 video_detector_
.reset(new VideoDetector
);
766 window_cycle_controller_
.reset(new WindowCycleController
);
767 monitor_controller_
.reset(new internal::MonitorController
);
768 screen_dimmer_
.reset(new internal::ScreenDimmer
);
771 aura::Window
* Shell::GetContainer(int container_id
) {
772 return const_cast<aura::Window
*>(
773 const_cast<const Shell
*>(this)->GetContainer(container_id
));
776 const aura::Window
* Shell::GetContainer(int container_id
) const {
777 return GetRootWindow()->GetChildById(container_id
);
780 void Shell::AddRootWindowEventFilter(aura::EventFilter
* filter
) {
781 static_cast<aura::shared::RootWindowEventFilter
*>(
782 GetRootWindow()->event_filter())->AddFilter(filter
);
785 void Shell::RemoveRootWindowEventFilter(aura::EventFilter
* filter
) {
786 static_cast<aura::shared::RootWindowEventFilter
*>(
787 GetRootWindow()->event_filter())->RemoveFilter(filter
);
790 size_t Shell::GetRootWindowEventFilterCount() const {
791 return static_cast<aura::shared::RootWindowEventFilter
*>(
792 GetRootWindow()->event_filter())->GetFilterCount();
795 void Shell::ShowBackgroundMenu(views::Widget
* widget
,
796 const gfx::Point
& location
) {
797 if (shell_context_menu_
.get())
798 shell_context_menu_
->ShowMenu(widget
, location
);
801 void Shell::ToggleAppList() {
802 if (!app_list_controller_
.get())
803 app_list_controller_
.reset(new internal::AppListController
);
804 app_list_controller_
->SetVisible(!app_list_controller_
->IsVisible());
807 bool Shell::GetAppListTargetVisibility() const {
808 return app_list_controller_
.get() &&
809 app_list_controller_
->GetTargetVisibility();
812 aura::Window
* Shell::GetAppListWindow() {
813 return app_list_controller_
.get() ? app_list_controller_
->GetWindow() : NULL
;
816 bool Shell::IsScreenLocked() const {
817 return !delegate_
.get() || delegate_
->IsScreenLocked();
820 bool Shell::IsModalWindowOpen() const {
821 const aura::Window
* modal_container
= GetContainer(
822 internal::kShellWindowId_SystemModalContainer
);
823 return !modal_container
->children().empty();
826 views::NonClientFrameView
* Shell::CreateDefaultNonClientFrameView(
827 views::Widget
* widget
) {
828 if (CommandLine::ForCurrentProcess()->HasSwitch(
829 switches::kAuraGoogleDialogFrames
)) {
830 return new internal::DialogFrameView
;
832 // Use translucent-style window frames for dialogs.
833 CustomFrameViewAsh
* frame_view
= new CustomFrameViewAsh
;
834 frame_view
->Init(widget
);
838 void Shell::RotateFocus(Direction direction
) {
839 focus_cycler_
->RotateFocus(
840 direction
== FORWARD
? internal::FocusCycler::FORWARD
:
841 internal::FocusCycler::BACKWARD
);
844 void Shell::SetMonitorWorkAreaInsets(Window
* contains
,
845 const gfx::Insets
& insets
) {
846 internal::MultiMonitorManager
* monitor_manager
=
847 static_cast<internal::MultiMonitorManager
*>(
848 aura::Env::GetInstance()->monitor_manager());
849 if (!monitor_manager
->UpdateWorkAreaOfMonitorNearestWindow(contains
, insets
))
851 FOR_EACH_OBSERVER(ShellObserver
, observers_
,
852 OnMonitorWorkAreaInsetsChanged());
855 void Shell::OnLoginStateChanged(user::LoginStatus status
) {
856 FOR_EACH_OBSERVER(ShellObserver
, observers_
, OnLoginStateChanged(status
));
859 void Shell::OnAppTerminating() {
860 FOR_EACH_OBSERVER(ShellObserver
, observers_
, OnAppTerminating());
863 void Shell::OnLockStateChanged(bool locked
) {
864 FOR_EACH_OBSERVER(ShellObserver
, observers_
, OnLockStateChanged(locked
));
867 void Shell::CreateLauncher() {
871 aura::Window
* default_container
=
872 GetContainer(internal::kShellWindowId_DefaultContainer
);
873 launcher_
.reset(new Launcher(default_container
));
875 launcher_
->SetFocusCycler(focus_cycler_
.get());
876 shelf_
->SetLauncher(launcher_
.get());
877 if (panel_layout_manager_
)
878 panel_layout_manager_
->SetLauncher(launcher_
.get());
880 launcher_
->widget()->Show();
883 void Shell::AddShellObserver(ShellObserver
* observer
) {
884 observers_
.AddObserver(observer
);
887 void Shell::RemoveShellObserver(ShellObserver
* observer
) {
888 observers_
.RemoveObserver(observer
);
891 void Shell::UpdateShelfVisibility() {
892 shelf_
->UpdateVisibilityState();
895 void Shell::SetShelfAutoHideBehavior(ShelfAutoHideBehavior behavior
) {
896 shelf_
->SetAutoHideBehavior(behavior
);
899 ShelfAutoHideBehavior
Shell::GetShelfAutoHideBehavior() const {
900 return shelf_
->auto_hide_behavior();
903 void Shell::SetShelfAlignment(ShelfAlignment alignment
) {
904 shelf_
->SetAlignment(alignment
);
907 ShelfAlignment
Shell::GetShelfAlignment() {
908 return shelf_
->alignment();
911 int Shell::GetGridSize() const {
912 return workspace_controller_
->workspace_manager()->grid_size();
915 bool Shell::IsInMaximizedMode() const {
916 return workspace_controller_
->workspace_manager()->IsInMaximizedMode();
919 ////////////////////////////////////////////////////////////////////////////////
922 void Shell::InitLayoutManagers() {
923 DCHECK(root_window_layout_
);
924 DCHECK(tray_
->widget());
926 internal::ShelfLayoutManager
* shelf_layout_manager
=
927 new internal::ShelfLayoutManager(tray_
->widget());
928 GetContainer(internal::kShellWindowId_LauncherContainer
)->
929 SetLayoutManager(shelf_layout_manager
);
930 shelf_
= shelf_layout_manager
;
932 internal::StatusAreaLayoutManager
* status_area_layout_manager
=
933 new internal::StatusAreaLayoutManager(shelf_layout_manager
);
934 GetContainer(internal::kShellWindowId_StatusContainer
)->
935 SetLayoutManager(status_area_layout_manager
);
937 aura::Window
* default_container
=
938 GetContainer(internal::kShellWindowId_DefaultContainer
);
939 // Workspace manager has its own layout managers.
940 workspace_controller_
.reset(
941 new internal::WorkspaceController(default_container
));
942 workspace_controller_
->workspace_manager()->set_shelf(shelf_layout_manager
);
943 shelf_layout_manager
->set_workspace_manager(
944 workspace_controller_
->workspace_manager());
946 aura::Window
* always_on_top_container
=
947 GetContainer(internal::kShellWindowId_AlwaysOnTopContainer
);
948 always_on_top_container
->SetLayoutManager(
949 new internal::BaseLayoutManager(
950 always_on_top_container
->GetRootWindow()));
952 // Create Panel layout manager
953 if (CommandLine::ForCurrentProcess()->
954 HasSwitch(switches::kAuraPanelManager
)) {
955 aura::Window
* panel_container
= GetContainer(
956 internal::kShellWindowId_PanelContainer
);
957 panel_layout_manager_
=
958 new internal::PanelLayoutManager(panel_container
);
959 panel_container
->SetEventFilter(
960 new internal::PanelWindowEventFilter(
961 panel_container
, panel_layout_manager_
));
962 panel_container
->SetLayoutManager(panel_layout_manager_
);
966 void Shell::DisableWorkspaceGridLayout() {
967 if (workspace_controller_
.get())
968 workspace_controller_
->workspace_manager()->set_grid_size(0);