Remove stops_event_propagation from Window, since it's broken.

Changes it to be implemented by the Aura client, via a new interface EventClient.
The client can determine whether or not a given window and its subtree can receive events.
I also cleaned up the way screen locking is entered/exited via the delegate, and some stuff in ash/shell.

http://crbug.com/119347
TEST=none
Review URL: https://chromiumcodereview.appspot.com/9788001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@128553 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc
index 80ff70e..2003b32 100644
--- a/ash/shell/app_list.cc
+++ b/ash/shell/app_list.cc
@@ -7,6 +7,8 @@
 #include "ash/app_list/app_list_model.h"
 #include "ash/app_list/app_list_view_delegate.h"
 #include "ash/app_list/app_list_view.h"
+#include "ash/shell.h"
+#include "ash/shell_delegate.h"
 #include "ash/shell/example_factory.h"
 #include "ash/shell/toplevel_window.h"
 #include "base/basictypes.h"
@@ -80,7 +82,7 @@
         break;
       }
       case LOCK_SCREEN: {
-        CreateLockScreen();
+        Shell::GetInstance()->delegate()->LockScreen();
         break;
       }
       case WIDGETS_WINDOW: {
diff --git a/ash/shell/launcher_delegate_impl.cc b/ash/shell/launcher_delegate_impl.cc
new file mode 100644
index 0000000..b5f6e7f
--- /dev/null
+++ b/ash/shell/launcher_delegate_impl.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/shell/launcher_delegate_impl.h"
+
+#include "ash/shell/toplevel_window.h"
+#include "ash/shell/window_watcher.h"
+#include "ash/wm/window_util.h"
+#include "grit/ui_resources.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+namespace shell {
+
+LauncherDelegateImpl::LauncherDelegateImpl(WindowWatcher* watcher)
+    : watcher_(watcher) {
+}
+
+LauncherDelegateImpl::~LauncherDelegateImpl() {
+}
+
+void LauncherDelegateImpl::CreateNewWindow() {
+  ash::shell::ToplevelWindow::CreateParams create_params;
+  create_params.can_resize = true;
+  create_params.can_maximize = true;
+  ash::shell::ToplevelWindow::CreateToplevelWindow(create_params);
+}
+
+void LauncherDelegateImpl::ItemClicked(const ash::LauncherItem& item) {
+  aura::Window* window = watcher_->GetWindowByID(item.id);
+  window->Show();
+  ash::wm::ActivateWindow(window);
+}
+
+int LauncherDelegateImpl::GetBrowserShortcutResourceId() {
+  return IDR_AURA_LAUNCHER_BROWSER_SHORTCUT;
+}
+
+string16 LauncherDelegateImpl::GetTitle(const ash::LauncherItem& item) {
+  return watcher_->GetWindowByID(item.id)->title();
+}
+
+ui::MenuModel* LauncherDelegateImpl::CreateContextMenu(
+    const ash::LauncherItem& item) {
+  return NULL;
+}
+
+ash::LauncherID LauncherDelegateImpl::GetIDByWindow(aura::Window* window) {
+  return watcher_->GetIDByWindow(window);
+}
+
+}  // namespace shell
+}  // namespace ash
diff --git a/ash/shell/launcher_delegate_impl.h b/ash/shell/launcher_delegate_impl.h
new file mode 100644
index 0000000..425e4cfd
--- /dev/null
+++ b/ash/shell/launcher_delegate_impl.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SHELL_LAUNCHER_DELEGATE_IMPL_H_
+#define ASH_SHELL_LAUNCHER_DELEGATE_IMPL_H_
+#pragma once
+
+#include "ash/launcher/launcher_delegate.h"
+#include "base/compiler_specific.h"
+
+namespace aura {
+class Window;
+}
+
+namespace ash {
+namespace shell {
+
+class WindowWatcher;
+
+class LauncherDelegateImpl : public ash::LauncherDelegate {
+ public:
+  explicit LauncherDelegateImpl(WindowWatcher* watcher);
+  virtual ~LauncherDelegateImpl();
+
+  void set_watcher(WindowWatcher* watcher) { watcher_ = watcher; }
+
+  // LauncherDelegate overrides:
+  virtual void CreateNewWindow() OVERRIDE;
+  virtual void ItemClicked(const ash::LauncherItem& item) OVERRIDE;
+  virtual int GetBrowserShortcutResourceId() OVERRIDE;
+  virtual string16 GetTitle(const ash::LauncherItem& item) OVERRIDE;
+  virtual ui::MenuModel* CreateContextMenu(
+      const ash::LauncherItem& item) OVERRIDE;
+  virtual ash::LauncherID GetIDByWindow(aura::Window* window) OVERRIDE;
+
+ private:
+  // Used to update Launcher. Owned by main.
+  WindowWatcher* watcher_;
+
+  DISALLOW_COPY_AND_ASSIGN(LauncherDelegateImpl);
+};
+
+}  // namespace shell
+}  // namespace ash
+
+#endif  // ASH_SHELL_LAUNCHER_DELEGATE_IMPL_H_
diff --git a/ash/shell/lock_view.cc b/ash/shell/lock_view.cc
index c8a4d82..a604e89 100644
--- a/ash/shell/lock_view.cc
+++ b/ash/shell/lock_view.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "ash/shell.h"
+#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/shell/example_factory.h"
 #include "ash/tooltips/tooltip_controller.h"
