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.
9 #include "ash/app_list/app_list.h"
10 #include "ash/ash_switches.h"
11 #include "ash/desktop_background/desktop_background_controller.h"
12 #include "ash/desktop_background/desktop_background_resources.h"
13 #include "ash/desktop_background/desktop_background_view.h"
14 #include "ash/drag_drop/drag_drop_controller.h"
15 #include "ash/focus_cycler.h"
16 #include "ash/ime/input_method_event_filter.h"
17 #include "ash/launcher/launcher.h"
18 #include "ash/monitor/multi_monitor_manager.h"
19 #include "ash/monitor/monitor_controller.h"
20 #include "ash/screen_ash.h"
21 #include "ash/shell_delegate.h"
22 #include "ash/shell_factory.h"
23 #include "ash/shell_window_ids.h"
24 #include "ash/system/audio/tray_volume.h"
25 #include "ash/system/bluetooth/tray_bluetooth.h"
26 #include "ash/system/brightness/tray_brightness.h"
27 #include "ash/system/date/tray_date.h"
28 #include "ash/system/ime/tray_ime.h"
29 #include "ash/system/network/tray_network.h"
30 #include "ash/system/power/power_status_observer.h"
31 #include "ash/system/power/power_supply_status.h"
32 #include "ash/system/power/tray_power.h"
33 #include "ash/system/settings/tray_settings.h"
34 #include "ash/system/tray/system_tray_delegate.h"
35 #include "ash/system/tray/system_tray.h"
36 #include "ash/system/tray/tray_empty.h"
37 #include "ash/system/tray_accessibility.h"
38 #include "ash/system/tray_caps_lock.h"
39 #include "ash/system/tray_update.h"
40 #include "ash/system/user/tray_user.h"
41 #include "ash/tooltips/tooltip_controller.h"
42 #include "ash/wm/activation_controller.h"
43 #include "ash/wm/base_layout_manager.h"
44 #include "ash/wm/custom_frame_view_ash.h"
45 #include "ash/wm/dialog_frame_view.h"
46 #include "ash/wm/event_client_impl.h"
47 #include "ash/wm/key_rewriter_event_filter.h"
48 #include "ash/wm/panel_window_event_filter.h"
49 #include "ash/wm/panel_layout_manager.h"
50 #include "ash/wm/partial_screenshot_event_filter.h"
51 #include "ash/wm/power_button_controller.h"
52 #include "ash/wm/resize_shadow_controller.h"
53 #include "ash/wm/root_window_event_filter.h"
54 #include "ash/wm/root_window_layout_manager.h"
55 #include "ash/wm/shadow_controller.h"
56 #include "ash/wm/shelf_layout_manager.h"
57 #include "ash/wm/stacking_controller.h"
58 #include "ash/wm/status_area_layout_manager.h"
59 #include "ash/wm/system_modal_container_layout_manager.h"
60 #include "ash/wm/toplevel_window_event_filter.h"
61 #include "ash/wm/video_detector.h"
62 #include "ash/wm/visibility_controller.h"
63 #include "ash/wm/window_cycle_controller.h"
64 #include "ash/wm/window_modality_controller.h"
65 #include "ash/wm/window_util.h"
66 #include "ash/wm/workspace/always_on_top_layout_manager.h"
67 #include "ash/wm/workspace_controller.h"
68 #include "ash/wm/workspace/workspace_event_filter.h"
69 #include "ash/wm/workspace/workspace_layout_manager.h"
70 #include "ash/wm/workspace/workspace_manager.h"
71 #include "base/bind.h"
72 #include "base/command_line.h"
73 #include "grit/ui_resources.h"
74 #include "third_party/skia/include/core/SkBitmap.h"
75 #include "ui/aura/client/aura_constants.h"
76 #include "ui/aura/env.h"
77 #include "ui/aura/layout_manager.h"
78 #include "ui/aura/monitor.h"
79 #include "ui/aura/monitor_manager.h"
80 #include "ui/aura/monitor_manager.h"
81 #include "ui/aura/root_window.h"
82 #include "ui/aura/ui_controls_aura.h"
83 #include "ui/aura/window.h"
84 #include "ui/gfx/compositor/layer.h"
85 #include "ui/gfx/compositor/layer_animator.h"
86 #include "ui/gfx/size.h"
87 #include "ui/ui_controls/ui_controls.h"
88 #include "ui/views/widget/native_widget_aura.h"
89 #include "ui/views/widget/widget.h"
91 #if !defined(OS_MACOSX)
92 #include "ash/accelerators/accelerator_controller.h"
93 #include "ash/accelerators/accelerator_filter.h"
94 #include "ash/accelerators/nested_dispatcher_controller.h"
104 // Creates a new window for use as a container.
105 aura::Window
* CreateContainer(int window_id
,
107 aura::Window
* parent
) {
108 aura::Window
* container
= new aura::Window(NULL
);
109 container
->set_id(window_id
);
110 container
->SetName(name
);
111 container
->Init(ui::LAYER_NOT_DRAWN
);
112 parent
->AddChild(container
);
113 if (window_id
!= internal::kShellWindowId_UnparentedControlContainer
)
118 // Creates each of the special window containers that holds windows of various
119 // types in the shell UI.
120 void CreateSpecialContainers(aura::RootWindow
* root_window
) {
121 // These containers are just used by PowerButtonController to animate groups
122 // of containers simultaneously without messing up the current transformations
123 // on those containers. These are direct children of the root window; all of
124 // the other containers are their children.
125 aura::Window
* non_lock_screen_containers
= CreateContainer(
126 internal::kShellWindowId_NonLockScreenContainersContainer
,
127 "NonLockScreenContainersContainer",
129 aura::Window
* lock_screen_containers
= CreateContainer(
130 internal::kShellWindowId_LockScreenContainersContainer
,
131 "LockScreenContainersContainer",
133 aura::Window
* lock_screen_related_containers
= CreateContainer(
134 internal::kShellWindowId_LockScreenRelatedContainersContainer
,
135 "LockScreenRelatedContainersContainer",
138 CreateContainer(internal::kShellWindowId_UnparentedControlContainer
,
139 "UnparentedControlContainer",
140 non_lock_screen_containers
);
142 CreateContainer(internal::kShellWindowId_DesktopBackgroundContainer
,
143 "DesktopBackgroundContainer",
144 non_lock_screen_containers
);
146 aura::Window
* default_container
= CreateContainer(
147 internal::kShellWindowId_DefaultContainer
,
149 non_lock_screen_containers
);
150 default_container
->SetEventFilter(
151 new ToplevelWindowEventFilter(default_container
));
152 SetChildWindowVisibilityChangesAnimated(default_container
);
154 aura::Window
* always_on_top_container
= CreateContainer(
155 internal::kShellWindowId_AlwaysOnTopContainer
,
156 "AlwaysOnTopContainer",
157 non_lock_screen_containers
);
158 always_on_top_container
->SetEventFilter(
159 new ToplevelWindowEventFilter(always_on_top_container
));
160 SetChildWindowVisibilityChangesAnimated(always_on_top_container
);
162 aura::Window
* panel_container
= CreateContainer(
163 internal::kShellWindowId_PanelContainer
,
165 non_lock_screen_containers
);
166 if (CommandLine::ForCurrentProcess()->
167 HasSwitch(switches::kAuraPanelManager
)) {
168 internal::PanelLayoutManager
* layout_manager
=
169 new internal::PanelLayoutManager(panel_container
);
170 panel_container
->SetEventFilter(
171 new internal::PanelWindowEventFilter(panel_container
, layout_manager
));
172 panel_container
->SetLayoutManager(layout_manager
);
175 CreateContainer(internal::kShellWindowId_AppListContainer
,
177 non_lock_screen_containers
);
179 CreateContainer(internal::kShellWindowId_LauncherContainer
,
181 non_lock_screen_containers
);
183 aura::Window
* modal_container
= CreateContainer(
184 internal::kShellWindowId_SystemModalContainer
,
185 "SystemModalContainer",
186 non_lock_screen_containers
);
187 modal_container
->SetEventFilter(
188 new ToplevelWindowEventFilter(modal_container
));
189 modal_container
->SetLayoutManager(
190 new internal::SystemModalContainerLayoutManager(modal_container
));
191 SetChildWindowVisibilityChangesAnimated(modal_container
);
193 // TODO(beng): Figure out if we can make this use
194 // SystemModalContainerEventFilter instead of stops_event_propagation.
195 aura::Window
* lock_container
= CreateContainer(
196 internal::kShellWindowId_LockScreenContainer
,
197 "LockScreenContainer",
198 lock_screen_containers
);
199 lock_container
->SetLayoutManager(
200 new internal::BaseLayoutManager(root_window
));
201 // TODO(beng): stopsevents
203 aura::Window
* lock_modal_container
= CreateContainer(
204 internal::kShellWindowId_LockSystemModalContainer
,
205 "LockSystemModalContainer",
206 lock_screen_containers
);
207 lock_modal_container
->SetEventFilter(
208 new ToplevelWindowEventFilter(lock_modal_container
));
209 lock_modal_container
->SetLayoutManager(
210 new internal::SystemModalContainerLayoutManager(lock_modal_container
));
211 SetChildWindowVisibilityChangesAnimated(lock_modal_container
);
213 CreateContainer(internal::kShellWindowId_StatusContainer
,
215 lock_screen_related_containers
);
217 aura::Window
* menu_container
= CreateContainer(
218 internal::kShellWindowId_MenuContainer
,
220 lock_screen_related_containers
);
221 SetChildWindowVisibilityChangesAnimated(menu_container
);
223 aura::Window
* drag_drop_container
= CreateContainer(
224 internal::kShellWindowId_DragImageAndTooltipContainer
,
225 "DragImageAndTooltipContainer",
226 lock_screen_related_containers
);
227 SetChildWindowVisibilityChangesAnimated(drag_drop_container
);
229 aura::Window
* settings_bubble_container
= CreateContainer(
230 internal::kShellWindowId_SettingBubbleContainer
,
231 "SettingBubbleContainer",
232 lock_screen_related_containers
);
233 SetChildWindowVisibilityChangesAnimated(settings_bubble_container
);
235 CreateContainer(internal::kShellWindowId_OverlayContainer
,
237 lock_screen_related_containers
);
240 // This dummy class is used for shell unit tests. We dont have chrome delegate
242 class DummyUserWallpaperDelegate
: public UserWallpaperDelegate
{
244 DummyUserWallpaperDelegate() {}
246 virtual ~DummyUserWallpaperDelegate() {}
248 virtual const int GetUserWallpaperIndex() OVERRIDE
{
252 virtual void OpenSetWallpaperPage() OVERRIDE
{
256 DISALLOW_COPY_AND_ASSIGN(DummyUserWallpaperDelegate
);
259 class DummySystemTrayDelegate
: public SystemTrayDelegate
{
261 DummySystemTrayDelegate()
264 cellular_enabled_(true),
265 bluetooth_enabled_(true),
269 virtual ~DummySystemTrayDelegate() {}
273 virtual bool GetTrayVisibilityOnStartup() OVERRIDE
{ return true; }
275 // Overridden from SystemTrayDelegate:
276 virtual const std::string
GetUserDisplayName() const OVERRIDE
{
277 return "Ãœber tray Ãœber tray Ãœber tray Ãœber tray";
280 virtual const std::string
GetUserEmail() const OVERRIDE
{
284 virtual const SkBitmap
& GetUserImage() const OVERRIDE
{
288 virtual user::LoginStatus
GetUserLoginStatus() const OVERRIDE
{
289 return user::LOGGED_IN_USER
;
292 virtual bool SystemShouldUpgrade() const OVERRIDE
{
296 virtual int GetSystemUpdateIconResource() const OVERRIDE
{
297 return IDR_AURA_UBER_TRAY_UPDATE
;
300 virtual base::HourClockType
GetHourClockType() const OVERRIDE
{
301 return base::k24HourClock
;
304 virtual PowerSupplyStatus
GetPowerSupplyStatus() const OVERRIDE
{
305 return PowerSupplyStatus();
308 virtual void ShowSettings() OVERRIDE
{
311 virtual void ShowDateSettings() OVERRIDE
{
314 virtual void ShowNetworkSettings() OVERRIDE
{
317 virtual void ShowBluetoothSettings() OVERRIDE
{
320 virtual void ShowIMESettings() OVERRIDE
{
323 virtual void ShowHelp() OVERRIDE
{
326 virtual bool IsAudioMuted() const OVERRIDE
{
330 virtual void SetAudioMuted(bool muted
) OVERRIDE
{
334 virtual float GetVolumeLevel() const OVERRIDE
{
338 virtual void SetVolumeLevel(float volume
) OVERRIDE
{
342 virtual bool IsCapsLockOn() const OVERRIDE
{
346 virtual bool IsInAccessibilityMode() const OVERRIDE
{
350 virtual void ShutDown() OVERRIDE
{}
352 virtual void SignOut() OVERRIDE
{
353 MessageLoop::current()->Quit();
356 virtual void RequestLockScreen() OVERRIDE
{}
358 virtual void RequestRestart() OVERRIDE
{}
360 virtual void GetAvailableBluetoothDevices(
361 BluetoothDeviceList
* list
) OVERRIDE
{
364 virtual void ToggleBluetoothConnection(const std::string
& address
) OVERRIDE
{
367 virtual void GetCurrentIME(IMEInfo
* info
) OVERRIDE
{
370 virtual void GetAvailableIMEList(IMEInfoList
* list
) OVERRIDE
{
373 virtual void GetCurrentIMEProperties(IMEPropertyInfoList
* list
) OVERRIDE
{
376 virtual void SwitchIME(const std::string
& ime_id
) OVERRIDE
{
379 virtual void ActivateIMEProperty(const std::string
& key
) OVERRIDE
{
382 virtual void GetMostRelevantNetworkIcon(NetworkIconInfo
* info
,
383 bool large
) OVERRIDE
{
386 virtual void GetAvailableNetworks(
387 std::vector
<NetworkIconInfo
>* list
) OVERRIDE
{
390 virtual void ConnectToNetwork(const std::string
& network_id
) OVERRIDE
{
393 virtual void GetNetworkAddresses(std::string
* ip_address
,
394 std::string
* ethernet_mac_address
,
395 std::string
* wifi_mac_address
) OVERRIDE
{
396 *ip_address
= "127.0.0.1";
397 *ethernet_mac_address
= "00:11:22:33:44:55";
398 *wifi_mac_address
= "66:77:88:99:00:11";
401 virtual void AddBluetoothDevice() OVERRIDE
{
404 virtual void ToggleAirplaneMode() OVERRIDE
{
407 virtual void ToggleWifi() OVERRIDE
{
408 wifi_enabled_
= !wifi_enabled_
;
409 ash::NetworkObserver
* observer
=
410 ash::Shell::GetInstance()->tray()->network_observer();
412 ash::NetworkIconInfo info
;
413 observer
->OnNetworkRefresh(info
);
417 virtual void ToggleCellular() OVERRIDE
{
418 cellular_enabled_
= !cellular_enabled_
;
419 ash::NetworkObserver
* observer
=
420 ash::Shell::GetInstance()->tray()->network_observer();
422 ash::NetworkIconInfo info
;
423 observer
->OnNetworkRefresh(info
);
427 virtual void ToggleBluetooth() OVERRIDE
{
428 bluetooth_enabled_
= !bluetooth_enabled_
;
429 ash::BluetoothObserver
* observer
=
430 ash::Shell::GetInstance()->tray()->bluetooth_observer();
432 observer
->OnBluetoothRefresh();
435 virtual void ShowOtherWifi() OVERRIDE
{
438 virtual void ShowOtherCellular() OVERRIDE
{
441 virtual bool GetWifiAvailable() OVERRIDE
{
445 virtual bool GetCellularAvailable() OVERRIDE
{
449 virtual bool GetBluetoothAvailable() OVERRIDE
{
453 virtual bool GetWifiEnabled() OVERRIDE
{
454 return wifi_enabled_
;
457 virtual bool GetCellularEnabled() OVERRIDE
{
458 return cellular_enabled_
;
461 virtual bool GetBluetoothEnabled() OVERRIDE
{
462 return bluetooth_enabled_
;
465 virtual bool GetCellularScanSupported() OVERRIDE
{
469 virtual bool GetCellularCarrierInfo(std::string
* carrier_id
,
470 std::string
* toup_url
) OVERRIDE
{
474 virtual void ShowCellularTopupURL(const std::string
& topup_url
) OVERRIDE
{
477 virtual void ChangeProxySettings() OVERRIDE
{
482 bool cellular_enabled_
;
483 bool bluetooth_enabled_
;
485 SkBitmap null_image_
;
487 DISALLOW_COPY_AND_ASSIGN(DummySystemTrayDelegate
);
493 Shell
* Shell::instance_
= NULL
;
495 bool Shell::initially_hide_cursor_
= false;
497 ////////////////////////////////////////////////////////////////////////////////
500 Shell::TestApi::TestApi(Shell
* shell
) : shell_(shell
) {}
502 internal::RootWindowLayoutManager
* Shell::TestApi::root_window_layout() {
503 return shell_
->root_window_layout_
;
506 internal::InputMethodEventFilter
* Shell::TestApi::input_method_event_filter() {
507 return shell_
->input_method_filter_
.get();
510 internal::WorkspaceController
* Shell::TestApi::workspace_controller() {
511 return shell_
->workspace_controller_
.get();
514 ////////////////////////////////////////////////////////////////////////////////
517 Shell::Shell(ShellDelegate
* delegate
)
518 : root_window_(aura::MonitorManager::CreateRootWindowForPrimaryMonitor()),
519 screen_(new ScreenAsh(root_window_
.get())),
523 root_window_layout_(NULL
),
524 status_widget_(NULL
) {
525 gfx::Screen::SetInstance(screen_
);
526 ui_controls::InstallUIControlsAura(CreateUIControlsAura(root_window_
.get()));
530 RemoveRootWindowEventFilter(key_rewriter_filter_
.get());
531 RemoveRootWindowEventFilter(partial_screenshot_filter_
.get());
532 RemoveRootWindowEventFilter(input_method_filter_
.get());
533 RemoveRootWindowEventFilter(window_modality_controller_
.get());
534 #if !defined(OS_MACOSX)
535 RemoveRootWindowEventFilter(accelerator_filter_
.get());
538 // Close background widget now so that the focus manager of the
539 // widget gets deleted in the final message loop run.
540 root_window_layout_
->SetBackgroundWidget(NULL
);
542 // TooltipController is deleted with the Shell so removing its references.
543 RemoveRootWindowEventFilter(tooltip_controller_
.get());
544 aura::client::SetTooltipClient(GetRootWindow(), NULL
);
546 // Make sure we delete WorkspaceController before launcher is
547 // deleted as it has a reference to launcher model.
548 workspace_controller_
.reset();
550 // The system tray needs to be reset before all the windows are destroyed.
553 // Desroy secondary monitor's widgets before all the windows are destroyed.
554 monitor_controller_
.reset();
556 // Delete containers now so that child windows does not access
557 // observers when they are destructed.
558 aura::RootWindow
* root_window
= GetRootWindow();
559 while (!root_window
->children().empty()) {
560 aura::Window
* child
= root_window
->children()[0];
564 // These need a valid Shell instance to clean up properly, so explicitly
565 // delete them before invalidating the instance.
567 activation_controller_
.reset();
568 drag_drop_controller_
.reset();
569 resize_shadow_controller_
.reset();
570 shadow_controller_
.reset();
571 window_cycle_controller_
.reset();
572 event_client_
.reset();
573 monitor_controller_
.reset();
575 // Launcher widget has a InputMethodBridge that references to
576 // input_method_filter_'s input_method_. So explicitly release launcher_
577 // before input_method_filter_. And this needs to be after we delete all
578 // containers in case there are still live browser windows which access
579 // LauncherModel during close.
582 DCHECK(instance_
== this);
587 Shell
* Shell::CreateInstance(ShellDelegate
* delegate
) {
589 aura::Env::GetInstance()->SetMonitorManager(
590 new internal::MultiMonitorManager());
591 instance_
= new Shell(delegate
);
597 Shell
* Shell::GetInstance() {
603 bool Shell::HasInstance() {
608 void Shell::DeleteInstance() {
614 aura::RootWindow
* Shell::GetRootWindow() {
615 return GetInstance()->root_window_
.get();
619 aura::RootWindow
* root_window
= GetRootWindow();
620 root_filter_
= new internal::RootWindowEventFilter(root_window
);
621 #if !defined(OS_MACOSX)
622 nested_dispatcher_controller_
.reset(new NestedDispatcherController
);
623 accelerator_controller_
.reset(new AcceleratorController
);
625 // Pass ownership of the filter to the root window.
626 GetRootWindow()->SetEventFilter(root_filter_
);
628 // KeyRewriterEventFilter must be the first one.
629 DCHECK(!GetRootWindowEventFilterCount());
630 key_rewriter_filter_
.reset(new internal::KeyRewriterEventFilter
);
631 AddRootWindowEventFilter(key_rewriter_filter_
.get());
633 // PartialScreenshotEventFilter must be the second one to capture key
634 // events when the taking partial screenshot UI is there.
635 DCHECK_EQ(1U, GetRootWindowEventFilterCount());
636 partial_screenshot_filter_
.reset(new internal::PartialScreenshotEventFilter
);
637 AddRootWindowEventFilter(partial_screenshot_filter_
.get());
639 // Then AcceleratorFilter and InputMethodEventFilter must be added (in this
640 // order) since they have the second highest priority.
641 DCHECK_EQ(2U, GetRootWindowEventFilterCount());
642 #if !defined(OS_MACOSX)
643 accelerator_filter_
.reset(new internal::AcceleratorFilter
);
644 AddRootWindowEventFilter(accelerator_filter_
.get());
645 DCHECK_EQ(3U, GetRootWindowEventFilterCount());
647 input_method_filter_
.reset(new internal::InputMethodEventFilter
);
648 AddRootWindowEventFilter(input_method_filter_
.get());
650 root_window
->SetCursor(aura::kCursorPointer
);
651 if (initially_hide_cursor_
)
652 root_window
->ShowCursor(false);
654 activation_controller_
.reset(new internal::ActivationController
);
656 CreateSpecialContainers(root_window
);
658 stacking_controller_
.reset(new internal::StackingController
);
660 root_window_layout_
= new internal::RootWindowLayoutManager(root_window
);
661 root_window
->SetLayoutManager(root_window_layout_
);
663 event_client_
.reset(new internal::EventClientImpl(root_window
));
666 status_widget_
= delegate_
->CreateStatusArea();
668 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
669 if (!command_line
->HasSwitch(switches::kDisableAshUberTray
)) {
670 // TODO(sad): This is rather ugly at the moment. This is because we are
671 // supporting both the old and the new status bar at the same time. This
672 // will soon get better once the new one is ready and the old one goes out
674 tray_
.reset(new SystemTray());
675 if (status_widget_
) {
676 status_widget_
->GetContentsView()->RemoveAllChildViews(false);
677 status_widget_
->GetContentsView()->AddChildView(tray_
.get());
681 tray_delegate_
.reset(delegate_
->CreateSystemTrayDelegate(tray_
.get()));
682 if (!tray_delegate_
.get())
683 tray_delegate_
.reset(new DummySystemTrayDelegate());
685 internal::TrayVolume
* tray_volume
= new internal::TrayVolume();
686 internal::TrayBluetooth
* tray_bluetooth
= new internal::TrayBluetooth();
687 internal::TrayBrightness
* tray_brightness
= new internal::TrayBrightness();
688 internal::TrayDate
* tray_date
= new internal::TrayDate();
689 internal::TrayPower
* tray_power
= new internal::TrayPower();
690 internal::TrayNetwork
* tray_network
= new internal::TrayNetwork
;
691 internal::TrayUser
* tray_user
= new internal::TrayUser
;
692 internal::TrayAccessibility
* tray_accessibility
=
693 new internal::TrayAccessibility
;
694 internal::TrayCapsLock
* tray_caps_lock
= new internal::TrayCapsLock
;
695 internal::TrayIME
* tray_ime
= new internal::TrayIME
;
696 internal::TrayUpdate
* tray_update
= new internal::TrayUpdate
;
698 tray_
->accessibility_observer_
= tray_accessibility
;
699 tray_
->audio_observer_
= tray_volume
;
700 tray_
->bluetooth_observer_
= tray_bluetooth
;
701 tray_
->brightness_observer_
= tray_brightness
;
702 tray_
->caps_lock_observer_
= tray_caps_lock
;
703 tray_
->clock_observer_
= tray_date
;
704 tray_
->ime_observer_
= tray_ime
;
705 tray_
->network_observer_
= tray_network
;
706 tray_
->power_status_observer_
= tray_power
;
707 tray_
->update_observer_
= tray_update
;
708 tray_
->user_observer_
= tray_user
;
710 tray_
->AddTrayItem(tray_user
);
711 tray_
->AddTrayItem(new internal::TrayEmpty());
712 tray_
->AddTrayItem(tray_power
);
713 tray_
->AddTrayItem(tray_network
);
714 tray_
->AddTrayItem(tray_bluetooth
);
715 tray_
->AddTrayItem(tray_ime
);
716 tray_
->AddTrayItem(tray_volume
);
717 tray_
->AddTrayItem(tray_brightness
);
718 tray_
->AddTrayItem(tray_update
);
719 tray_
->AddTrayItem(new internal::TraySettings());
720 tray_
->AddTrayItem(tray_accessibility
);
721 tray_
->AddTrayItem(tray_caps_lock
);
722 tray_
->AddTrayItem(tray_date
);
724 tray_
->SetVisible(tray_delegate_
->GetTrayVisibilityOnStartup());
727 status_widget_
= internal::CreateStatusArea(tray_
.get());
729 // This controller needs to be set before SetupManagedWindowMode.
730 desktop_background_controller_
.reset(new DesktopBackgroundController
);
732 user_wallpaper_delegate_
.reset(delegate_
->CreateUserWallpaperDelegate());
733 if (!user_wallpaper_delegate_
.get())
734 user_wallpaper_delegate_
.reset(new DummyUserWallpaperDelegate());
736 InitLayoutManagers();
738 if (!command_line
->HasSwitch(switches::kAuraNoShadows
)) {
739 resize_shadow_controller_
.reset(new internal::ResizeShadowController());
740 shadow_controller_
.reset(new internal::ShadowController());
743 focus_cycler_
.reset(new internal::FocusCycler());
744 focus_cycler_
->AddWidget(status_widget_
);
746 if (!delegate_
.get() || delegate_
->IsUserLoggedIn())
750 root_window
->layout_manager()->OnWindowResized();
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 power_button_controller_
.reset(new PowerButtonController
);
762 video_detector_
.reset(new VideoDetector
);
763 window_cycle_controller_
.reset(new WindowCycleController
);
764 monitor_controller_
.reset(new internal::MonitorController
);
767 aura::Window
* Shell::GetContainer(int container_id
) {
768 return const_cast<aura::Window
*>(
769 const_cast<const Shell
*>(this)->GetContainer(container_id
));
772 const aura::Window
* Shell::GetContainer(int container_id
) const {
773 return GetRootWindow()->GetChildById(container_id
);
776 void Shell::AddRootWindowEventFilter(aura::EventFilter
* filter
) {
777 static_cast<internal::RootWindowEventFilter
*>(
778 GetRootWindow()->event_filter())->AddFilter(filter
);
781 void Shell::RemoveRootWindowEventFilter(aura::EventFilter
* filter
) {
782 static_cast<internal::RootWindowEventFilter
*>(
783 GetRootWindow()->event_filter())->RemoveFilter(filter
);
786 size_t Shell::GetRootWindowEventFilterCount() const {
787 return static_cast<internal::RootWindowEventFilter
*>(
788 GetRootWindow()->event_filter())->GetFilterCount();
791 void Shell::ShowBackgroundMenu(views::Widget
* widget
,
792 const gfx::Point
& location
) {
793 if (workspace_controller_
.get())
794 workspace_controller_
->ShowMenu(widget
, location
);
797 void Shell::ToggleAppList() {
798 if (!app_list_
.get())
799 app_list_
.reset(new internal::AppList
);
800 app_list_
->SetVisible(!app_list_
->IsVisible());
803 bool Shell::IsScreenLocked() const {
804 return !delegate_
.get() || delegate_
->IsScreenLocked();
807 bool Shell::IsModalWindowOpen() const {
808 const aura::Window
* modal_container
= GetContainer(
809 internal::kShellWindowId_SystemModalContainer
);
810 return !modal_container
->children().empty();
813 views::NonClientFrameView
* Shell::CreateDefaultNonClientFrameView(
814 views::Widget
* widget
) {
815 if (CommandLine::ForCurrentProcess()->HasSwitch(
816 switches::kAuraGoogleDialogFrames
)) {
817 return new internal::DialogFrameView
;
819 // Use translucent-style window frames for dialogs.
820 CustomFrameViewAsh
* frame_view
= new CustomFrameViewAsh
;
821 frame_view
->Init(widget
);
825 void Shell::RotateFocus(Direction direction
) {
826 focus_cycler_
->RotateFocus(
827 direction
== FORWARD
? internal::FocusCycler::FORWARD
:
828 internal::FocusCycler::BACKWARD
);
831 void Shell::SetMonitorWorkAreaInsets(Window
* contains
,
832 const gfx::Insets
& insets
) {
833 aura::Monitor
* monitor
= aura::Env::GetInstance()->monitor_manager()->
834 GetMonitorNearestWindow(contains
);
835 if (monitor
->work_area_insets() == insets
)
837 monitor
->set_work_area_insets(insets
);
838 FOR_EACH_OBSERVER(ShellObserver
, observers_
,
839 OnMonitorWorkAreaInsetsChanged());
842 void Shell::CreateLauncher() {
846 aura::Window
* default_container
=
847 GetContainer(internal::kShellWindowId_DefaultContainer
);
848 launcher_
.reset(new Launcher(default_container
));
850 launcher_
->SetFocusCycler(focus_cycler_
.get());
851 shelf_
->SetLauncher(launcher_
.get());
853 launcher_
->widget()->Show();
856 void Shell::AddShellObserver(ShellObserver
* observer
) {
857 observers_
.AddObserver(observer
);
860 void Shell::RemoveShellObserver(ShellObserver
* observer
) {
861 observers_
.RemoveObserver(observer
);
864 void Shell::UpdateShelfVisibility() {
865 shelf_
->UpdateVisibilityState();
868 void Shell::SetShelfAutoHideBehavior(ShelfAutoHideBehavior behavior
) {
869 shelf_
->SetAutoHideBehavior(behavior
);
872 ShelfAutoHideBehavior
Shell::GetShelfAutoHideBehavior() const {
873 return shelf_
->auto_hide_behavior();
876 int Shell::GetGridSize() const {
877 return workspace_controller_
->workspace_manager()->grid_size();
880 ////////////////////////////////////////////////////////////////////////////////
883 void Shell::InitLayoutManagers() {
884 DCHECK(root_window_layout_
);
885 DCHECK(status_widget_
);
887 internal::ShelfLayoutManager
* shelf_layout_manager
=
888 new internal::ShelfLayoutManager(status_widget_
);
889 GetContainer(internal::kShellWindowId_LauncherContainer
)->
890 SetLayoutManager(shelf_layout_manager
);
891 shelf_
= shelf_layout_manager
;
893 internal::StatusAreaLayoutManager
* status_area_layout_manager
=
894 new internal::StatusAreaLayoutManager(shelf_layout_manager
);
895 GetContainer(internal::kShellWindowId_StatusContainer
)->
896 SetLayoutManager(status_area_layout_manager
);
898 aura::Window
* default_container
=
899 GetContainer(internal::kShellWindowId_DefaultContainer
);
900 // Workspace manager has its own layout managers.
901 workspace_controller_
.reset(
902 new internal::WorkspaceController(default_container
));
903 workspace_controller_
->workspace_manager()->set_shelf(shelf_layout_manager
);
904 shelf_layout_manager
->set_workspace_manager(
905 workspace_controller_
->workspace_manager());
907 aura::Window
* always_on_top_container
=
908 GetContainer(internal::kShellWindowId_AlwaysOnTopContainer
);
909 always_on_top_container
->SetLayoutManager(
910 new internal::AlwaysOnTopLayoutManager(
911 always_on_top_container
->GetRootWindow()));
913 // Create desktop background widget.
914 // TODO(bshe): We should be able to use OnDesktopBackgroundChanged function
915 // here after issue 117244 got fixed.
916 int index
= user_wallpaper_delegate_
->GetUserWallpaperIndex();
917 desktop_background_controller_
->SetDesktopBackgroundImageMode(
918 GetWallpaper(index
), GetWallpaperInfo(index
).layout
);
921 void Shell::DisableWorkspaceGridLayout() {
922 if (workspace_controller_
.get())
923 workspace_controller_
->workspace_manager()->set_grid_size(0);