summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/focus_cycler_unittest.cc4
-rw-r--r--ash/launcher/launcher.cc3
-rw-r--r--ash/launcher/launcher.h4
-rw-r--r--ash/shell.cc28
-rw-r--r--ash/shell.h9
-rw-r--r--ash/shell/shell_main.cc10
-rw-r--r--ash/shell_delegate.h4
-rw-r--r--ash/test/test_shell_delegate.cc4
-rw-r--r--ash/test/test_shell_delegate.h1
-rw-r--r--ash/wm/shelf_layout_manager.cc62
-rw-r--r--ash/wm/shelf_layout_manager.h5
-rw-r--r--chrome/browser/ui/views/ash/chrome_shell_delegate.cc40
-rw-r--r--chrome/browser/ui/views/ash/chrome_shell_delegate.h13
13 files changed, 139 insertions, 48 deletions
diff --git a/ash/focus_cycler_unittest.cc b/ash/focus_cycler_unittest.cc
index 7380463..9bc23b9 100644
--- a/ash/focus_cycler_unittest.cc
+++ b/ash/focus_cycler_unittest.cc
@@ -60,7 +60,6 @@ TEST_F(FocusCyclerTest, CycleFocusForward) {
ASSERT_TRUE(launcher);
views::Widget* launcher_widget = launcher->widget();
ASSERT_TRUE(launcher_widget);
- focus_cycler->AddWidget(launcher_widget);
launcher->SetFocusCycler(focus_cycler.get());
// Create a single test window.
@@ -103,7 +102,6 @@ TEST_F(FocusCyclerTest, CycleFocusBackward) {
ASSERT_TRUE(launcher);
views::Widget* launcher_widget = launcher->widget();
ASSERT_TRUE(launcher_widget);
- focus_cycler->AddWidget(launcher_widget);
launcher->SetFocusCycler(focus_cycler.get());
// Create a single test window.
@@ -177,7 +175,6 @@ TEST_F(FocusCyclerLauncherTest, CycleFocusForwardInvisible) {
ASSERT_TRUE(launcher);
views::Widget* launcher_widget = launcher->widget();
ASSERT_TRUE(launcher_widget);
- focus_cycler->AddWidget(launcher_widget);
launcher->SetFocusCycler(focus_cycler.get());
// Create a single test window.
@@ -216,7 +213,6 @@ TEST_F(FocusCyclerLauncherTest, CycleFocusBackwardInvisible) {
ASSERT_TRUE(launcher);
views::Widget* launcher_widget = launcher->widget();
ASSERT_TRUE(launcher_widget);
- focus_cycler->AddWidget(launcher_widget);
launcher->SetFocusCycler(focus_cycler.get());
// Create a single test window.
diff --git a/ash/launcher/launcher.cc b/ash/launcher/launcher.cc
index 3c1543f..9f4ba4b 100644
--- a/ash/launcher/launcher.cc
+++ b/ash/launcher/launcher.cc
@@ -71,8 +71,9 @@ Launcher::DelegateView::DelegateView()
Launcher::DelegateView::~DelegateView() {
}
-void Launcher::SetFocusCycler(const internal::FocusCycler* focus_cycler) {
+void Launcher::SetFocusCycler(internal::FocusCycler* focus_cycler) {
delegate_view_->set_focus_cycler(focus_cycler);
+ focus_cycler->AddWidget(widget_.get());
}
void Launcher::DelegateView::SetStatusWidth(int width) {
diff --git a/ash/launcher/launcher.h b/ash/launcher/launcher.h
index 6825771..368d943 100644
--- a/ash/launcher/launcher.h
+++ b/ash/launcher/launcher.h
@@ -37,8 +37,8 @@ class ASH_EXPORT Launcher {
explicit Launcher(aura::Window* window_container);
~Launcher();
- // Sets the focus cycler.
- void SetFocusCycler(const internal::FocusCycler* focus_cycler);
+ // Sets the focus cycler. Also adds the launcher to the cycle.
+ void SetFocusCycler(internal::FocusCycler* focus_cycler);
// Sets the width of the status area.
void SetStatusWidth(int width);
diff --git a/ash/shell.cc b/ash/shell.cc
index dea9786..fdc7b57 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -600,10 +600,6 @@ void Shell::Init() {
if (!status_widget_)
status_widget_ = internal::CreateStatusArea(tray_.get());
- aura::Window* default_container =
- GetContainer(internal::kShellWindowId_DefaultContainer);
- launcher_.reset(new Launcher(default_container));
-
// This controller needs to be set before SetupManagedWindowMode.
desktop_background_controller_.reset(new DesktopBackgroundController);
@@ -616,8 +612,9 @@ void Shell::Init() {
focus_cycler_.reset(new internal::FocusCycler());
focus_cycler_->AddWidget(status_widget_);
- focus_cycler_->AddWidget(launcher_->widget());
- launcher_->SetFocusCycler(focus_cycler_.get());
+
+ if (!delegate_.get() || delegate_->CanCreateLauncher())
+ CreateLauncher();
// Force a layout.
root_window->layout_manager()->OnWindowResized();
@@ -713,6 +710,20 @@ void Shell::SetMonitorWorkAreaInsets(Window* contains,
OnMonitorWorkAreaInsetsChanged());
}
+void Shell::CreateLauncher() {
+ if (launcher_.get())
+ return;
+
+ aura::Window* default_container =
+ GetContainer(internal::kShellWindowId_DefaultContainer);
+ launcher_.reset(new Launcher(default_container));
+
+ launcher_->SetFocusCycler(focus_cycler_.get());
+ shelf_->SetLauncherWidget(launcher_->widget());
+
+ launcher_->widget()->Show();
+}
+
void Shell::AddShellObserver(ShellObserver* observer) {
observers_.AddObserver(observer);
}
@@ -741,7 +752,7 @@ void Shell::InitLayoutManagers() {
DCHECK(status_widget_);
internal::ShelfLayoutManager* shelf_layout_manager =
- new internal::ShelfLayoutManager(launcher_->widget(), status_widget_);
+ new internal::ShelfLayoutManager(status_widget_);
GetContainer(internal::kShellWindowId_LauncherContainer)->
SetLayoutManager(shelf_layout_manager);
shelf_ = shelf_layout_manager;
@@ -758,9 +769,6 @@ void Shell::InitLayoutManagers() {
new internal::WorkspaceController(default_container));
workspace_controller_->workspace_manager()->set_shelf(shelf_layout_manager);
- // Ensure launcher is visible.
- launcher_->widget()->Show();
-
// Create the desktop background image.
desktop_background_controller_->SetDefaultDesktopBackgroundImage();
}
diff --git a/ash/shell.h b/ash/shell.h
index b5fc9cf..06a41d6 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -113,7 +113,7 @@ class ASH_EXPORT Shell : public aura::MonitorObserver {
static void DeleteInstance();
- // Get the singleton RootWindow used by the Shell.
+ // Gets the singleton RootWindow used by the Shell.
static aura::RootWindow* GetRootWindow();
internal::RootWindowLayoutManager* root_window_layout() const {
@@ -145,7 +145,7 @@ class ASH_EXPORT Shell : public aura::MonitorObserver {
views::NonClientFrameView* CreateDefaultNonClientFrameView(
views::Widget* widget);
- // Rotate focus through containers that can receive focus.
+ // Rotates focus through containers that can receive focus.
void RotateFocus(Direction direction);
// Sets the work area insets of the monitor that contains |window|,
@@ -153,7 +153,10 @@ class ASH_EXPORT Shell : public aura::MonitorObserver {
void SetMonitorWorkAreaInsets(aura::Window* window,
const gfx::Insets& insets);
- // Add/remove observer.
+ // Initializes |launcher_|. Does nothing if it's already initialized.
+ void CreateLauncher();
+
+ // Adds/removes observer.
void AddShellObserver(ShellObserver* observer);
void RemoveShellObserver(ShellObserver* observer);
diff --git a/ash/shell/shell_main.cc b/ash/shell/shell_main.cc
index 3ba1285..47d32e7 100644
--- a/ash/shell/shell_main.cc
+++ b/ash/shell/shell_main.cc
@@ -190,10 +190,14 @@ class ShellDelegateImpl : public ash::ShellDelegate {
return NULL;
}
+ virtual bool CanCreateLauncher() OVERRIDE {
+ return true;
+ }
+
#if defined(OS_CHROMEOS)
- virtual void LockScreen() OVERRIDE {
- ash::shell::CreateLockScreen();
- }
+ virtual void LockScreen() OVERRIDE {
+ ash::shell::CreateLockScreen();
+ }
#endif
virtual void Exit() OVERRIDE {
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h
index 8e9076e..9744190 100644
--- a/ash/shell_delegate.h
+++ b/ash/shell_delegate.h
@@ -49,6 +49,10 @@ class ASH_EXPORT ShellDelegate {
// Invoked to create a new status area. Can return NULL.
virtual views::Widget* CreateStatusArea() = 0;
+ // Can we create the launcher yet? In some cases, we may need to defer it
+ // until e.g. a user has logged in and their profile has been loaded.
+ virtual bool CanCreateLauncher() = 0;
+
#if defined(OS_CHROMEOS)
// Invoked when a user uses Ctrl-Shift-L to lock the screen.
virtual void LockScreen() = 0;
diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc
index 16caee5..bf446ca 100644
--- a/ash/test/test_shell_delegate.cc
+++ b/ash/test/test_shell_delegate.cc
@@ -25,6 +25,10 @@ views::Widget* TestShellDelegate::CreateStatusArea() {
return NULL;
}
+bool TestShellDelegate::CanCreateLauncher() {
+ return true;
+}
+
#if defined(OS_CHROMEOS)
void TestShellDelegate::LockScreen() {
}
diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h
index 888b732..90fcbb6 100644
--- a/ash/test/test_shell_delegate.h
+++ b/ash/test/test_shell_delegate.h
@@ -19,6 +19,7 @@ class TestShellDelegate : public ShellDelegate {
// Overridden from ShellDelegate:
virtual views::Widget* CreateStatusArea() OVERRIDE;
+ virtual bool CanCreateLauncher() OVERRIDE;
#if defined(OS_CHROMEOS)
virtual void LockScreen() OVERRIDE;
#endif
diff --git a/ash/wm/shelf_layout_manager.cc b/ash/wm/shelf_layout_manager.cc
index db32647..db1fe84 100644
--- a/ash/wm/shelf_layout_manager.cc
+++ b/ash/wm/shelf_layout_manager.cc
@@ -32,47 +32,60 @@ const int ShelfLayoutManager::kWorkspaceAreaBottomInset = 2;
////////////////////////////////////////////////////////////////////////////////
// ShelfLayoutManager, public:
-ShelfLayoutManager::ShelfLayoutManager(views::Widget* launcher,
- views::Widget* status)
+ShelfLayoutManager::ShelfLayoutManager(views::Widget* status)
: in_layout_(false),
visible_(true),
- max_height_(-1),
- launcher_(launcher),
+ max_height_(status->GetWindowScreenBounds().height()),
+ launcher_(NULL),
status_(status) {
- gfx::Rect launcher_bounds = launcher->GetWindowScreenBounds();
- gfx::Rect status_bounds = status->GetWindowScreenBounds();
- max_height_ = std::max(launcher_bounds.height(), status_bounds.height());
- root_window_ = launcher->GetNativeView()->GetRootWindow();
+ root_window_ = status->GetNativeView()->GetRootWindow();
}
ShelfLayoutManager::~ShelfLayoutManager() {
}
+void ShelfLayoutManager::SetLauncherWidget(views::Widget* launcher) {
+ if (launcher == launcher_)
+ return;
+
+ launcher_ = launcher;
+ max_height_ =
+ std::max(max_height_, launcher->GetWindowScreenBounds().height());
+ LayoutShelf();
+ SetVisible(visible());
+}
+
void ShelfLayoutManager::LayoutShelf() {
AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
StopAnimating();
TargetBounds target_bounds;
float target_opacity = visible_ ? 1.0f : 0.0f;
CalculateTargetBounds(visible_, &target_bounds);
- GetLayer(launcher_)->SetOpacity(target_opacity);
GetLayer(status_)->SetOpacity(target_opacity);
- launcher_->SetBounds(target_bounds.launcher_bounds);
status_->SetBounds(target_bounds.status_bounds);
- Shell::GetInstance()->launcher()->SetStatusWidth(
- target_bounds.status_bounds.width());
+
+ if (launcher_) {
+ GetLayer(launcher_)->SetOpacity(target_opacity);
+ launcher_->SetBounds(target_bounds.launcher_bounds);
+ ash::Shell::GetInstance()->launcher()->SetStatusWidth(
+ target_bounds.status_bounds.width());
+ }
+
Shell::GetInstance()->SetMonitorWorkAreaInsets(
Shell::GetRootWindow(),
target_bounds.work_area_insets);
}
void ShelfLayoutManager::SetVisible(bool visible) {
- ui::Layer* launcher_layer = GetLayer(launcher_);
+ ui::Layer* launcher_layer = launcher_ ? GetLayer(launcher_) : NULL;
ui::Layer* status_layer = GetLayer(status_);
// TODO(vollick): once visibility is animatable, use GetTargetVisibility.
bool current_visibility = visible_ &&
- launcher_layer->GetTargetOpacity() > 0.0f &&
status_layer->GetTargetOpacity() > 0.0f;
+ if (launcher_layer)
+ current_visibility =
+ current_visibility && launcher_layer->GetTargetOpacity() > 0.0f;
if (visible == current_visibility)
return; // Nothing changed.
@@ -84,18 +97,19 @@ void ShelfLayoutManager::SetVisible(bool visible) {
float target_opacity = visible ? 1.0f : 0.0f;
CalculateTargetBounds(visible, &target_bounds);
- ui::ScopedLayerAnimationSettings launcher_animation_setter(
- launcher_layer->GetAnimator());
ui::ScopedLayerAnimationSettings status_animation_setter(
status_layer->GetAnimator());
-
- launcher_animation_setter.AddObserver(this);
status_animation_setter.AddObserver(this);
-
- launcher_layer->SetBounds(target_bounds.launcher_bounds);
- launcher_layer->SetOpacity(target_opacity);
status_layer->SetBounds(target_bounds.status_bounds);
status_layer->SetOpacity(target_opacity);
+
+ if (launcher_layer) {
+ ui::ScopedLayerAnimationSettings launcher_animation_setter(
+ launcher_layer->GetAnimator());
+ launcher_animation_setter.AddObserver(this);
+ launcher_layer->SetBounds(target_bounds.launcher_bounds);
+ launcher_layer->SetOpacity(target_opacity);
+ }
}
////////////////////////////////////////////////////////////////////////////////
@@ -127,7 +141,8 @@ void ShelfLayoutManager::SetChildBounds(aura::Window* child,
void ShelfLayoutManager::StopAnimating() {
StopObservingImplicitAnimations();
- GetLayer(launcher_)->GetAnimator()->StopAnimating();
+ if (launcher_)
+ GetLayer(launcher_)->GetAnimator()->StopAnimating();
GetLayer(status_)->GetAnimator()->StopAnimating();
}
@@ -141,7 +156,8 @@ void ShelfLayoutManager::CalculateTargetBounds(bool visible,
available_bounds.right() - status_bounds.width(),
y + max_height_ - status_bounds.height(),
status_bounds.width(), status_bounds.height());
- gfx::Rect launcher_bounds(launcher_->GetWindowScreenBounds());
+ gfx::Rect launcher_bounds =
+ launcher_ ? launcher_->GetWindowScreenBounds() : gfx::Rect();
target_bounds->launcher_bounds = gfx::Rect(
available_bounds.x(), y + (max_height_ - launcher_bounds.height()) / 2,
available_bounds.width(),
diff --git a/ash/wm/shelf_layout_manager.h b/ash/wm/shelf_layout_manager.h
index b0a9b3c..e70d323 100644
--- a/ash/wm/shelf_layout_manager.h
+++ b/ash/wm/shelf_layout_manager.h
@@ -42,11 +42,14 @@ class ASH_EXPORT ShelfLayoutManager : public aura::LayoutManager,
// the invisible parts of the launcher.
static const int kWorkspaceAreaBottomInset;
- ShelfLayoutManager(views::Widget* launcher, views::Widget* status);
+ explicit ShelfLayoutManager(views::Widget* status);
virtual ~ShelfLayoutManager();
bool in_layout() const { return in_layout_; }
+ // The launcher is typically created after the layout manager.
+ void SetLauncherWidget(views::Widget* launcher);
+
// Stops any animations and sets the bounds of the launcher and status
// widgets.
void LayoutShelf();
diff --git a/chrome/browser/ui/views/ash/chrome_shell_delegate.cc b/chrome/browser/ui/views/ash/chrome_shell_delegate.cc
index 7982438..bbf82ae 100644
--- a/chrome/browser/ui/views/ash/chrome_shell_delegate.cc
+++ b/chrome/browser/ui/views/ash/chrome_shell_delegate.cc
@@ -15,12 +15,16 @@
#include "chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.h"
#include "chrome/browser/ui/views/ash/status_area_host_aura.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
+#include "content/public/browser/notification_service.h"
#include "ui/aura/window.h"
#if defined(OS_CHROMEOS)
+#include "base/chromeos/chromeos_version.h"
#include "chrome/browser/chromeos/dbus/dbus_thread_manager.h"
#include "chrome/browser/chromeos/dbus/power_manager_client.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/system/ash_system_tray_delegate.h"
#endif
namespace {
@@ -45,6 +49,12 @@ ChromeShellDelegate* ChromeShellDelegate::instance_ = NULL;
ChromeShellDelegate::ChromeShellDelegate() {
instance_ = this;
+#if defined(OS_CHROMEOS)
+ registrar_.Add(
+ this,
+ chrome::NOTIFICATION_SESSION_STARTED,
+ content::NotificationService::AllSources());
+#endif
}
ChromeShellDelegate::~ChromeShellDelegate() {
@@ -63,6 +73,19 @@ views::Widget* ChromeShellDelegate::CreateStatusArea() {
return status_area_widget;
}
+bool ChromeShellDelegate::CanCreateLauncher() {
+#if defined(OS_CHROMEOS)
+ // When running a Chrome OS build outside of a device (i.e. on a developer's
+ // workstation), pretend like we're always logged in.
+ if (!base::chromeos::IsRunningOnChromeOS())
+ return true;
+
+ return chromeos::UserManager::Get()->IsUserLoggedIn();
+#else
+ return true;
+#endif
+}
+
#if defined(OS_CHROMEOS)
void ChromeShellDelegate::LockScreen() {
if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession)) {
@@ -109,3 +132,20 @@ ash::SystemTrayDelegate* ChromeShellDelegate::CreateSystemTrayDelegate(
return NULL;
#endif
}
+
+void ChromeShellDelegate::Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+#if defined(OS_CHROMEOS)
+ switch (type) {
+ case chrome::NOTIFICATION_SESSION_STARTED:
+ ash::Shell::GetInstance()->CreateLauncher();
+ break;
+ default:
+ NOTREACHED() << "Unexpected notification " << type;
+ }
+#else
+ // MSVC++ warns about switch statements without any cases.
+ NOTREACHED() << "Unexpected notification " << type;
+#endif
+}
diff --git a/chrome/browser/ui/views/ash/chrome_shell_delegate.h b/chrome/browser/ui/views/ash/chrome_shell_delegate.h
index 125b575..5c30d88 100644
--- a/chrome/browser/ui/views/ash/chrome_shell_delegate.h
+++ b/chrome/browser/ui/views/ash/chrome_shell_delegate.h
@@ -11,6 +11,8 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
class StatusAreaHostAura;
class StatusAreaView;
@@ -19,7 +21,8 @@ namespace views {
class View;
}
-class ChromeShellDelegate : public ash::ShellDelegate {
+class ChromeShellDelegate : public ash::ShellDelegate,
+ public content::NotificationObserver {
public:
ChromeShellDelegate();
virtual ~ChromeShellDelegate();
@@ -34,6 +37,7 @@ class ChromeShellDelegate : public ash::ShellDelegate {
// ash::ShellDelegate overrides;
virtual views::Widget* CreateStatusArea() OVERRIDE;
+ virtual bool CanCreateLauncher() OVERRIDE;
#if defined(OS_CHROMEOS)
virtual void LockScreen() OVERRIDE;
#endif
@@ -48,9 +52,16 @@ class ChromeShellDelegate : public ash::ShellDelegate {
virtual ash::SystemTrayDelegate* CreateSystemTrayDelegate(
ash::SystemTray* tray) OVERRIDE;
+ // content::NotificationObserver override:
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
+
private:
static ChromeShellDelegate* instance_;
+ content::NotificationRegistrar registrar_;
+
scoped_ptr<StatusAreaHostAura> status_area_host_;
DISALLOW_COPY_AND_ASSIGN(ChromeShellDelegate);