@@ -11,6 +12,7 @@
 #include "ui/aura/window.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/font.h"
+#include "ui/views/controls/button/text_button.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
 
@@ -19,18 +21,23 @@
 namespace ash {
 namespace shell {
 
-class LockView : public views::WidgetDelegateView {
+class LockView : public views::WidgetDelegateView,
+                 public views::ButtonListener {
  public:
-  LockView() {}
+  LockView() : unlock_button_(ALLOW_THIS_IN_INITIALIZER_LIST(
+                   new views::NativeTextButton(this, ASCIIToUTF16("Unlock")))) {
+    AddChildView(unlock_button_);
+    unlock_button_->set_focusable(true);
+  }
   virtual ~LockView() {}
 
-  // Overridden from View:
+  // Overridden from views::View:
   virtual gfx::Size GetPreferredSize() OVERRIDE {
     return gfx::Size(500, 400);
   }
 
  private:
-  // Overridden from View:
+  // Overridden from views::View:
   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
     canvas->FillRect(GetLocalBounds(), SK_ColorYELLOW);
     string16 text = ASCIIToUTF16("LOCKED!");
@@ -39,14 +46,35 @@
                           (height() - font_.GetHeight()) / 2,
                           string_width, font_.GetHeight());
   }
-  virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE {
-    return true;
+  virtual void Layout() OVERRIDE {
+    gfx::Rect bounds = GetLocalBounds();
+    gfx::Size ps = unlock_button_->GetPreferredSize();
+    bounds.set_y(bounds.bottom() - ps.height() - 5);
+    bounds.set_x((bounds.width() - ps.width()) / 2);
+    bounds.set_size(ps);
+    unlock_button_->SetBoundsRect(bounds);
   }
-  virtual void OnMouseReleased(const views::MouseEvent& event) OVERRIDE {
+  virtual void ViewHierarchyChanged(bool is_add,
+                                    views::View* parent,
+                                    views::View* child) OVERRIDE {
+    if (is_add && child == this)
+      unlock_button_->RequestFocus();
+  }
+
+  // Overridden from views::WidgetDelegateView:
+  virtual void WindowClosing() OVERRIDE {
+    Shell::GetInstance()->delegate()->UnlockScreen();
+  }
+
+  // Overridden from views::ButtonListener:
+  virtual void ButtonPressed(views::Button* sender,
+                             const views::Event& event) OVERRIDE {
+    DCHECK(sender == unlock_button_);
     GetWidget()->Close();
   }
 
   gfx::Font font_;
+  views::NativeTextButton* unlock_button_;
 
   DISALLOW_COPY_AND_ASSIGN(LockView);
 };
@@ -54,7 +82,8 @@
 void CreateLockScreen() {
   LockView* lock_view = new LockView;
   views::Widget* widget = new views::Widget;
-  views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
+  views::Widget::InitParams params(
+      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
   gfx::Size ps = lock_view->GetPreferredSize();
 
   gfx::Size root_window_size = Shell::GetRootWindow()->bounds().size();
@@ -69,6 +98,7 @@
   widget->SetContentsView(lock_view);
   widget->Show();
   widget->GetNativeView()->SetName("LockView");
+  widget->GetNativeView()->Focus();
 
   Shell::GetInstance()->tooltip_controller()->UpdateTooltip(
       widget->GetNativeView());
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc
new file mode 100644
index 0000000..2fb2c27a
--- /dev/null
+++ b/ash/shell/shell_delegate_impl.cc
@@ -0,0 +1,92 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/shell/shell_delegate_impl.h"
+
+#include "ash/shell/example_factory.h"
+#include "ash/shell/launcher_delegate_impl.h"
+#include "ash/shell_window_ids.h"
+#include "ash/wm/partial_screenshot_view.h"
+#include "base/message_loop.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+namespace shell {
+
+ShellDelegateImpl::ShellDelegateImpl()
+    : watcher_(NULL),
+      launcher_delegate_(NULL),
+      locked_(false) {
+}
+
+ShellDelegateImpl::~ShellDelegateImpl() {
+}
+
+void ShellDelegateImpl::SetWatcher(WindowWatcher* watcher) {
+  watcher_ = watcher;
+  if (launcher_delegate_)
+    launcher_delegate_->set_watcher(watcher);
+}
+
+views::Widget* ShellDelegateImpl::CreateStatusArea() {
+  return NULL;
+}
+
+bool ShellDelegateImpl::CanCreateLauncher() {
+  return true;
+}
+
+void ShellDelegateImpl::LockScreen() {
+  ash::shell::CreateLockScreen();
+  locked_ = true;
+}
+
+void ShellDelegateImpl::UnlockScreen() {
+  locked_ = false;
+}
+
+bool ShellDelegateImpl::IsScreenLocked() const {
+  return locked_;
+}
+
+void ShellDelegateImpl::Exit() {
+  MessageLoopForUI::current()->Quit();
+}
+
+ash::AppListViewDelegate* ShellDelegateImpl::CreateAppListViewDelegate() {
+  return ash::shell::CreateAppListViewDelegate();
+}
+
+std::vector<aura::Window*> ShellDelegateImpl::GetCycleWindowList(
+    CycleSource source) const {
+  aura::Window* default_container = ash::Shell::GetInstance()->GetContainer(
+      ash::internal::kShellWindowId_DefaultContainer);
+  std::vector<aura::Window*> windows = default_container->children();
+  // Window cycling expects the topmost window at the front of the list.
+  std::reverse(windows.begin(), windows.end());
+  return windows;
+}
+
+void ShellDelegateImpl::StartPartialScreenshot(
+    ash::ScreenshotDelegate* screenshot_delegate) {
+  ash::PartialScreenshotView::StartPartialScreenshot(screenshot_delegate);
+}
+
+ash::LauncherDelegate* ShellDelegateImpl::CreateLauncherDelegate(
+    ash::LauncherModel* model) {
+  launcher_delegate_ = new LauncherDelegateImpl(watcher_);
+  return launcher_delegate_;
+}
+
+ash::SystemTrayDelegate* ShellDelegateImpl::CreateSystemTrayDelegate(
+    ash::SystemTray* tray) {
+  return NULL;
+}
+
+ash::UserWallpaperDelegate* ShellDelegateImpl::CreateUserWallpaperDelegate() {
+  return NULL;
+}
+
+}  // namespace shell
+}  // namespace ash
diff --git a/ash/shell/shell_delegate_impl.h b/ash/shell/shell_delegate_impl.h
new file mode 100644
index 0000000..797011b
--- /dev/null
+++ b/ash/shell/shell_delegate_impl.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SHELL_SHELL_DELEGATE_IMPL_H_
+#define ASH_SHELL_SHELL_DELEGATE_IMPL_H_
+#pragma once
+
+#include "ash/shell_delegate.h"
+#include "base/compiler_specific.h"
+
+namespace ash {
+namespace shell {
+
+class LauncherDelegateImpl;
+class WindowWatcher;
+
+class ShellDelegateImpl : public ash::ShellDelegate {
+ public:
+  ShellDelegateImpl();
+  virtual ~ShellDelegateImpl();
+
+  void SetWatcher(WindowWatcher* watcher);
+
+  virtual views::Widget* CreateStatusArea() OVERRIDE;
+  virtual bool CanCreateLauncher() OVERRIDE;
+  virtual void LockScreen() OVERRIDE;
+  virtual void UnlockScreen() OVERRIDE;
+  virtual bool IsScreenLocked() const OVERRIDE;
+  virtual void Exit() OVERRIDE;
+  virtual ash::AppListViewDelegate* CreateAppListViewDelegate() OVERRIDE;
+  virtual std::vector<aura::Window*> GetCycleWindowList(
+      CycleSource source) const OVERRIDE;
+  virtual void StartPartialScreenshot(
+      ash::ScreenshotDelegate* screenshot_delegate) OVERRIDE;
+  virtual ash::LauncherDelegate* CreateLauncherDelegate(
+      ash::LauncherModel* model) OVERRIDE;
+  virtual ash::SystemTrayDelegate* CreateSystemTrayDelegate(
+      ash::SystemTray* tray) OVERRIDE;
+  virtual ash::UserWallpaperDelegate* CreateUserWallpaperDelegate() OVERRIDE;
+
+ private:
+  // Used to update Launcher. Owned by main.
+  WindowWatcher* watcher_;
+
+  LauncherDelegateImpl* launcher_delegate_;
+
+  bool locked_;
+
+  DISALLOW_COPY_AND_ASSIGN(ShellDelegateImpl);
+};
+
+}  // namespace shell
+}  // namespace ash
+
+#endif  // ASH_SHELL_SHELL_DELEGATE_IMPL_H_
diff --git a/ash/shell/shell_main.cc b/ash/shell/shell_main.cc
index ee62358..3a5c699 100644
--- a/ash/shell/shell_main.cc
+++ b/ash/shell/shell_main.cc
@@ -12,16 +12,14 @@
 #include "ash/shell_delegate.h"
 #include "ash/shell_factory.h"
 #include "ash/shell_window_ids.h"
-#include "ash/shell/example_factory.h"
-#include "ash/shell/toplevel_window.h"
+#include "ash/shell/launcher_delegate_impl.h"
+#include "ash/shell/shell_delegate_impl.h"
 #include "ash/shell/shell_main_parts.h"
-#include "ash/wm/partial_screenshot_view.h"
-#include "ash/wm/window_util.h"
+#include "ash/shell/window_watcher.h"
 #include "base/at_exit.h"
 #include "base/command_line.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
-#include "grit/ui_resources.h"
 #include "ui/aura/env.h"
 #include "ui/aura/client/window_types.h"
 #include "ui/aura/root_window.h"
@@ -55,198 +53,6 @@
   DISALLOW_COPY_AND_ASSIGN(ShellViewsDelegate);
 };
 
-// WindowWatcher is responsible for listening for newly created windows and
-// creating items on the Launcher for them.
-class WindowWatcher : public aura::WindowObserver {
- public:
-  WindowWatcher()
-      : window_(ash::Shell::GetInstance()->launcher()->window_container()) {
-    window_->AddObserver(this);
-  }
-
-  virtual ~WindowWatcher() {
-    window_->RemoveObserver(this);
-  }
-
-  aura::Window* GetWindowByID(ash::LauncherID id) {
-    IDToWindow::const_iterator i = id_to_window_.find(id);
-    return i != id_to_window_.end() ? i->second : NULL;
-  }
-
-  ash::LauncherID GetIDByWindow(aura::Window* window) const {
-    for (IDToWindow::const_iterator i = id_to_window_.begin();
-         i != id_to_window_.end(); ++i) {
-      if (i->second == window)
-        return i->first;
-    }
-    return 0;  // TODO: add a constant for this.
-  }
-
-  // aura::WindowObserver overrides:
-  virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE {
-    if (new_window->type() != aura::client::WINDOW_TYPE_NORMAL)
-      return;
-
-    static int image_count = 0;
-    ash::LauncherModel* model = ash::Shell::GetInstance()->launcher()->model();
-    ash::LauncherItem item;
-    item.type = ash::TYPE_TABBED;
-    id_to_window_[model->next_id()] = new_window;
-    item.num_tabs = image_count + 1;
-    item.image.setConfig(SkBitmap::kARGB_8888_Config, 16, 16);
-    item.image.allocPixels();
-    item.image.eraseARGB(255,
-                         image_count == 0 ? 255 : 0,
-                         image_count == 1 ? 255 : 0,
-                         image_count == 2 ? 255 : 0);
-    image_count = (image_count + 1) % 3;
-    model->Add(model->item_count(), item);
-  }
-
-  virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE {
-    for (IDToWindow::iterator i = id_to_window_.begin();
-         i != id_to_window_.end(); ++i) {
-      if (i->second == window) {
-        ash::LauncherModel* model =
-            ash::Shell::GetInstance()->launcher()->model();
-        int index = model->ItemIndexByID(i->first);
-        DCHECK_NE(-1, index);
-        model->RemoveItemAt(index);
-        id_to_window_.erase(i);
-        break;
-      }
-    }
-  }
-
- private:
-  typedef std::map<ash::LauncherID, aura::Window*> IDToWindow;
-
-  // Window watching for newly created windows to be added to.
-  aura::Window* window_;
-
-  // Maps from window to the id we gave it.
-  IDToWindow id_to_window_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowWatcher);
-};
-
-class LauncherDelegateImpl : public ash::LauncherDelegate {
- public:
-  explicit LauncherDelegateImpl(WindowWatcher* watcher)
-      : watcher_(watcher) {
-  }
-
-  void set_watcher(WindowWatcher* watcher) { watcher_ = watcher; }
-
-  // LauncherDelegate overrides:
-  virtual void CreateNewWindow() OVERRIDE {
-    ash::shell::ToplevelWindow::CreateParams create_params;
-    create_params.can_resize = true;
-    create_params.can_maximize = true;
-    ash::shell::ToplevelWindow::CreateToplevelWindow(create_params);
-  }
-
-  virtual void ItemClicked(const ash::LauncherItem& item) OVERRIDE {
-    aura::Window* window = watcher_->GetWindowByID(item.id);
-    window->Show();
-    ash::wm::ActivateWindow(window);
-  }
-
-  virtual int GetBrowserShortcutResourceId() OVERRIDE {
-    return IDR_AURA_LAUNCHER_BROWSER_SHORTCUT;
-  }
-
-  virtual string16 GetTitle(const ash::LauncherItem& item) OVERRIDE {
-    return watcher_->GetWindowByID(item.id)->title();
-  }
-
-  virtual ui::MenuModel* CreateContextMenu(
-      const ash::LauncherItem& item) OVERRIDE {
-    return NULL;
-  }
-
-  virtual ash::LauncherID GetIDByWindow(aura::Window* window) OVERRIDE {
-    return watcher_->GetIDByWindow(window);
-  }
-
- private:
-  // Used to update Launcher. Owned by main.
-  WindowWatcher* watcher_;
-
-  DISALLOW_COPY_AND_ASSIGN(LauncherDelegateImpl);
-};
-
-class ShellDelegateImpl : public ash::ShellDelegate {
- public:
-  ShellDelegateImpl() : watcher_(NULL), launcher_delegate_(NULL) {}
-
-  void SetWatcher(WindowWatcher* watcher) {
-    watcher_ = watcher;
-    if (launcher_delegate_)
-      launcher_delegate_->set_watcher(watcher);
-  }
-
-  virtual views::Widget* CreateStatusArea() OVERRIDE {
-    return NULL;
-  }
-
-  virtual bool CanCreateLauncher() OVERRIDE {
-    return true;
-  }
-
-#if defined(OS_CHROMEOS)
-  virtual void LockScreen() OVERRIDE {
-    ash::shell::CreateLockScreen();
-  }
-#endif
-
-  virtual void Exit() OVERRIDE {
-    MessageLoopForUI::current()->Quit();
-  }
-
-  virtual ash::AppListViewDelegate* CreateAppListViewDelegate() OVERRIDE {
-    return ash::shell::CreateAppListViewDelegate();
-  }
-
-  std::vector<aura::Window*> GetCycleWindowList(
-      CycleSource source) const OVERRIDE {
-    aura::Window* default_container = ash::Shell::GetInstance()->GetContainer(
-        ash::internal::kShellWindowId_DefaultContainer);
-    std::vector<aura::Window*> windows = default_container->children();
-    // Window cycling expects the topmost window at the front of the list.
-    std::reverse(windows.begin(), windows.end());
-    return windows;
-  }
-
-  virtual void StartPartialScreenshot(
-      ash::ScreenshotDelegate* screenshot_delegate) OVERRIDE {
-    ash::PartialScreenshotView::StartPartialScreenshot(screenshot_delegate);
-  }
-
-  virtual ash::LauncherDelegate* CreateLauncherDelegate(
-      ash::LauncherModel* model) OVERRIDE {
-    launcher_delegate_ = new LauncherDelegateImpl(watcher_);
-    return launcher_delegate_;
-  }
-
-  virtual ash::SystemTrayDelegate* CreateSystemTrayDelegate(
-      ash::SystemTray* tray) {
-    return NULL;
-  }
-
-  virtual ash::UserWallpaperDelegate* CreateUserWallpaperDelegate() {
-    return NULL;
-  }
-
- private:
-  // Used to update Launcher. Owned by main.
-  WindowWatcher* watcher_;
-
-  LauncherDelegateImpl* launcher_delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(ShellDelegateImpl);
-};
-
 }  // namespace
 
 namespace ash {
@@ -273,10 +79,11 @@
   if (!views::ViewsDelegate::views_delegate)
     views::ViewsDelegate::views_delegate = new ShellViewsDelegate;
 
-  ShellDelegateImpl* delegate = new ShellDelegateImpl;
+  ash::shell::ShellDelegateImpl* delegate = new ash::shell::ShellDelegateImpl;
   ash::Shell::CreateInstance(delegate);
 
-  scoped_ptr<WindowWatcher> window_watcher(new WindowWatcher);
+  scoped_ptr<ash::shell::WindowWatcher> window_watcher(
+      new ash::shell::WindowWatcher);
   delegate->SetWatcher(window_watcher.get());
 
   ash::shell::InitWindowTypeLauncher();
diff --git a/ash/shell/window_type_launcher.cc b/ash/shell/window_type_launcher.cc
index 9efd285e..61d0d9cf 100644
--- a/ash/shell/window_type_launcher.cc
+++ b/ash/shell/window_type_launcher.cc
@@ -4,6 +4,8 @@
 
 #include "ash/shell/window_type_launcher.h"
 
+#include "ash/shell.h"
+#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/shell/example_factory.h"
 #include "ash/shell/panel_window.h"
@@ -323,7 +325,7 @@
   } else if (sender == bubble_button_) {
     CreatePointyBubble(sender);
   } else if (sender == lock_button_) {
-    CreateLockScreen();
+    Shell::GetInstance()->delegate()->LockScreen();
   } else if (sender == widgets_button_) {
     CreateWidgetsWindow();
   } else if (sender == system_modal_button_) {
diff --git a/ash/shell/window_watcher.cc b/ash/shell/window_watcher.cc
new file mode 100644
index 0000000..05c4f74
--- /dev/null
+++ b/ash/shell/window_watcher.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/shell/window_watcher.h"
+
+#include "ash/launcher/launcher.h"
+#include "ash/launcher/launcher_model.h"
+#include "ash/shell.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+namespace shell {
+
+WindowWatcher::WindowWatcher()
+    : window_(ash::Shell::GetInstance()->launcher()->window_container()) {
+  window_->AddObserver(this);
+}
+
+WindowWatcher::~WindowWatcher() {
+  window_->RemoveObserver(this);
+}
+
+aura::Window* WindowWatcher::GetWindowByID(ash::LauncherID id) {
+  IDToWindow::const_iterator i = id_to_window_.find(id);
+  return i != id_to_window_.end() ? i->second : NULL;
+}
+
+ash::LauncherID WindowWatcher::GetIDByWindow(aura::Window* window) const {
+  for (IDToWindow::const_iterator i = id_to_window_.begin();
+       i != id_to_window_.end(); ++i) {
+    if (i->second == window)
+      return i->first;
+  }
+  return 0;  // TODO: add a constant for this.
+}
+
+// aura::WindowObserver overrides:
+void WindowWatcher::OnWindowAdded(aura::Window* new_window) {
+  if (new_window->type() != aura::client::WINDOW_TYPE_NORMAL)
+    return;
+
+  static int image_count = 0;
+  ash::LauncherModel* model = ash::Shell::GetInstance()->launcher()->model();
+  ash::LauncherItem item;
+  item.type = ash::TYPE_TABBED;
+  id_to_window_[model->next_id()] = new_window;
+  item.num_tabs = image_count + 1;
+  item.image.setConfig(SkBitmap::kARGB_8888_Config, 16, 16);
+  item.image.allocPixels();
+  item.image.eraseARGB(255,
+                       image_count == 0 ? 255 : 0,
+                       image_count == 1 ? 255 : 0,
+                       image_count == 2 ? 255 : 0);
+  image_count = (image_count + 1) % 3;
+  model->Add(model->item_count(), item);
+}
+
+void WindowWatcher::OnWillRemoveWindow(aura::Window* window) {
+  for (IDToWindow::iterator i = id_to_window_.begin();
+       i != id_to_window_.end(); ++i) {
+    if (i->second == window) {
+      ash::LauncherModel* model =
+          ash::Shell::GetInstance()->launcher()->model();
+      int index = model->ItemIndexByID(i->first);
+      DCHECK_NE(-1, index);
+      model->RemoveItemAt(index);
+      id_to_window_.erase(i);
+      break;
+    }
+  }
+}
+
+}  // namespace shell
+}  // namespace ash
diff --git a/ash/shell/window_watcher.h b/ash/shell/window_watcher.h
new file mode 100644
index 0000000..d36a4c8
--- /dev/null
+++ b/ash/shell/window_watcher.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SHELL_WINDOW_WATCHER_H_
+#define ASH_SHELL_WINDOW_WATCHER_H_
+#pragma once
+
+#include <map>
+
+#include "ash/launcher/launcher_types.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "ui/aura/window_observer.h"
+
+namespace aura {
+class Window;
+}
+
+namespace ash {
+namespace shell {
+
+// WindowWatcher is responsible for listening for newly created windows and
+// creating items on the Launcher for them.
+class WindowWatcher : public aura::WindowObserver {
+ public:
+  WindowWatcher();
+  virtual ~WindowWatcher();
+
+  aura::Window* GetWindowByID(ash::LauncherID id);
+  ash::LauncherID GetIDByWindow(aura::Window* window) const;
+
+  // aura::WindowObserver overrides:
+  virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE;
+  virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE;
+
+ private:
+  typedef std::map<ash::LauncherID, aura::Window*> IDToWindow;
+
+  // Window watching for newly created windows to be added to.
+  aura::Window* window_;
+
+  // Maps from window to the id we gave it.
+  IDToWindow id_to_window_;
+
+  DISALLOW_COPY_AND_ASSIGN(WindowWatcher);
+};
+
+}  // namespace shell
+}  // namespace ash
+
+#endif  // ASH_SHELL_WINDOW_WATCHER_H_