Invert the ownership relationship between WindowEventDispatcher and WindowTreeHost.

Prior to this change, WindowEventDispatcher owns WindowTreeHost. Code wishing to own an aura::Window hierarchy must create a WindowEventDispatcher, which will either create a default WTH implementation or use the one supplied by the caller.

This relationship made more sense long ago in the days when WED was called RootWindow, and served a purpose broader than just event dispatch bookkeeping. Those days are gone. For code using Aura, it makes more sense for them to create the WTH directly. I predict this may permit some simplification of shutdown code in some situations, since I think it is more intuitive to think of the destruction cascade initiating at the object that most closely binds to the platform accelerated widget. Today, ownership of the window tree sits with WED, which must destroy the window tree and the host.

This CL attempts to make as few changes as possible to invert the ownership. The effect of this is that there is a bunch of code left that probably only needs a WTH but instead has a WED. I will get around to cleaning these up in a future CL.

http://crbug.com/308843
[email protected]

Review URL: https://codereview.chromium.org/180003006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254071 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/ash/display/cursor_window_controller.cc b/ash/display/cursor_window_controller.cc
index d8b7f13..10ccd14 100644
--- a/ash/display/cursor_window_controller.cc
+++ b/ash/display/cursor_window_controller.cc
@@ -120,9 +120,9 @@
   if (is_cursor_compositing_enabled_) {
     SetDisplay(display_);
   } else {
-    aura::WindowEventDispatcher* mirror_dispatcher = Shell::GetInstance()->
-        display_controller()->mirror_window_controller()->dispatcher();
-    SetContainer(mirror_dispatcher ? mirror_dispatcher->window() : NULL);
+    aura::WindowTreeHost* mirror_host = Shell::GetInstance()->
+        display_controller()->mirror_window_controller()->host();
+    SetContainer(mirror_host ? mirror_host->window() : NULL);
   }
 }
 
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc
index 1383400..43a457b 100644
--- a/ash/display/display_controller.cc
+++ b/ash/display/display_controller.cc
@@ -77,8 +77,8 @@
   return Shell::GetInstance()->display_manager();
 }
 
-void SetDisplayPropertiesOnHostWindow(aura::WindowEventDispatcher* dispatcher,
-                                      const gfx::Display& display) {
+void SetDisplayPropertiesOnHost(aura::WindowTreeHost* host,
+                                const gfx::Display& display) {
   internal::DisplayInfo info =
       GetDisplayManager()->GetDisplayInfo(display.id());
 #if defined(OS_CHROMEOS) && defined(USE_X11)
@@ -110,7 +110,7 @@
   }
 
   int internal = display.IsInternal() ? 1 : 0;
-  gfx::AcceleratedWidget xwindow = dispatcher->host()->GetAcceleratedWidget();
+  gfx::AcceleratedWidget xwindow = host->GetAcceleratedWidget();
   ui::SetIntProperty(xwindow, kInternalProp, kCARDINAL, internal);
   ui::SetIntProperty(xwindow, kRotationProp, kCARDINAL, xrandr_rotation);
   ui::SetIntProperty(xwindow,
@@ -119,17 +119,16 @@
                      100 * display.device_scale_factor());
 #endif
   scoped_ptr<aura::RootWindowTransformer> transformer(
-      internal::CreateRootWindowTransformerForDisplay(dispatcher->window(),
+      internal::CreateRootWindowTransformerForDisplay(host->window(),
                                                       display));
-  dispatcher->host()->SetRootWindowTransformer(transformer.Pass());
+  host->SetRootWindowTransformer(transformer.Pass());
 
   internal::DisplayMode mode;
   if (GetDisplayManager()->GetSelectedModeForDisplayId(display.id(), &mode) &&
       mode.refresh_rate > 0.0f) {
-    dispatcher->host()->compositor()->vsync_manager()->
-        SetAuthoritativeVSyncInterval(
-            base::TimeDelta::FromMicroseconds(
-                base::Time::kMicrosecondsPerSecond / mode.refresh_rate));
+    host->compositor()->vsync_manager()->SetAuthoritativeVSyncInterval(
+        base::TimeDelta::FromMicroseconds(
+            base::Time::kMicrosecondsPerSecond / mode.refresh_rate));
   }
 }
 
@@ -280,7 +279,7 @@
   const gfx::Display& primary_candidate =
       GetDisplayManager()->GetPrimaryDisplayCandidate();
   primary_display_id = primary_candidate.id();
-  AddRootWindowForDisplay(primary_candidate);
+  AddWindowTreeHostForDisplay(primary_candidate);
 }
 
 void DisplayController::InitSecondaryDisplays() {
@@ -288,9 +287,8 @@
   for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
     const gfx::Display& display = display_manager->GetDisplayAt(i);
     if (primary_display_id != display.id()) {
-      aura::WindowEventDispatcher* dispatcher =
-          AddRootWindowForDisplay(display);
-      internal::RootWindowController::CreateForSecondaryDisplay(dispatcher);
+      aura::WindowTreeHost* host = AddWindowTreeHostForDisplay(display);
+      internal::RootWindowController::CreateForSecondaryDisplay(host);
     }
   }
   UpdateHostWindowNames();
@@ -547,7 +545,7 @@
   aura::WindowEventDispatcher* dispatcher =
       root_windows_[display.id()]->GetDispatcher();
   dispatcher->host()->SetBounds(display_info.bounds_in_native());
-  SetDisplayPropertiesOnHostWindow(dispatcher, display);
+  SetDisplayPropertiesOnHost(dispatcher->host(), display);
 }
 
 void DisplayController::OnDisplayAdded(const gfx::Display& display) {
@@ -563,14 +561,13 @@
     aura::WindowEventDispatcher* dispatcher =
         root_windows_[display.id()]->GetDispatcher();
     dispatcher->host()->SetBounds(display_info.bounds_in_native());
-    SetDisplayPropertiesOnHostWindow(dispatcher, display);
+    SetDisplayPropertiesOnHost(dispatcher->host(), display);
   } else {
     if (primary_display_id == gfx::Display::kInvalidDisplayID)
       primary_display_id = display.id();
     DCHECK(!root_windows_.empty());
-    aura::WindowEventDispatcher* dispatcher =
-        AddRootWindowForDisplay(display);
-    internal::RootWindowController::CreateForSecondaryDisplay(dispatcher);
+    aura::WindowTreeHost* host = AddWindowTreeHostForDisplay(display);
+    internal::RootWindowController::CreateForSecondaryDisplay(host);
   }
 }
 
@@ -703,38 +700,34 @@
   EnsurePointerInDisplays();
 }
 
-aura::WindowEventDispatcher* DisplayController::AddRootWindowForDisplay(
+aura::WindowTreeHost* DisplayController::AddWindowTreeHostForDisplay(
     const gfx::Display& display) {
-  static int dispatcher_count = 0;
+  static int host_count = 0;
   const internal::DisplayInfo& display_info =
       GetDisplayManager()->GetDisplayInfo(display.id());
   const gfx::Rect& bounds_in_native = display_info.bounds_in_native();
-  aura::WindowEventDispatcher::CreateParams params(bounds_in_native);
-  params.host = Shell::GetInstance()->window_tree_host_factory()->
-      CreateWindowTreeHost(bounds_in_native);
-  aura::WindowEventDispatcher* dispatcher =
-      new aura::WindowEventDispatcher(params);
-  dispatcher->window()->SetName(
-      base::StringPrintf("RootWindow-%d", dispatcher_count++));
-  dispatcher->host()->compositor()->SetBackgroundColor(SK_ColorBLACK);
+  aura::WindowTreeHost* host =
+      Shell::GetInstance()->window_tree_host_factory()->CreateWindowTreeHost(
+          bounds_in_native);
+  host->window()->SetName(base::StringPrintf("RootWindow-%d", host_count++));
+  host->compositor()->SetBackgroundColor(SK_ColorBLACK);
   // No need to remove RootWindowObserver because
-  // the DisplayController object outlives RootWindow objects.
-  dispatcher->AddRootWindowObserver(this);
-  internal::InitRootWindowSettings(dispatcher->window())->display_id =
-      display.id();
-  dispatcher->host()->InitHost();
+  // the DisplayController object outlives WindowEventDispatcher objects.
+  host->dispatcher()->AddRootWindowObserver(this);
+  internal::InitRootWindowSettings(host->window())->display_id = display.id();
+  host->InitHost();
 
-  root_windows_[display.id()] = dispatcher->window();
-  SetDisplayPropertiesOnHostWindow(dispatcher, display);
+  root_windows_[display.id()] = host->window();
+  SetDisplayPropertiesOnHost(host, display);
 
 #if defined(OS_CHROMEOS)
   static bool force_constrain_pointer_to_root =
       CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kAshConstrainPointerToRoot);
   if (base::SysInfo::IsRunningOnChromeOS() || force_constrain_pointer_to_root)
-    dispatcher->host()->ConfineCursorToRootWindow();
+    host->ConfineCursorToRootWindow();
 #endif
-  return dispatcher;
+  return host;
 }
 
 void DisplayController::OnFadeOutForSwapDisplayFinished() {
diff --git a/ash/display/display_controller.h b/ash/display/display_controller.h
index dfc432e5..565b9be1 100644
--- a/ash/display/display_controller.h
+++ b/ash/display/display_controller.h
@@ -23,7 +23,7 @@
 
 namespace aura {
 class Display;
-class WindowEventDispatcher;
+class WindowTreeHost;
 }
 
 namespace base {
@@ -166,9 +166,9 @@
   friend class internal::DisplayManager;
   friend class internal::MirrorWindowController;
 
-  // Creates a root window for |display| and stores it in the |root_windows_|
+  // Creates a WindowTreeHost for |display| and stores it in the |root_windows_|
   // map.
-  aura::WindowEventDispatcher* AddRootWindowForDisplay(
+  aura::WindowTreeHost* AddWindowTreeHostForDisplay(
       const gfx::Display& display);
 
   void OnFadeOutForSwapDisplayFinished();
diff --git a/ash/display/mirror_window_controller.cc b/ash/display/mirror_window_controller.cc
index 3cb77be..6b1c69ec 100644
--- a/ash/display/mirror_window_controller.cc
+++ b/ash/display/mirror_window_controller.cc
@@ -79,47 +79,42 @@
 }
 
 void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) {
-  static int mirror_dispatcher_count = 0;
+  static int mirror_host_count = 0;
 
-  if (!dispatcher_.get()) {
+  if (!host_.get()) {
     const gfx::Rect& bounds_in_native = display_info.bounds_in_native();
-    aura::WindowEventDispatcher::CreateParams params(bounds_in_native);
-    params.host = Shell::GetInstance()->window_tree_host_factory()->
-        CreateWindowTreeHost(bounds_in_native);
-    dispatcher_.reset(new aura::WindowEventDispatcher(params));
-    dispatcher_->window()->SetName(
-        base::StringPrintf("MirrorRootWindow-%d", mirror_dispatcher_count++));
-    dispatcher_->host()->compositor()->SetBackgroundColor(SK_ColorBLACK);
+    host_.reset(Shell::GetInstance()->window_tree_host_factory()->
+        CreateWindowTreeHost(bounds_in_native));
+    host_->window()->SetName(
+        base::StringPrintf("MirrorRootWindow-%d", mirror_host_count++));
+    host_->compositor()->SetBackgroundColor(SK_ColorBLACK);
     // No need to remove RootWindowObserver because the DisplayController object
     // outlives WindowEventDispatcher objects.
-    dispatcher_->AddRootWindowObserver(
+    host_->dispatcher()->AddRootWindowObserver(
         Shell::GetInstance()->display_controller());
-    dispatcher_->AddRootWindowObserver(this);
+    host_->dispatcher()->AddRootWindowObserver(this);
     // TODO(oshima): TouchHUD is using idkey.
-    InitRootWindowSettings(dispatcher_->window())->display_id =
-        display_info.id();
-    dispatcher_->host()->InitHost();
+    InitRootWindowSettings(host_->window())->display_id = display_info.id();
+    host_->InitHost();
 #if defined(USE_X11)
-    DisableInput(dispatcher_->host()->GetAcceleratedWidget());
+    DisableInput(host_->GetAcceleratedWidget());
 #endif
 
-    aura::client::SetCaptureClient(dispatcher_->window(),
-                                   new NoneCaptureClient());
-    dispatcher_->host()->Show();
+    aura::client::SetCaptureClient(host_->window(), new NoneCaptureClient());
+    host_->Show();
 
     // TODO(oshima): Start mirroring.
     aura::Window* mirror_window = new aura::Window(NULL);
     mirror_window->Init(aura::WINDOW_LAYER_TEXTURED);
-    dispatcher_->window()->AddChild(mirror_window);
-    mirror_window->SetBounds(dispatcher_->window()->bounds());
+    host_->window()->AddChild(mirror_window);
+    mirror_window->SetBounds(host_->window()->bounds());
     mirror_window->Show();
     reflector_ = ui::ContextFactory::GetInstance()->CreateReflector(
         Shell::GetPrimaryRootWindow()->GetDispatcher()->host()->compositor(),
         mirror_window->layer());
   } else {
-    GetRootWindowSettings(dispatcher_->window())->display_id =
-        display_info.id();
-    dispatcher_->host()->SetBounds(display_info.bounds_in_native());
+    GetRootWindowSettings(host_->window())->display_id = display_info.id();
+    host_->SetBounds(display_info.bounds_in_native());
   }
 
   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
@@ -130,11 +125,11 @@
       internal::CreateRootWindowTransformerForMirroredDisplay(
           source_display_info,
           display_info));
-  dispatcher_->host()->SetRootWindowTransformer(transformer.Pass());
+  host_->SetRootWindowTransformer(transformer.Pass());
 }
 
 void MirrorWindowController::UpdateWindow() {
-  if (dispatcher_.get()) {
+  if (host_.get()) {
     DisplayManager* display_manager = Shell::GetInstance()->display_manager();
     const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo(
         display_manager->mirrored_display_id());
@@ -143,18 +138,18 @@
 }
 
 void MirrorWindowController::Close() {
-  if (dispatcher_.get()) {
+  if (host_.get()) {
     ui::ContextFactory::GetInstance()->RemoveReflector(reflector_);
     reflector_ = NULL;
     NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>(
-        aura::client::GetCaptureClient(dispatcher_->window()));
-    aura::client::SetCaptureClient(dispatcher_->window(), NULL);
+        aura::client::GetCaptureClient(host_->window()));
+    aura::client::SetCaptureClient(host_->window(), NULL);
     delete capture_client;
 
-    dispatcher_->RemoveRootWindowObserver(
+    host_->dispatcher()->RemoveRootWindowObserver(
         Shell::GetInstance()->display_controller());
-    dispatcher_->RemoveRootWindowObserver(this);
-    dispatcher_.reset();
+    host_->dispatcher()->RemoveRootWindowObserver(this);
+    host_.reset();
   }
 }
 
@@ -166,8 +161,7 @@
     return;
   mirror_window_host_size_ = dispatcher->host()->GetBounds().size();
   reflector_->OnMirroringCompositorResized();
-  dispatcher_->host()->SetRootWindowTransformer(
-      CreateRootWindowTransformer().Pass());
+  host_->SetRootWindowTransformer(CreateRootWindowTransformer().Pass());
   Shell::GetInstance()->display_controller()->cursor_window_controller()->
       UpdateLocation();
 }
diff --git a/ash/display/mirror_window_controller.h b/ash/display/mirror_window_controller.h
index 5f1cc27d..a0a770c4 100644
--- a/ash/display/mirror_window_controller.h
+++ b/ash/display/mirror_window_controller.h
@@ -10,6 +10,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "ui/aura/root_window_observer.h"
+#include "ui/aura/window_tree_host.h"
 #include "ui/gfx/display.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/point.h"
@@ -18,7 +19,6 @@
 namespace aura {
 class RootWindowTransformer;
 class Window;
-class WindowEventDispatcher;
 }
 
 namespace ui {
@@ -56,8 +56,7 @@
   virtual void OnWindowTreeHostResized(
       const aura::WindowEventDispatcher* root) OVERRIDE;
 
-  // Returns the mirror root window.
-  aura::WindowEventDispatcher* dispatcher() const { return dispatcher_.get(); }
+  aura::WindowTreeHost* host() const { return host_.get(); }
 
  private:
   friend class test::MirrorWindowTestApi;
@@ -66,7 +65,7 @@
   // configuration.
   scoped_ptr<aura::RootWindowTransformer> CreateRootWindowTransformer() const;
 
-  scoped_ptr<aura::WindowEventDispatcher> dispatcher_;
+  scoped_ptr<aura::WindowTreeHost> host_;
   gfx::Size mirror_window_host_size_;
   scoped_refptr<ui::Reflector> reflector_;
 
diff --git a/ash/display/virtual_keyboard_window_controller.cc b/ash/display/virtual_keyboard_window_controller.cc
index 3977ce5..4197992 100644
--- a/ash/display/virtual_keyboard_window_controller.cc
+++ b/ash/display/virtual_keyboard_window_controller.cc
@@ -38,29 +38,24 @@
 
 void VirtualKeyboardWindowController::UpdateWindow(
     const DisplayInfo& display_info) {
-  static int virtual_keyboard_root_window_count = 0;
+  static int virtual_keyboard_host_count = 0;
   if (!root_window_controller_.get()) {
     const gfx::Rect& bounds_in_native = display_info.bounds_in_native();
-    aura::WindowEventDispatcher::CreateParams params(bounds_in_native);
-    params.host = Shell::GetInstance()->window_tree_host_factory()->
-        CreateWindowTreeHost(bounds_in_native);
-    aura::WindowEventDispatcher* dispatcher =
-        new aura::WindowEventDispatcher(params);
-
-    dispatcher->window()->SetName(
+    aura::WindowTreeHost* host =
+        Shell::GetInstance()->window_tree_host_factory()->CreateWindowTreeHost(
+            bounds_in_native);
+    host->window()->SetName(
         base::StringPrintf("VirtualKeyboardRootWindow-%d",
-                           virtual_keyboard_root_window_count++));
+                           virtual_keyboard_host_count++));
 
     // No need to remove RootWindowObserver because
     // the DisplayController object outlives RootWindow objects.
-    dispatcher->AddRootWindowObserver(
+    host->dispatcher()->AddRootWindowObserver(
         Shell::GetInstance()->display_controller());
-    InitRootWindowSettings(dispatcher->window())->display_id =
-        display_info.id();
-    dispatcher->host()->InitHost();
-    RootWindowController::CreateForVirtualKeyboardDisplay(dispatcher);
-    root_window_controller_.reset(GetRootWindowController(
-        dispatcher->window()));
+    InitRootWindowSettings(host->window())->display_id = display_info.id();
+    host->InitHost();
+    RootWindowController::CreateForVirtualKeyboardDisplay(host);
+    root_window_controller_.reset(GetRootWindowController(host->window()));
     root_window_controller_->dispatcher()->host()->Show();
     root_window_controller_->ActivateKeyboard(
         Shell::GetInstance()->keyboard_controller());
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index ded880b..0fbc980 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -263,22 +263,21 @@
 
 namespace internal {
 
-void RootWindowController::CreateForPrimaryDisplay(
-    aura::WindowEventDispatcher* dispatcher) {
-  RootWindowController* controller = new RootWindowController(dispatcher);
+void RootWindowController::CreateForPrimaryDisplay(aura::WindowTreeHost* host) {
+  RootWindowController* controller = new RootWindowController(host);
   controller->Init(RootWindowController::PRIMARY,
                    Shell::GetInstance()->delegate()->IsFirstRunAfterBoot());
 }
 
 void RootWindowController::CreateForSecondaryDisplay(
-    aura::WindowEventDispatcher* dispatcher) {
-  RootWindowController* controller = new RootWindowController(dispatcher);
+    aura::WindowTreeHost* host) {
+  RootWindowController* controller = new RootWindowController(host);
   controller->Init(RootWindowController::SECONDARY, false /* first run */);
 }
 
 void RootWindowController::CreateForVirtualKeyboardDisplay(
-    aura::WindowEventDispatcher* dispatcher) {
-  RootWindowController* controller = new RootWindowController(dispatcher);
+    aura::WindowTreeHost* host) {
+  RootWindowController* controller = new RootWindowController(host);
   controller->Init(RootWindowController::VIRTUAL_KEYBOARD,
                    false /* first run */);
 }
@@ -310,7 +309,7 @@
 
 RootWindowController::~RootWindowController() {
   Shutdown();
-  dispatcher_.reset();
+  host_.reset();
   // The CaptureClient needs to be around for as long as the RootWindow is
   // valid.
   capture_client_.reset();
@@ -355,7 +354,7 @@
   internal::GetRootWindowSettings(root_window())->display_id =
       gfx::Display::kInvalidDisplayID;
   // And this root window should no longer process events.
-  dispatcher_->PrepareForShutdown();
+  dispatcher()->PrepareForShutdown();
 
   system_background_.reset();
 }
@@ -386,7 +385,7 @@
 }
 
 const aura::Window* RootWindowController::GetContainer(int container_id) const {
-  return dispatcher_->window()->GetChildById(container_id);
+  return host_->window()->GetChildById(container_id);
 }
 
 void RootWindowController::ShowShelf() {
@@ -650,22 +649,20 @@
 ////////////////////////////////////////////////////////////////////////////////
 // RootWindowController, private:
 
-RootWindowController::RootWindowController(
-    aura::WindowEventDispatcher* dispatcher)
-    : dispatcher_(dispatcher),
+RootWindowController::RootWindowController(aura::WindowTreeHost* host)
+    : host_(host),
       root_window_layout_(NULL),
       docked_layout_manager_(NULL),
       panel_layout_manager_(NULL),
       touch_hud_debug_(NULL),
       touch_hud_projection_(NULL) {
-  GetRootWindowSettings(dispatcher_->window())->controller = this;
-  screen_dimmer_.reset(new ScreenDimmer(dispatcher_->window()));
+  GetRootWindowSettings(root_window())->controller = this;
+  screen_dimmer_.reset(new ScreenDimmer(root_window()));
 
   stacking_controller_.reset(new StackingController);
-  aura::client::SetWindowTreeClient(dispatcher_->window(),
-                                    stacking_controller_.get());
+  aura::client::SetWindowTreeClient(root_window(), stacking_controller_.get());
   capture_client_.reset(
-      new views::corewm::ScopedCaptureClient(dispatcher_->window()));
+      new views::corewm::ScopedCaptureClient(root_window()));
 }
 
 void RootWindowController::Init(RootWindowType root_window_type,
@@ -673,8 +670,8 @@
   Shell* shell = Shell::GetInstance();
   shell->InitRootWindow(root_window());
 
-  dispatcher_->host()->SetCursor(ui::kCursorPointer);
-  CreateContainersInRootWindow(dispatcher_->window());
+  host_->SetCursor(ui::kCursorPointer);
+  CreateContainersInRootWindow(root_window());
 
   if (root_window_type == VIRTUAL_KEYBOARD) {
     shell->InitKeyboard();
@@ -700,8 +697,8 @@
   } else {
     root_window_layout()->OnWindowResized();
     shell->desktop_background_controller()->OnRootWindowAdded(root_window());
-    shell->high_contrast_controller()->OnRootWindowAdded(dispatcher_->window());
-    dispatcher_->host()->Show();
+    shell->high_contrast_controller()->OnRootWindowAdded(root_window());
+    host_->Show();
 
     // Create a shelf if a user is already logged in.
     if (shell->session_state_delegate()->NumberOfLoggedInUsers())
@@ -793,7 +790,7 @@
            switches::kAshCopyHostBackgroundAtBoot) ||
        CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kAshAnimateFromBootSplashScreen)))
-    boot_splash_screen_.reset(new BootSplashScreen(dispatcher_.get()));
+    boot_splash_screen_.reset(new BootSplashScreen(dispatcher()));
 #endif
 }
 
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h
index 8ec271de..468dcfa 100644
--- a/ash/root_window_controller.h
+++ b/ash/root_window_controller.h
@@ -14,7 +14,7 @@
 #include "base/basictypes.h"
 #include "base/memory/scoped_ptr.h"
 #include "ui/aura/window.h"
-#include "ui/aura/window_event_dispatcher.h"
+#include "ui/aura/window_tree_host.h"
 #include "ui/base/ui_base_types.h"
 
 class SkBitmap;
@@ -83,16 +83,14 @@
  public:
 
   // Creates and Initialize the RootWindowController for primary display.
-  static void CreateForPrimaryDisplay(aura::WindowEventDispatcher* dispatcher);
+  static void CreateForPrimaryDisplay(aura::WindowTreeHost* host);
 
   // Creates and Initialize the RootWindowController for secondary displays.
-  static void CreateForSecondaryDisplay(
-      aura::WindowEventDispatcher* dispatcher);
+  static void CreateForSecondaryDisplay(aura::WindowTreeHost* host);
 
   // Creates and Initialize the RootWindowController for virtual
   // keyboard displays.
-  static void CreateForVirtualKeyboardDisplay(
-      aura::WindowEventDispatcher* dispatcher);
+  static void CreateForVirtualKeyboardDisplay(aura::WindowTreeHost* host);
 
   // Returns a RootWindowController that has a shelf for given
   // |window|. This returns the RootWindowController for the |window|'s
@@ -111,12 +109,11 @@
 
   virtual ~RootWindowController();
 
-  aura::Window* root_window() { return dispatcher()->window(); }
-  const aura::Window* root_window() const { return dispatcher()->window(); }
-
-  aura::WindowEventDispatcher* dispatcher() { return dispatcher_.get(); }
+  aura::Window* root_window() { return host_->window(); }
+  const aura::Window* root_window() const { return host_->window(); }
+  aura::WindowEventDispatcher* dispatcher() { return host_->dispatcher(); }
   const aura::WindowEventDispatcher* dispatcher() const {
-    return dispatcher_.get();
+    return host_->dispatcher();
   }
 
   RootWindowLayoutManager* root_window_layout() { return root_window_layout_; }
@@ -240,7 +237,7 @@
   void DeactivateKeyboard(keyboard::KeyboardController* keyboard_controller);
 
  private:
-  explicit RootWindowController(aura::WindowEventDispatcher* dispatcher);
+  explicit RootWindowController(aura::WindowTreeHost* host);
   enum RootWindowType {
     PRIMARY,
     SECONDARY,
@@ -272,7 +269,7 @@
   virtual void OnLoginStateChanged(user::LoginStatus status) OVERRIDE;
   virtual void OnTouchHudProjectionToggled(bool enabled) OVERRIDE;
 
-  scoped_ptr<aura::WindowEventDispatcher> dispatcher_;
+  scoped_ptr<aura::WindowTreeHost> host_;
   RootWindowLayoutManager* root_window_layout_;
 
   scoped_ptr<StackingController> stacking_controller_;
diff --git a/ash/shell.cc b/ash/shell.cc
index c70e584c..6d561a27 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -956,7 +956,7 @@
   // initialize controller/delegates above when initializing the
   // primary root window controller.
   internal::RootWindowController::CreateForPrimaryDisplay(
-      root_window->GetDispatcher());
+      root_window->GetDispatcher()->host());
 
   display_controller_->InitSecondaryDisplays();
 
diff --git a/ash/test/mirror_window_test_api.cc b/ash/test/mirror_window_test_api.cc
index 4c098f2..dd495f61 100644
--- a/ash/test/mirror_window_test_api.cc
+++ b/ash/test/mirror_window_test_api.cc
@@ -15,8 +15,9 @@
 namespace test {
 
 const aura::WindowEventDispatcher* MirrorWindowTestApi::GetDispatcher() const {
-  return Shell::GetInstance()->display_controller()->
-      mirror_window_controller()->dispatcher_.get();
+  aura::WindowTreeHost* host = Shell::GetInstance()->display_controller()->
+      mirror_window_controller()->host_.get();
+  return host ? host->dispatcher() : NULL;
 }
 
 int MirrorWindowTestApi::GetCurrentCursorType() const {
diff --git a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_x11.cc b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_x11.cc
index b208f72..49f9ae2e4 100644
--- a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_x11.cc
+++ b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_x11.cc
@@ -42,10 +42,8 @@
 
 void BrowserDesktopWindowTreeHostX11::Init(
     aura::Window* content_window,
-    const views::Widget::InitParams& params,
-    aura::WindowEventDispatcher::CreateParams* rw_create_params) {
-  views::DesktopWindowTreeHostX11::Init(content_window, params,
-                                        rw_create_params);
+    const views::Widget::InitParams& params) {
+  views::DesktopWindowTreeHostX11::Init(content_window, params);
 
   // We have now created our backing X11 window. We now need to (possibly)
   // alert Unity that there's a menu bar attached to it.
diff --git a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_x11.h b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_x11.h
index d104b95..d746c807 100644
--- a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_x11.h
+++ b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_x11.h
@@ -35,8 +35,7 @@
   // Overridden from views::DesktopWindowTreeHostX11:
   virtual void Init(
       aura::Window* content_window,
-      const views::Widget::InitParams& params,
-      aura::WindowEventDispatcher::CreateParams* rw_create_params) OVERRIDE;
+      const views::Widget::InitParams& params) OVERRIDE;
   virtual void CloseNow() OVERRIDE;
 
   BrowserView* browser_view_;
diff --git a/content/shell/browser/shell_platform_data_aura.cc b/content/shell/browser/shell_platform_data_aura.cc
index 95af492..fdbf634 100644
--- a/content/shell/browser/shell_platform_data_aura.cc
+++ b/content/shell/browser/shell_platform_data_aura.cc
@@ -63,20 +63,20 @@
 class MinimalInputEventFilter : public ui::internal::InputMethodDelegate,
                                 public ui::EventHandler {
  public:
-  explicit MinimalInputEventFilter(aura::WindowEventDispatcher* dispatcher)
-      : dispatcher_(dispatcher),
+  explicit MinimalInputEventFilter(aura::WindowTreeHost* host)
+      : host_(host),
         input_method_(ui::CreateInputMethod(this,
                                             gfx::kNullAcceleratedWidget)) {
     input_method_->Init(true);
-    dispatcher_->window()->AddPreTargetHandler(this);
-    dispatcher_->window()->SetProperty(aura::client::kRootWindowInputMethodKey,
-                                       input_method_.get());
+    host_->window()->AddPreTargetHandler(this);
+    host_->window()->SetProperty(aura::client::kRootWindowInputMethodKey,
+                                 input_method_.get());
   }
 
   virtual ~MinimalInputEventFilter() {
-    dispatcher_->window()->RemovePreTargetHandler(this);
-    dispatcher_->window()->SetProperty(aura::client::kRootWindowInputMethodKey,
-                                       static_cast<ui::InputMethod*>(NULL));
+    host_->window()->RemovePreTargetHandler(this);
+    host_->window()->SetProperty(aura::client::kRootWindowInputMethodKey,
+                                 static_cast<ui::InputMethod*>(NULL));
   }
 
  private:
@@ -98,11 +98,11 @@
   virtual bool DispatchKeyEventPostIME(const ui::KeyEvent& event) OVERRIDE {
     ui::TranslatedKeyEvent aura_event(event);
     ui::EventDispatchDetails details =
-        dispatcher_->OnEventFromSource(&aura_event);
+        host_->dispatcher()->OnEventFromSource(&aura_event);
     return aura_event.handled() || details.dispatcher_destroyed;
   }
 
-  aura::WindowEventDispatcher* dispatcher_;
+  aura::WindowTreeHost* host_;
   scoped_ptr<ui::InputMethod> input_method_;
 
   DISALLOW_COPY_AND_ASSIGN(MinimalInputEventFilter);
@@ -114,35 +114,31 @@
 
 ShellPlatformDataAura::ShellPlatformDataAura(const gfx::Size& initial_size) {
   aura::Env::CreateInstance();
-  dispatcher_.reset(new aura::WindowEventDispatcher(
-      aura::WindowEventDispatcher::CreateParams(gfx::Rect(initial_size))));
-  dispatcher_->host()->InitHost();
-  dispatcher_->window()->SetLayoutManager(
-      new FillLayout(dispatcher_->window()));
+  host_.reset(aura::WindowTreeHost::Create(gfx::Rect(initial_size)));
+  host_->InitHost();
+  host_->window()->SetLayoutManager(new FillLayout(host_->window()));
 
   focus_client_.reset(new aura::test::TestFocusClient());
-  aura::client::SetFocusClient(dispatcher_->window(), focus_client_.get());
+  aura::client::SetFocusClient(host_->window(), focus_client_.get());
 
   activation_client_.reset(
-      new aura::client::DefaultActivationClient(dispatcher_->window()));
+      new aura::client::DefaultActivationClient(host_->window()));
   capture_client_.reset(
-      new aura::client::DefaultCaptureClient(dispatcher_->window()));
+      new aura::client::DefaultCaptureClient(host_->window()));
   window_tree_client_.reset(
-      new aura::test::TestWindowTreeClient(dispatcher_->window()));
-  ime_filter_.reset(new MinimalInputEventFilter(dispatcher_.get()));
+      new aura::test::TestWindowTreeClient(host_->window()));
+  ime_filter_.reset(new MinimalInputEventFilter(host_.get()));
 }
 
 ShellPlatformDataAura::~ShellPlatformDataAura() {
 }
 
 void ShellPlatformDataAura::ShowWindow() {
-  dispatcher_->host()->Show();
+  host_->Show();
 }
 
 void ShellPlatformDataAura::ResizeWindow(const gfx::Size& size) {
-  dispatcher_->host()->SetBounds(gfx::Rect(size));
+  host_->SetBounds(gfx::Rect(size));
 }
 
-
-
 }  // namespace content
diff --git a/content/shell/browser/shell_platform_data_aura.h b/content/shell/browser/shell_platform_data_aura.h
index 1a50cec..0a52d97 100644
--- a/content/shell/browser/shell_platform_data_aura.h
+++ b/content/shell/browser/shell_platform_data_aura.h
@@ -6,9 +6,9 @@
 #define CONTENT_SHELL_BROWSER_SHELL_PLATFORM_DATA_AURA_H_
 
 #include "base/memory/scoped_ptr.h"
+#include "ui/aura/window_tree_host.h"
 
 namespace aura {
-class WindowEventDispatcher;
 namespace client {
 class DefaultActivationClient;
 class DefaultCaptureClient;
@@ -35,10 +35,10 @@
   void ShowWindow();
   void ResizeWindow(const gfx::Size& size);
 
-  aura::WindowEventDispatcher* dispatcher() { return dispatcher_.get(); }
+  aura::WindowEventDispatcher* dispatcher() { return host_->dispatcher(); }
 
  private:
-  scoped_ptr<aura::WindowEventDispatcher> dispatcher_;
+  scoped_ptr<aura::WindowTreeHost> host_;
   scoped_ptr<aura::client::FocusClient> focus_client_;
   scoped_ptr<aura::client::DefaultActivationClient> activation_client_;
   scoped_ptr<aura::client::DefaultCaptureClient> capture_client_;
diff --git a/mojo/examples/aura_demo/aura_demo.cc b/mojo/examples/aura_demo/aura_demo.cc
index a9bf880..a65036a 100644
--- a/mojo/examples/aura_demo/aura_demo.cc
+++ b/mojo/examples/aura_demo/aura_demo.cc
@@ -22,7 +22,6 @@
 #include "ui/aura/env.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_delegate.h"
-#include "ui/aura/window_event_dispatcher.h"
 #include "ui/base/hit_test.h"
 #include "ui/gfx/canvas.h"
 
@@ -134,28 +133,24 @@
 
  private:
   void HostContextCreated() {
-    aura::WindowEventDispatcher::CreateParams params(
-        gfx::Rect(window_tree_host_->bounds().size()));
-    params.host = window_tree_host_.get();
-    dispatcher_.reset(new aura::WindowEventDispatcher(params));
-    window_tree_host_->set_delegate(dispatcher_.get());
-    dispatcher_->host()->InitHost();
+    window_tree_host_->InitHost();
 
-    window_tree_client_.reset(new DemoWindowTreeClient(dispatcher_->window()));
+    window_tree_client_.reset(
+        new DemoWindowTreeClient(window_tree_host_->window()));
 
     delegate1_.reset(new DemoWindowDelegate(SK_ColorBLUE));
     window1_ = new aura::Window(delegate1_.get());
     window1_->Init(aura::WINDOW_LAYER_TEXTURED);
     window1_->SetBounds(gfx::Rect(100, 100, 400, 400));
     window1_->Show();
-    dispatcher_->window()->AddChild(window1_);
+    window_tree_host_->window()->AddChild(window1_);
 
     delegate2_.reset(new DemoWindowDelegate(SK_ColorRED));
     window2_ = new aura::Window(delegate2_.get());
     window2_->Init(aura::WINDOW_LAYER_TEXTURED);
     window2_->SetBounds(gfx::Rect(200, 200, 350, 350));
     window2_->Show();
-    dispatcher_->window()->AddChild(window2_);
+    window_tree_host_->window()->AddChild(window2_);
 
     delegate21_.reset(new DemoWindowDelegate(SK_ColorGREEN));
     window21_ = new aura::Window(delegate21_.get());
@@ -164,7 +159,7 @@
     window21_->Show();
     window2_->AddChild(window21_);
 
-    dispatcher_->host()->Show();
+    window_tree_host_->Show();
   }
 
   scoped_ptr<DemoScreen> screen_;
@@ -179,8 +174,7 @@
   aura::Window* window2_;
   aura::Window* window21_;
 
-  scoped_ptr<WindowTreeHostMojo> window_tree_host_;
-  scoped_ptr<aura::WindowEventDispatcher> dispatcher_;
+  scoped_ptr<aura::WindowTreeHost> window_tree_host_;
 };
 
 }  // namespace examples
diff --git a/mojo/examples/launcher/launcher.cc b/mojo/examples/launcher/launcher.cc
index 5e19f84..a86bb25 100644
--- a/mojo/examples/launcher/launcher.cc
+++ b/mojo/examples/launcher/launcher.cc
@@ -221,14 +221,14 @@
 
   // Overridden from Launcher:
   virtual void Show() OVERRIDE {
-    if (!dispatcher_.get()) {
+    if (!window_tree_host_.get()) {
       pending_show_ = true;
       return;
     }
-    dispatcher_->host()->Show();
+    window_tree_host_->Show();
   }
   virtual void Hide() OVERRIDE {
-    dispatcher_->host()->Hide();
+    window_tree_host_->Hide();
   }
 
   // Overridden from URLReceiver:
@@ -238,25 +238,22 @@
   }
 
   void HostContextCreated() {
-    aura::WindowEventDispatcher::CreateParams params(gfx::Rect(450, 60));
-    params.host = window_tree_host_.get();
-    dispatcher_.reset(new aura::WindowEventDispatcher(params));
-    window_tree_host_->set_delegate(dispatcher_.get());
-    dispatcher_->host()->InitHost();
-    dispatcher_->window()->SetBounds(gfx::Rect(450, 60));
+    window_tree_host_->InitHost();
+    window_tree_host_->window()->SetBounds(gfx::Rect(450, 60));
 
     focus_client_.reset(new aura::test::TestFocusClient());
-    aura::client::SetFocusClient(dispatcher_->window(), focus_client_.get());
+    aura::client::SetFocusClient(window_tree_host_->window(),
+                                 focus_client_.get());
     activation_client_.reset(
-        new aura::client::DefaultActivationClient(dispatcher_->window()));
+        new aura::client::DefaultActivationClient(window_tree_host_->window()));
     capture_client_.reset(
-        new aura::client::DefaultCaptureClient(dispatcher_->window()));
-    ime_filter_.reset(new MinimalInputEventFilter(dispatcher_->window()));
+        new aura::client::DefaultCaptureClient(window_tree_host_->window()));
+    ime_filter_.reset(new MinimalInputEventFilter(window_tree_host_->window()));
 
     window_tree_client_.reset(
-        new LauncherWindowTreeClient(dispatcher_->window()));
+        new LauncherWindowTreeClient(window_tree_host_->window()));
 
-    launcher_controller_.InitInWindow(dispatcher_->window());
+    launcher_controller_.InitInWindow(window_tree_host_->window());
 
     if (pending_show_) {
       pending_show_ = false;
@@ -274,8 +271,7 @@
   LauncherController launcher_controller_;
 
   RemotePtr<LauncherClient> launcher_client_;
-  scoped_ptr<WindowTreeHostMojo> window_tree_host_;
-  scoped_ptr<aura::WindowEventDispatcher> dispatcher_;
+  scoped_ptr<aura::WindowTreeHost> window_tree_host_;
 
   bool pending_show_;
 };
diff --git a/ui/aura/bench/bench_main.cc b/ui/aura/bench/bench_main.cc
index 7692633..43092a83 100644
--- a/ui/aura/bench/bench_main.cc
+++ b/ui/aura/bench/bench_main.cc
@@ -19,7 +19,7 @@
 #include "ui/aura/test/test_focus_client.h"
 #include "ui/aura/test/test_screen.h"
 #include "ui/aura/window.h"
-#include "ui/aura/window_event_dispatcher.h"
+#include "ui/aura/window_tree_host.h"
 #include "ui/base/hit_test.h"
 #include "ui/compositor/compositor.h"
 #include "ui/compositor/compositor_observer.h"
@@ -300,20 +300,20 @@
   scoped_ptr<aura::TestScreen> test_screen(
       aura::TestScreen::CreateFullscreen());
   gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen.get());
-  scoped_ptr<aura::WindowEventDispatcher> dispatcher(
-      test_screen->CreateRootWindowForPrimaryDisplay());
+  scoped_ptr<aura::WindowTreeHost> host(
+      test_screen->CreateHostForPrimaryDisplay());
   aura::client::SetCaptureClient(
-      dispatcher->window(),
-      new aura::client::DefaultCaptureClient(dispatcher->window()));
+      host->window(),
+      new aura::client::DefaultCaptureClient(host->window()));
 
   scoped_ptr<aura::client::FocusClient> focus_client(
       new aura::test::TestFocusClient);
-  aura::client::SetFocusClient(dispatcher->window(), focus_client.get());
+  aura::client::SetFocusClient(host->window(), focus_client.get());
 
   // add layers
   ColoredLayer background(SK_ColorRED);
-  background.SetBounds(dispatcher->window()->bounds());
-  dispatcher->window()->layer()->Add(&background);
+  background.SetBounds(host->window()->bounds());
+  host->window()->layer()->Add(&background);
 
   ColoredLayer window(SK_ColorBLUE);
   window.SetBounds(gfx::Rect(background.bounds().size()));
@@ -338,22 +338,22 @@
 
   if (command_line->HasSwitch("bench-software-scroll")) {
     bench.reset(new SoftwareScrollBench(&page_background,
-                                        dispatcher->host()->compositor(),
+                                        host->compositor(),
                                         frames));
   } else {
     bench.reset(new WebGLBench(&page_background,
-                               dispatcher->host()->compositor(),
+                               host->compositor(),
                                frames));
   }
 
 #ifndef NDEBUG
-  ui::PrintLayerHierarchy(dispatcher->window()->layer(), gfx::Point(100, 100));
+  ui::PrintLayerHierarchy(host->window()->layer(), gfx::Point(100, 100));
 #endif
 
-  dispatcher->host()->Show();
+  host->Show();
   base::MessageLoopForUI::current()->Run();
   focus_client.reset();
-  dispatcher.reset();
+  host.reset();
 
   return 0;
 }
diff --git a/ui/aura/demo/demo_main.cc b/ui/aura/demo/demo_main.cc
index b818663a..40de256f 100644
--- a/ui/aura/demo/demo_main.cc
+++ b/ui/aura/demo/demo_main.cc
@@ -15,7 +15,7 @@
 #include "ui/aura/test/test_screen.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_delegate.h"
-#include "ui/aura/window_event_dispatcher.h"
+#include "ui/aura/window_tree_host.h"
 #include "ui/base/hit_test.h"
 #include "ui/compositor/test/context_factories_for_test.h"
 #include "ui/events/event.h"
@@ -118,12 +118,12 @@
   aura::Env::CreateInstance();
   scoped_ptr<aura::TestScreen> test_screen(aura::TestScreen::Create());
   gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen.get());
-  scoped_ptr<aura::WindowEventDispatcher> dispatcher(
-      test_screen->CreateRootWindowForPrimaryDisplay());
-  scoped_ptr<DemoWindowTreeClient> window_tree_client(new DemoWindowTreeClient(
-      dispatcher->window()));
+  scoped_ptr<aura::WindowTreeHost> host(
+      test_screen->CreateHostForPrimaryDisplay());
+  scoped_ptr<DemoWindowTreeClient> window_tree_client(
+      new DemoWindowTreeClient(host->window()));
   aura::test::TestFocusClient focus_client;
-  aura::client::SetFocusClient(dispatcher->window(), &focus_client);
+  aura::client::SetFocusClient(host->window(), &focus_client);
 
   // Create a hierarchy of test windows.
   DemoWindowDelegate window_delegate1(SK_ColorBLUE);
@@ -132,8 +132,7 @@
   window1.Init(aura::WINDOW_LAYER_TEXTURED);
   window1.SetBounds(gfx::Rect(100, 100, 400, 400));
   window1.Show();
-  aura::client::ParentWindowWithContext(
-      &window1, dispatcher->window(), gfx::Rect());
+  aura::client::ParentWindowWithContext(&window1, host->window(), gfx::Rect());
 
   DemoWindowDelegate window_delegate2(SK_ColorRED);
   aura::Window window2(&window_delegate2);
@@ -141,8 +140,7 @@
   window2.Init(aura::WINDOW_LAYER_TEXTURED);
   window2.SetBounds(gfx::Rect(200, 200, 350, 350));
   window2.Show();
-  aura::client::ParentWindowWithContext(
-      &window2, dispatcher->window(), gfx::Rect());
+  aura::client::ParentWindowWithContext(&window2, host->window(), gfx::Rect());
 
   DemoWindowDelegate window_delegate3(SK_ColorGREEN);
   aura::Window window3(&window_delegate3);
@@ -152,7 +150,7 @@
   window3.Show();
   window2.AddChild(&window3);
 
-  dispatcher->host()->Show();
+  host->Show();
   base::MessageLoopForUI::current()->Run();
 
   return 0;
diff --git a/ui/aura/remote_window_tree_host_win.cc b/ui/aura/remote_window_tree_host_win.cc
index 1eae586..3fe87b7 100644
--- a/ui/aura/remote_window_tree_host_win.cc
+++ b/ui/aura/remote_window_tree_host_win.cc
@@ -173,6 +173,7 @@
 
 RemoteWindowTreeHostWin::~RemoteWindowTreeHostWin() {
   DestroyCompositor();
+  DestroyDispatcher();
   g_instance = NULL;
 }
 
diff --git a/ui/aura/test/aura_test_helper.cc b/ui/aura/test/aura_test_helper.cc
index 70f3025c..02d36e44 100644
--- a/ui/aura/test/aura_test_helper.cc
+++ b/ui/aura/test/aura_test_helper.cc
@@ -35,7 +35,7 @@
 AuraTestHelper::AuraTestHelper(base::MessageLoopForUI* message_loop)
     : setup_called_(false),
       teardown_called_(false),
-      owns_dispatcher_(false) {
+      owns_host_(false) {
   DCHECK(message_loop);
   message_loop_ = message_loop;
   // Disable animations during tests.
@@ -66,7 +66,7 @@
 
   test_screen_.reset(TestScreen::Create());
   gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen_.get());
-  dispatcher_.reset(test_screen_->CreateRootWindowForPrimaryDisplay());
+  host_.reset(test_screen_->CreateHostForPrimaryDisplay());
 
   focus_client_.reset(new TestFocusClient);
   client::SetFocusClient(root_window(), focus_client_.get());
@@ -92,7 +92,7 @@
   capture_client_.reset();
   focus_client_.reset();
   client::SetFocusClient(root_window(), NULL);
-  dispatcher_.reset();
+  host_.reset();
   ui::GestureRecognizer::Reset();
   test_screen_.reset();
   gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, NULL);
diff --git a/ui/aura/test/aura_test_helper.h b/ui/aura/test/aura_test_helper.h
index 6c014db..c472db8 100644
--- a/ui/aura/test/aura_test_helper.h
+++ b/ui/aura/test/aura_test_helper.h
@@ -46,8 +46,9 @@
   // Flushes message loop.
   void RunAllPendingInMessageLoop();
 
-  Window* root_window() { return dispatcher_->window(); }
-  WindowEventDispatcher* dispatcher() { return dispatcher_.get(); }
+  Window* root_window() { return host_->window(); }
+  WindowEventDispatcher* dispatcher() { return host_->dispatcher(); }
+  WindowTreeHost* host() { return host_.get(); }
 
   TestScreen* test_screen() { return test_screen_.get(); }
 
@@ -55,8 +56,8 @@
   base::MessageLoopForUI* message_loop_;
   bool setup_called_;
   bool teardown_called_;
-  bool owns_dispatcher_;
-  scoped_ptr<WindowEventDispatcher> dispatcher_;
+  bool owns_host_;
+  scoped_ptr<WindowTreeHost> host_;
   scoped_ptr<TestWindowTreeClient> stacking_client_;
   scoped_ptr<client::DefaultActivationClient> activation_client_;
   scoped_ptr<client::DefaultCaptureClient> capture_client_;
diff --git a/ui/aura/test/test_screen.cc b/ui/aura/test/test_screen.cc
index 26a2eeb..2fced68 100644
--- a/ui/aura/test/test_screen.cc
+++ b/ui/aura/test/test_screen.cc
@@ -31,27 +31,24 @@
 TestScreen::~TestScreen() {
 }
 
-WindowEventDispatcher* TestScreen::CreateRootWindowForPrimaryDisplay() {
-  DCHECK(!dispatcher_);
-  dispatcher_ = new WindowEventDispatcher(
-      WindowEventDispatcher::CreateParams(
-          gfx::Rect(display_.GetSizeInPixel())));
-  dispatcher_->window()->AddObserver(this);
-  dispatcher_->host()->InitHost();
-  return dispatcher_;
+WindowTreeHost* TestScreen::CreateHostForPrimaryDisplay() {
+  DCHECK(!host_);
+  host_ = WindowTreeHost::Create(gfx::Rect(display_.GetSizeInPixel()));
+  host_->window()->AddObserver(this);
+  host_->InitHost();
+  return host_;
 }
 
 void TestScreen::SetDeviceScaleFactor(float device_scale_factor) {
   gfx::Rect bounds_in_pixel(display_.GetSizeInPixel());
   display_.SetScaleAndBounds(device_scale_factor, bounds_in_pixel);
-  dispatcher_->host()->NotifyHostResized(bounds_in_pixel.size());
+  host_->NotifyHostResized(bounds_in_pixel.size());
 }
 
 void TestScreen::SetDisplayRotation(gfx::Display::Rotation rotation) {
   display_.set_rotation(rotation);
   // TODO(oshima|mukai): Update the display_ as well.
-  dispatcher_->host()->SetTransform(
-      GetRotationTransform() * GetUIScaleTransform());
+  host_->SetTransform(GetRotationTransform() * GetUIScaleTransform());
 }
 
 void TestScreen::SetUIScale(float ui_scale) {
@@ -60,8 +57,7 @@
   gfx::Rect new_bounds = gfx::ToNearestRect(
       gfx::ScaleRect(bounds_in_pixel, 1.0f / ui_scale));
   display_.SetScaleAndBounds(display_.device_scale_factor(), new_bounds);
-  dispatcher_->host()->SetTransform(
-      GetRotationTransform() * GetUIScaleTransform());
+  host_->SetTransform(GetRotationTransform() * GetUIScaleTransform());
 }
 
 gfx::Transform TestScreen::GetRotationTransform() const {
@@ -100,14 +96,14 @@
 
 void TestScreen::OnWindowBoundsChanged(
     Window* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) {
-  DCHECK_EQ(dispatcher_->window(), window);
+  DCHECK_EQ(host_->window(), window);
   display_.SetSize(gfx::ToFlooredSize(
       gfx::ScaleSize(new_bounds.size(), display_.device_scale_factor())));
 }
 
 void TestScreen::OnWindowDestroying(Window* window) {
-  if (dispatcher_->window() == window)
-    dispatcher_ = NULL;
+  if (host_->window() == window)
+    host_ = NULL;
 }
 
 gfx::Point TestScreen::GetCursorScreenPoint() {
@@ -119,7 +115,7 @@
 }
 
 gfx::NativeWindow TestScreen::GetWindowAtScreenPoint(const gfx::Point& point) {
-  return dispatcher_->window()->GetTopWindowContainingPoint(point);
+  return host_->window()->GetTopWindowContainingPoint(point);
 }
 
 int TestScreen::GetNumDisplays() const {
@@ -154,7 +150,7 @@
 }
 
 TestScreen::TestScreen(const gfx::Rect& screen_bounds)
-    : dispatcher_(NULL),
+    : host_(NULL),
       ui_scale_(1.0f) {
   static int64 synthesized_display_id = 2000;
   display_.set_id(synthesized_display_id++);
diff --git a/ui/aura/test/test_screen.h b/ui/aura/test/test_screen.h
index c344d3c..28351d20d 100644
--- a/ui/aura/test/test_screen.h
+++ b/ui/aura/test/test_screen.h
@@ -17,7 +17,7 @@
 
 namespace aura {
 class Window;
-class WindowEventDispatcher;
+class WindowTreeHost;
 
 // A minimal, testing Aura implementation of gfx::Screen.
 class TestScreen : public gfx::Screen,
@@ -28,9 +28,7 @@
   static TestScreen* CreateFullscreen();
   virtual ~TestScreen();
 
-  // TODO(beng): Rename to CreateHostForPrimaryDisplay() and make it return
-  //             a WTH.
-  WindowEventDispatcher* CreateRootWindowForPrimaryDisplay();
+  WindowTreeHost* CreateHostForPrimaryDisplay();
 
   void SetDeviceScaleFactor(float device_scale_fator);
   void SetDisplayRotation(gfx::Display::Rotation rotation);
@@ -67,7 +65,7 @@
  private:
   explicit TestScreen(const gfx::Rect& screen_bounds);
 
-  aura::WindowEventDispatcher* dispatcher_;
+  aura::WindowTreeHost* host_;
 
   gfx::Display display_;
 
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc
index 364ba2f..729def8b 100644
--- a/ui/aura/window_event_dispatcher.cc
+++ b/ui/aura/window_event_dispatcher.cc
@@ -70,14 +70,6 @@
   }
 }
 
-WindowTreeHost* CreateHost(WindowEventDispatcher* dispatcher,
-                           const WindowEventDispatcher::CreateParams& params) {
-  WindowTreeHost* host = params.host ?
-      params.host : WindowTreeHost::Create(params.initial_bounds);
-  host->set_delegate(dispatcher);
-  return host;
-}
-
 bool IsEventCandidateForHold(const ui::Event& event) {
   if (event.type() == ui::ET_TOUCH_MOVED)
     return true;
@@ -90,18 +82,12 @@
 
 }  // namespace
 
-WindowEventDispatcher::CreateParams::CreateParams(
-    const gfx::Rect& a_initial_bounds)
-    : initial_bounds(a_initial_bounds),
-      host(NULL) {
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // WindowEventDispatcher, public:
 
-WindowEventDispatcher::WindowEventDispatcher(const CreateParams& params)
+WindowEventDispatcher::WindowEventDispatcher(WindowTreeHost* host)
     : window_(new Window(NULL)),
-      host_(CreateHost(this, params)),
+      host_(host),
       touch_ids_down_(0),
       mouse_pressed_handler_(NULL),
       mouse_moved_handler_(NULL),
@@ -112,6 +98,7 @@
       dispatching_held_event_(false),
       repost_event_factory_(this),
       held_event_factory_(this) {
+  window()->Init(WINDOW_LAYER_NOT_DRAWN);
   window()->set_dispatcher(this);
   window()->SetName("RootWindow");
   window()->SetEventTargeter(
@@ -137,11 +124,6 @@
   // as GetRootWindow()) result in Window's implementation. By destroying here
   // we ensure GetRootWindow() still returns this.
   window()->RemoveOrDestroyChildren();
-
-  // Destroying/removing child windows may try to access |host_| (eg.
-  // GetAcceleratedWidget())
-  host_.reset(NULL);
-
   window()->set_dispatcher(NULL);
 }
 
diff --git a/ui/aura/window_event_dispatcher.h b/ui/aura/window_event_dispatcher.h
index 9b46581d..94ecd77 100644
--- a/ui/aura/window_event_dispatcher.h
+++ b/ui/aura/window_event_dispatcher.h
@@ -45,7 +45,6 @@
 }
 
 namespace aura {
-class WindowTreeHost;
 class RootWindowObserver;
 class TestScreen;
 class WindowTargeter;
@@ -57,19 +56,7 @@
                                           public client::CaptureDelegate,
                                           public WindowTreeHostDelegate {
  public:
-  struct AURA_EXPORT CreateParams {
-    // CreateParams with initial_bounds and default host in pixel.
-    explicit CreateParams(const gfx::Rect& initial_bounds);
-    ~CreateParams() {}
-
-    gfx::Rect initial_bounds;
-
-    // A host to use in place of the default one that RootWindow will create.
-    // NULL by default.
-    WindowTreeHost* host;
-  };
-
-  explicit WindowEventDispatcher(const CreateParams& params);
+  explicit WindowEventDispatcher(WindowTreeHost* host);
   virtual ~WindowEventDispatcher();
 
   // Returns the WindowTreeHost for the specified accelerated widget, or NULL
@@ -86,7 +73,7 @@
     return const_cast<WindowTreeHost*>(
         const_cast<const WindowEventDispatcher*>(this)->host());
   }
-  const WindowTreeHost* host() const { return host_.get(); }
+  const WindowTreeHost* host() const { return host_; }
   Window* mouse_pressed_handler() { return mouse_pressed_handler_; }
   Window* mouse_moved_handler() { return mouse_moved_handler_; }
 
@@ -284,10 +271,10 @@
   void PreDispatchMouseEvent(Window* target, ui::MouseEvent* event);
   void PreDispatchTouchEvent(Window* target, ui::TouchEvent* event);
 
-  // TODO(beng): evaluate the ideal ownership model.
+  // TODO(beng): should be owned by WindowTreeHost.
   scoped_ptr<Window> window_;
 
-  scoped_ptr<WindowTreeHost> host_;
+  WindowTreeHost* host_;
 
   // Touch ids that are currently down.
   uint32 touch_ids_down_;
diff --git a/ui/aura/window_event_dispatcher_unittest.cc b/ui/aura/window_event_dispatcher_unittest.cc
index c658d4c7..87e6193 100644
--- a/ui/aura/window_event_dispatcher_unittest.cc
+++ b/ui/aura/window_event_dispatcher_unittest.cc
@@ -1321,12 +1321,11 @@
   ValidRootDuringDestructionWindowObserver observer(&got_destroying,
                                                     &has_valid_root);
   {
-    scoped_ptr<WindowEventDispatcher> dispatcher(
-        new WindowEventDispatcher(
-            WindowEventDispatcher::CreateParams(gfx::Rect(0, 0, 100, 100))));
-    dispatcher->host()->InitHost();
+    scoped_ptr<WindowTreeHost> host(
+        WindowTreeHost::Create(gfx::Rect(0, 0, 100, 100)));
+    host->InitHost();
     // Owned by WindowEventDispatcher.
-    Window* w1 = CreateNormalWindow(1, dispatcher->window(), NULL);
+    Window* w1 = CreateNormalWindow(1, host->window(), NULL);
     w1->AddObserver(&observer);
   }
   EXPECT_TRUE(got_destroying);
@@ -1392,17 +1391,16 @@
 
 namespace {
 
-// See description above DeleteDispatcherFromHeldMouseEvent for details.
-class DeleteDispatcherFromHeldMouseEventDelegate
+// See description above DeleteHostFromHeldMouseEvent for details.
+class DeleteHostFromHeldMouseEventDelegate
     : public test::TestWindowDelegate {
  public:
-  explicit DeleteDispatcherFromHeldMouseEventDelegate(
-      WindowEventDispatcher* dispatcher)
-      : dispatcher_(dispatcher),
+  explicit DeleteHostFromHeldMouseEventDelegate(WindowTreeHost* host)
+      : host_(host),
         got_mouse_event_(false),
         got_destroy_(false) {
   }
-  virtual ~DeleteDispatcherFromHeldMouseEventDelegate() {}
+  virtual ~DeleteHostFromHeldMouseEventDelegate() {}
 
   bool got_mouse_event() const { return got_mouse_event_; }
   bool got_destroy() const { return got_destroy_; }
@@ -1411,7 +1409,7 @@
   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
     if ((event->flags() & ui::EF_SHIFT_DOWN) != 0) {
       got_mouse_event_ = true;
-      delete dispatcher_;
+      delete host_;
     }
   }
   virtual void OnWindowDestroyed(Window* window) OVERRIDE {
@@ -1419,37 +1417,36 @@
   }
 
  private:
-  WindowEventDispatcher* dispatcher_;
+  WindowTreeHost* host_;
   bool got_mouse_event_;
   bool got_destroy_;
 
-  DISALLOW_COPY_AND_ASSIGN(DeleteDispatcherFromHeldMouseEventDelegate);
+  DISALLOW_COPY_AND_ASSIGN(DeleteHostFromHeldMouseEventDelegate);
 };
 
 }  // namespace
 
 #if defined(USE_OZONE)
 // Creating multiple WindowTreeHostOzone instances is broken.
-#define MAYBE_DeleteDispatcherFromHeldMouseEvent DISABLED_DeleteDispatcherFromHeldMouseEvent
+#define MAYBE_DeleteHostFromHeldMouseEvent DISABLED_DeleteHostFromHeldMouseEvent
 #else
-#define MAYBE_DeleteDispatcherFromHeldMouseEvent DeleteDispatcherFromHeldMouseEvent
+#define MAYBE_DeleteHostFromHeldMouseEvent DeleteHostFromHeldMouseEvent
 #endif
 
-// Verifies if a RootWindow is deleted from dispatching a held mouse event we
-// don't crash.
-TEST_F(WindowEventDispatcherTest, MAYBE_DeleteDispatcherFromHeldMouseEvent) {
+// Verifies if a WindowTreeHost is deleted from dispatching a held mouse event
+// we don't crash.
+TEST_F(WindowEventDispatcherTest, MAYBE_DeleteHostFromHeldMouseEvent) {
   // Should be deleted by |delegate|.
-  WindowEventDispatcher* d2 = new WindowEventDispatcher(
-      WindowEventDispatcher::CreateParams(gfx::Rect(0, 0, 100, 100)));
-  d2->host()->InitHost();
-  DeleteDispatcherFromHeldMouseEventDelegate delegate(d2);
-  // Owned by |d2|.
-  Window* w1 = CreateNormalWindow(1, d2->window(), &delegate);
+  WindowTreeHost* h2 = WindowTreeHost::Create(gfx::Rect(0, 0, 100, 100));
+  h2->InitHost();
+  DeleteHostFromHeldMouseEventDelegate delegate(h2);
+  // Owned by |h2|.
+  Window* w1 = CreateNormalWindow(1, h2->window(), &delegate);
   w1->SetBounds(gfx::Rect(0, 0, 40, 40));
   ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED,
                          gfx::Point(10, 10), gfx::Point(10, 10),
                          ui::EF_SHIFT_DOWN, 0);
-  d2->RepostEvent(pressed);
+  h2->dispatcher()->RepostEvent(pressed);
   // RunAllPendingInMessageLoop() to make sure the |pressed| is run.
   RunAllPendingInMessageLoop();
   EXPECT_TRUE(delegate.got_mouse_event());
diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc
index 4b8b69c..fd3d217 100644
--- a/ui/aura/window_tree_host.cc
+++ b/ui/aura/window_tree_host.cc
@@ -78,7 +78,6 @@
 }
 
 void WindowTreeHost::InitHost() {
-  window()->Init(aura::WINDOW_LAYER_NOT_DRAWN);
   InitCompositor();
   UpdateRootWindowSize(GetBounds().size());
   Env::GetInstance()->NotifyRootWindowInitialized(delegate_->AsDispatcher());
@@ -210,10 +209,19 @@
   compositor_.reset();
 }
 
+void WindowTreeHost::DestroyDispatcher() {
+  dispatcher_.reset();
+}
+
 void WindowTreeHost::CreateCompositor(
     gfx::AcceleratedWidget accelerated_widget) {
   compositor_.reset(new ui::Compositor(GetAcceleratedWidget()));
   DCHECK(compositor_.get());
+  // TODO(beng): I think this setup should probably all move to a "accelerated
+  // widget available" function.
+  if (!dispatcher())
+    dispatcher_.reset(new WindowEventDispatcher(this));
+  delegate_ = dispatcher();
 }
 
 void WindowTreeHost::NotifyHostResized(const gfx::Size& new_size) {
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h
index 6567672f..6418791 100644
--- a/ui/aura/window_tree_host.h
+++ b/ui/aura/window_tree_host.h
@@ -45,8 +45,14 @@
   void InitCompositor();
 
   // TODO(beng): these will become trivial accessors in a future CL.
-  aura::Window* window();
-  const aura::Window* window() const;
+  Window* window();
+  const Window* window() const;
+
+  WindowEventDispatcher* dispatcher() {
+    return const_cast<WindowEventDispatcher*>(
+        const_cast<const WindowTreeHost*>(this)->dispatcher());
+  }
+  const WindowEventDispatcher* dispatcher() const { return dispatcher_.get(); }
 
   ui::Compositor* compositor() { return compositor_.get(); }
 
@@ -161,6 +167,7 @@
 
   WindowTreeHost();
   void DestroyCompositor();
+  void DestroyDispatcher();
 
   void CreateCompositor(gfx::AcceleratedWidget accelerated_widget);
 
@@ -186,6 +193,8 @@
   void MoveCursorToInternal(const gfx::Point& root_location,
                             const gfx::Point& host_location);
 
+  scoped_ptr<WindowEventDispatcher> dispatcher_;
+
   scoped_ptr<ui::Compositor> compositor_;
 
   scoped_ptr<RootWindowTransformer> transformer_;
diff --git a/ui/aura/window_tree_host_mac.mm b/ui/aura/window_tree_host_mac.mm
index 82ea978..b814f038 100644
--- a/ui/aura/window_tree_host_mac.mm
+++ b/ui/aura/window_tree_host_mac.mm
@@ -21,6 +21,7 @@
 }
 
 WindowTreeHostMac::~WindowTreeHostMac() {
+  DestroyDispatcher();
 }
 
 gfx::AcceleratedWidget WindowTreeHostMac::GetAcceleratedWidget() {
diff --git a/ui/aura/window_tree_host_ozone.cc b/ui/aura/window_tree_host_ozone.cc
index 6e9c831..a2c6f3b 100644
--- a/ui/aura/window_tree_host_ozone.cc
+++ b/ui/aura/window_tree_host_ozone.cc
@@ -34,6 +34,7 @@
 WindowTreeHostOzone::~WindowTreeHostOzone() {
   base::MessagePumpOzone::Current()->RemoveDispatcherForRootWindow(0);
   DestroyCompositor();
+  DestroyDispatcher();
 }
 
 uint32_t WindowTreeHostOzone::Dispatch(const base::NativeEvent& ne) {
diff --git a/ui/aura/window_tree_host_win.cc b/ui/aura/window_tree_host_win.cc
index 9187e04..2d592e5 100644
--- a/ui/aura/window_tree_host_win.cc
+++ b/ui/aura/window_tree_host_win.cc
@@ -53,6 +53,7 @@
 
 WindowTreeHostWin::~WindowTreeHostWin() {
   DestroyCompositor();
+  DestroyDispatcher();
   DestroyWindow(hwnd());
 }
 
diff --git a/ui/aura/window_tree_host_x11.cc b/ui/aura/window_tree_host_x11.cc
index 1421542..5f0c6ac 100644
--- a/ui/aura/window_tree_host_x11.cc
+++ b/ui/aura/window_tree_host_x11.cc
@@ -348,6 +348,7 @@
   UnConfineCursor();
 
   DestroyCompositor();
+  DestroyDispatcher();
   XDestroyWindow(xdisplay_, xwindow_);
 }
 
diff --git a/ui/views/corewm/capture_controller_unittest.cc b/ui/views/corewm/capture_controller_unittest.cc
index a470986..cf622d4 100644
--- a/ui/views/corewm/capture_controller_unittest.cc
+++ b/ui/views/corewm/capture_controller_unittest.cc
@@ -34,13 +34,12 @@
     AuraTestBase::SetUp();
     capture_controller_.reset(new corewm::ScopedCaptureClient(root_window()));
 
-    second_root_.reset(new aura::WindowEventDispatcher(
-        aura::WindowEventDispatcher::CreateParams(gfx::Rect(0, 0, 800, 600))));
-    second_root_->host()->InitHost();
-    second_root_->window()->Show();
-    second_root_->host()->SetBounds(gfx::Rect(800, 600));
+    second_host_.reset(aura::WindowTreeHost::Create(gfx::Rect(0, 0, 800, 600)));
+    second_host_->InitHost();
+    second_host_->window()->Show();
+    second_host_->SetBounds(gfx::Rect(800, 600));
     second_capture_controller_.reset(
-        new corewm::ScopedCaptureClient(second_root_->window()));
+        new corewm::ScopedCaptureClient(second_host_->window()));
 
 #if !defined(OS_CHROMEOS)
     desktop_position_client_.reset(new DesktopScreenPositionClient());
@@ -49,7 +48,7 @@
 
     second_desktop_position_client_.reset(new DesktopScreenPositionClient());
     aura::client::SetScreenPositionClient(
-        second_root_->window(),
+        second_host_->window(),
         second_desktop_position_client_.get());
 #endif
   }
@@ -63,7 +62,7 @@
     second_capture_controller_.reset();
 
     // Kill any active compositors before we hit the compositor shutdown paths.
-    second_root_.reset();
+    second_host_.reset();
 
 #if !defined(OS_CHROMEOS)
     desktop_position_client_.reset();
@@ -82,7 +81,7 @@
   }
 
   scoped_ptr<corewm::ScopedCaptureClient> capture_controller_;
-  scoped_ptr<aura::WindowEventDispatcher> second_root_;
+  scoped_ptr<aura::WindowTreeHost> second_host_;
   scoped_ptr<corewm::ScopedCaptureClient> second_capture_controller_;
 #if !defined(OS_CHROMEOS)
   scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client_;
@@ -108,7 +107,7 @@
 
   // Build a window in the second WindowEventDispatcher.
   scoped_ptr<aura::Window> w2(
-      CreateNormalWindow(2, second_root_->window(), NULL));
+      CreateNormalWindow(2, second_host_->window(), NULL));
 
   // The act of having the second window take capture should clear out mouse
   // pressed handler in the first WindowEventDispatcher.
@@ -130,7 +129,7 @@
   // Build a window in the second WindowEventDispatcher and give it capture.
   // Both capture clients should return the same capture window.
   scoped_ptr<aura::Window> w2(
-      CreateNormalWindow(2, second_root_->window(), NULL));
+      CreateNormalWindow(2, second_host_->window(), NULL));
   w2->SetCapture();
   EXPECT_EQ(w2.get(), GetCaptureWindow());
   EXPECT_EQ(w2.get(), GetSecondCaptureWindow());
@@ -151,7 +150,7 @@
   // Build a window in the second WindowEventDispatcher and give it capture.
   // Both capture clients should return the same capture window.
   scoped_ptr<aura::Window> w2(
-      CreateNormalWindow(2, second_root_->window(), NULL));
+      CreateNormalWindow(2, second_host_->window(), NULL));
   w2->SetCapture();
   EXPECT_EQ(w2.get(), GetCaptureWindow());
   EXPECT_EQ(w2.get(), GetSecondCaptureWindow());
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index ed62e48..d373a0cd 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -218,6 +218,25 @@
   DISALLOW_COPY_AND_ASSIGN(FocusManagerEventHandler);
 };
 
+class RootWindowDestructionObserver : public aura::WindowObserver {
+ public:
+  explicit RootWindowDestructionObserver(DesktopNativeWidgetAura* parent)
+    : parent_(parent) {}
+  virtual ~RootWindowDestructionObserver() {}
+
+ private:
+  // Overridden from aura::WindowObserver:
+  virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {
+    parent_->RootWindowDestroyed();
+    window->RemoveObserver(this);
+    delete this;
+  }
+
+  DesktopNativeWidgetAura* parent_;
+
+  DISALLOW_COPY_AND_ASSIGN(RootWindowDestructionObserver);
+};
+
 ////////////////////////////////////////////////////////////////////////////////
 // DesktopNativeWidgetAura, public:
 
@@ -228,10 +247,10 @@
 
 DesktopNativeWidgetAura::DesktopNativeWidgetAura(
     internal::NativeWidgetDelegate* delegate)
-    : ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
+    : desktop_window_tree_host_(NULL),
+      ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
       close_widget_factory_(this),
       can_activate_(true),
-      desktop_window_tree_host_(NULL),
       content_window_container_(NULL),
       content_window_(new aura::Window(this)),
       native_widget_delegate_(delegate),
@@ -269,7 +288,7 @@
   // WindowEventDispatcher are left referencing a deleted Window.
   {
     aura::Window* capture_window = capture_client_->GetCaptureWindow();
-    if (capture_window && dispatcher_->window()->Contains(capture_window))
+    if (capture_window && host_->window()->Contains(capture_window))
       capture_window->ReleaseCapture();
   }
 
@@ -277,27 +296,27 @@
   // references. Make sure we destroy ShadowController early on.
   shadow_controller_.reset();
   tooltip_manager_.reset();
-  dispatcher_->window()->RemovePreTargetHandler(tooltip_controller_.get());
-  aura::client::SetTooltipClient(dispatcher_->window(), NULL);
+  host_->window()->RemovePreTargetHandler(tooltip_controller_.get());
+  aura::client::SetTooltipClient(host_->window(), NULL);
   tooltip_controller_.reset();
 
   root_window_event_filter_->RemoveHandler(input_method_event_filter_.get());
 
-  window_tree_client_.reset();  // Uses dispatcher_ at destruction.
+  window_tree_client_.reset();  // Uses host_->dispatcher() at destruction.
 
-  capture_client_.reset();  // Uses dispatcher_ at destruction.
+  capture_client_.reset();  // Uses host_->dispatcher() at destruction.
 
   // FocusController uses |content_window_|. Destroy it now so that we don't
   // have to worry about the possibility of FocusController attempting to use
   // |content_window_| after it's been destroyed but before all child windows
   // have been destroyed.
-  dispatcher_->window()->RemovePreTargetHandler(focus_client_.get());
-  aura::client::SetFocusClient(dispatcher_->window(), NULL);
-  aura::client::SetActivationClient(dispatcher_->window(), NULL);
+  host_->window()->RemovePreTargetHandler(focus_client_.get());
+  aura::client::SetFocusClient(host_->window(), NULL);
+  aura::client::SetActivationClient(host_->window(), NULL);
   focus_client_.reset();
 
-  dispatcher_->RemoveRootWindowObserver(this);
-  dispatcher_.reset();  // Uses input_method_event_filter_ at destruction.
+  host_->dispatcher()->RemoveRootWindowObserver(this);
+  host_.reset();  // Uses input_method_event_filter_ at destruction.
   // WindowEventDispatcher owns |desktop_window_tree_host_|.
   desktop_window_tree_host_ = NULL;
   content_window_ = NULL;
@@ -314,18 +333,15 @@
   aura::client::SetDispatcherClient(dispatcher->window(), NULL);
   dispatcher_client_.reset();
 
-  aura::client::SetCursorClient(dispatcher->window(), NULL);
+  // We explicitly do NOT clear the cursor client property. Since the cursor
+  // manager is a singleton, it can outlive any window hierarchy, and it's
+  // important that objects attached to this destroying window hierarchy have
+  // an opportunity to deregister their observers from the cursor manager.
+  // They may want to do this when they are notified that they're being
+  // removed from the window hierarchy, which happens soon after this
+  // function when DesktopWindowTreeHost* calls DestroyDispatcher().
   native_cursor_manager_->RemoveRootWindow(dispatcher);
 
-  cursor_reference_count_--;
-  if (cursor_reference_count_ == 0) {
-    // We are the last DesktopNativeWidgetAura instance, and we are responsible
-    // for cleaning up |cursor_manager_|.
-    delete cursor_manager_;
-    native_cursor_manager_ = NULL;
-    cursor_manager_ = NULL;
-  }
-
   aura::client::SetScreenPositionClient(dispatcher->window(), NULL);
   position_client_.reset();
 
@@ -339,7 +355,7 @@
 void DesktopNativeWidgetAura::HandleActivationChanged(bool active) {
   native_widget_delegate_->OnNativeWidgetActivationChanged(active);
   aura::client::ActivationClient* activation_client =
-      aura::client::GetActivationClient(dispatcher_->window());
+      aura::client::GetActivationClient(host_->window());
   if (!activation_client)
     return;
   if (active) {
@@ -395,20 +411,21 @@
   desktop_window_tree_host_ = params.desktop_window_tree_host ?
       params.desktop_window_tree_host :
       DesktopWindowTreeHost::Create(native_widget_delegate_, this);
-  aura::WindowEventDispatcher::CreateParams rw_params(params.bounds);
-  desktop_window_tree_host_->Init(content_window_, params, &rw_params);
+  host_.reset(desktop_window_tree_host_->AsWindowTreeHost());
+  desktop_window_tree_host_->Init(content_window_, params);
 
-  dispatcher_.reset(new aura::WindowEventDispatcher(rw_params));
-  dispatcher_->host()->InitHost();
-  dispatcher_->window()->AddChild(content_window_container_);
-  dispatcher_->window()->SetProperty(kDesktopNativeWidgetAuraKey, this);
+  host_->InitHost();
+  host_->window()->AddChild(content_window_container_);
+  host_->window()->SetProperty(kDesktopNativeWidgetAuraKey, this);
+
+  host_->window()->AddObserver(new RootWindowDestructionObserver(this));
 
   // The WindowsModalityController event filter should be at the head of the
   // pre target handlers list. This ensures that it handles input events first
   // when modal windows are at the top of the Zorder.
   if (widget_type_ == Widget::InitParams::TYPE_WINDOW)
     window_modality_controller_.reset(
-        new views::corewm::WindowModalityController(dispatcher_->window()));
+        new views::corewm::WindowModalityController(host_->window()));
 
   // |root_window_event_filter_| must be created before
   // OnWindowTreeHostCreated() is invoked.
@@ -420,9 +437,9 @@
   // WindowEventDispatcher.
   root_window_event_filter_ = new corewm::CompoundEventFilter;
   // Pass ownership of the filter to the root_window.
-  dispatcher_->window()->SetEventFilter(root_window_event_filter_);
+  host_->window()->SetEventFilter(root_window_event_filter_);
 
-  // |dispatcher_| must be added to |native_cursor_manager_| before
+  // The host's dispatcher must be added to |native_cursor_manager_| before
   // OnRootWindowCreated() is called.
   cursor_reference_count_++;
   if (!native_cursor_manager_) {
@@ -433,46 +450,46 @@
     cursor_manager_ = new views::corewm::CursorManager(
         scoped_ptr<corewm::NativeCursorManager>(native_cursor_manager_));
   }
-  native_cursor_manager_->AddRootWindow(dispatcher_.get());
-  aura::client::SetCursorClient(dispatcher_->window(), cursor_manager_);
+  native_cursor_manager_->AddRootWindow(host_->dispatcher());
+  aura::client::SetCursorClient(host_->window(), cursor_manager_);
 
-  desktop_window_tree_host_->OnRootWindowCreated(dispatcher_.get(), params);
+  desktop_window_tree_host_->OnRootWindowCreated(host_->dispatcher(), params);
 
   UpdateWindowTransparency();
 
-  capture_client_.reset(new DesktopCaptureClient(dispatcher_->window()));
+  capture_client_.reset(new DesktopCaptureClient(host_->window()));
 
   corewm::FocusController* focus_controller =
       new corewm::FocusController(new DesktopFocusRules(content_window_));
   focus_client_.reset(focus_controller);
-  aura::client::SetFocusClient(dispatcher_->window(), focus_controller);
-  aura::client::SetActivationClient(dispatcher_->window(), focus_controller);
-  dispatcher_->window()->AddPreTargetHandler(focus_controller);
+  aura::client::SetFocusClient(host_->window(), focus_controller);
+  aura::client::SetActivationClient(host_->window(), focus_controller);
+  host_->window()->AddPreTargetHandler(focus_controller);
 
   dispatcher_client_.reset(new DesktopDispatcherClient);
-  aura::client::SetDispatcherClient(dispatcher_->window(),
+  aura::client::SetDispatcherClient(host_->window(),
                                     dispatcher_client_.get());
 
   position_client_.reset(new DesktopScreenPositionClient());
-  aura::client::SetScreenPositionClient(dispatcher_->window(),
+  aura::client::SetScreenPositionClient(host_->window(),
                                         position_client_.get());
 
   InstallInputMethodEventFilter();
 
   drag_drop_client_ = desktop_window_tree_host_->CreateDragDropClient(
       native_cursor_manager_);
-  aura::client::SetDragDropClient(dispatcher_->window(),
+  aura::client::SetDragDropClient(host_->window(),
                                   drag_drop_client_.get());
 
   static_cast<aura::client::FocusClient*>(focus_client_.get())->
       FocusWindow(content_window_);
 
-  OnWindowTreeHostResized(dispatcher_.get());
+  OnWindowTreeHostResized(host_->dispatcher());
 
-  dispatcher_->AddRootWindowObserver(this);
+  host_->dispatcher()->AddRootWindowObserver(this);
 
   window_tree_client_.reset(
-      new DesktopNativeWidgetAuraWindowTreeClient(dispatcher_->window()));
+      new DesktopNativeWidgetAuraWindowTreeClient(host_->window()));
   drop_helper_.reset(new DropHelper(
       static_cast<internal::RootView*>(GetWidget()->GetRootView())));
   aura::client::SetDragDropDelegate(content_window_, this);
@@ -482,36 +499,33 @@
   tooltip_controller_.reset(
       new corewm::TooltipController(
           desktop_window_tree_host_->CreateTooltip()));
-  aura::client::SetTooltipClient(dispatcher_->window(),
+  aura::client::SetTooltipClient(host_->window(),
                                  tooltip_controller_.get());
-  dispatcher_->window()->AddPreTargetHandler(tooltip_controller_.get());
+  host_->window()->AddPreTargetHandler(tooltip_controller_.get());
 
   if (params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW) {
     visibility_controller_.reset(new views::corewm::VisibilityController);
-    aura::client::SetVisibilityClient(dispatcher_->window(),
+    aura::client::SetVisibilityClient(host_->window(),
                                       visibility_controller_.get());
-    views::corewm::SetChildWindowVisibilityChangesAnimated(
-        dispatcher_->window());
+    views::corewm::SetChildWindowVisibilityChangesAnimated(host_->window());
     views::corewm::SetChildWindowVisibilityChangesAnimated(
         content_window_container_);
   }
 
   if (params.type == Widget::InitParams::TYPE_WINDOW) {
     focus_manager_event_handler_.reset(new FocusManagerEventHandler(this));
-    dispatcher_->window()->AddPreTargetHandler(
-        focus_manager_event_handler_.get());
+    host_->window()->AddPreTargetHandler(focus_manager_event_handler_.get());
   }
 
   event_client_.reset(new DesktopEventClient);
-  aura::client::SetEventClient(dispatcher_->window(), event_client_.get());
+  aura::client::SetEventClient(host_->window(), event_client_.get());
 
   aura::client::GetFocusClient(content_window_)->FocusWindow(content_window_);
 
   aura::client::SetActivationDelegate(content_window_, this);
 
-  shadow_controller_.reset(
-      new corewm::ShadowController(
-          aura::client::GetActivationClient(dispatcher_->window())));
+  shadow_controller_.reset(new corewm::ShadowController(
+      aura::client::GetActivationClient(host_->window())));
 
   content_window_->SetProperty(aura::client::kCanMaximizeKey,
                                GetWidget()->widget_delegate()->CanMaximize());
@@ -677,7 +691,7 @@
   // We could probably get rid of this and similar logic from
   // the DesktopNativeWidgetAura::OnWindowTreeHostResized function.
   float scale = 1;
-  aura::Window* root = dispatcher_->window();
+  aura::Window* root = host_->window();
   if (root) {
     scale = gfx::Screen::GetScreenFor(root)->
         GetDisplayNearestWindow(root).device_scale_factor();
@@ -847,7 +861,7 @@
 void DesktopNativeWidgetAura::SetCursor(gfx::NativeCursor cursor) {
   cursor_ = cursor;
   aura::client::CursorClient* cursor_client =
-      aura::client::GetCursorClient(dispatcher_->window());
+      aura::client::GetCursorClient(host_->window());
   if (cursor_client)
     cursor_client->SetCursor(cursor);
 }
@@ -856,7 +870,7 @@
   if (!content_window_)
     return false;
   aura::client::CursorClient* cursor_client =
-      aura::client::GetCursorClient(dispatcher_->window());
+      aura::client::GetCursorClient(host_->window());
   return cursor_client ? cursor_client->IsMouseEventsEnabled() : true;
 }
 
@@ -1161,9 +1175,9 @@
   DCHECK(!input_method_event_filter_.get());
 
   input_method_event_filter_.reset(new corewm::InputMethodEventFilter(
-      dispatcher_->host()->GetAcceleratedWidget()));
+      host_->GetAcceleratedWidget()));
   input_method_event_filter_->SetInputMethodPropertyInRootWindow(
-      dispatcher_->window());
+      host_->window());
   root_window_event_filter_->AddHandler(input_method_event_filter_.get());
 }
 
@@ -1172,4 +1186,15 @@
       desktop_window_tree_host_->ShouldWindowContentsBeTransparent());
 }
 
+void DesktopNativeWidgetAura::RootWindowDestroyed() {
+  cursor_reference_count_--;
+  if (cursor_reference_count_ == 0) {
+    // We are the last DesktopNativeWidgetAura instance, and we are responsible
+    // for cleaning up |cursor_manager_|.
+    delete cursor_manager_;
+    native_cursor_manager_ = NULL;
+    cursor_manager_ = NULL;
+  }
+}
+
 }  // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
index c7ecbef..ba8262ef 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -17,7 +17,7 @@
 #include "ui/views/widget/native_widget_private.h"
 
 namespace aura {
-class RootWindow;
+class WindowTreeHost;
 namespace client {
 class DragDropClient;
 class FocusClient;
@@ -70,6 +70,8 @@
   // this is the signal that we should start our shutdown.
   virtual void OnHostClosed();
 
+  // TODO(beng): remove this method and replace with an implementation of
+  //             WindowDestroying() that takes the window being destroyed.
   // Called from ~DesktopWindowTreeHost. This takes the WindowEventDispatcher
   // as by the time we get here |dispatcher_| is NULL.
   virtual void OnDesktopWindowTreeHostDestroyed(
@@ -81,8 +83,8 @@
   corewm::CompoundEventFilter* root_window_event_filter() {
     return root_window_event_filter_;
   }
-  aura::WindowEventDispatcher* dispatcher() {
-    return dispatcher_.get();
+  aura::WindowTreeHost* host() {
+    return host_.get();
   }
 
   // Overridden from NativeWidget:
@@ -237,6 +239,7 @@
 
  private:
   friend class FocusManagerEventHandler;
+  friend class RootWindowDestructionObserver;
 
   // Installs the input method filter.
   void InstallInputMethodEventFilter();
@@ -245,16 +248,16 @@
   // window is only set as transparent when the glass frame is in use.
   void UpdateWindowTransparency();
 
+  void RootWindowDestroyed();
+
+  scoped_ptr<aura::WindowTreeHost> host_;
+  DesktopWindowTreeHost* desktop_window_tree_host_;
+
   // See class documentation for Widget in widget.h for a note about ownership.
   Widget::InitParams::Ownership ownership_;
 
   scoped_ptr<DesktopCaptureClient> capture_client_;
 
-  // The NativeWidget owns the WindowEventDispatcher. Required because the
-  // WindowEventDispatcher owns its WindowTreeHost, so DesktopWindowTreeHost
-  // can't own it.
-  scoped_ptr<aura::WindowEventDispatcher> dispatcher_;
-
   // The following factory is used for calls to close the NativeWidgetAura
   // instance.
   base::WeakPtrFactory<DesktopNativeWidgetAura> close_widget_factory_;
@@ -262,9 +265,6 @@
   // Can we be made active?
   bool can_activate_;
 
-  // Ownership passed to RootWindow on Init.
-  DesktopWindowTreeHost* desktop_window_tree_host_;
-
   // Child of the root, contains |content_window_|.
   aura::Window* content_window_container_;
 
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
index 3d956358..6d15e2a 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
@@ -91,9 +91,9 @@
   widget_b.Init(init_params_b);
 
   aura::client::CursorClient* cursor_client_a = aura::client::GetCursorClient(
-      desktop_native_widget_aura_a->dispatcher()->window());
+      desktop_native_widget_aura_a->host()->window());
   aura::client::CursorClient* cursor_client_b = aura::client::GetCursorClient(
-      desktop_native_widget_aura_b->dispatcher()->window());
+      desktop_native_widget_aura_b->host()->window());
 
   // Verify the cursor can be locked using one client and unlocked using
   // another.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host.h b/ui/views/widget/desktop_aura/desktop_window_tree_host.h
index dea1df1..8bd1d923 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host.h
@@ -54,10 +54,8 @@
   static ui::NativeTheme* GetNativeTheme(aura::Window* window);
 
   // Sets up resources needed before the WindowEventDispatcher has been created.
-  virtual void Init(
-      aura::Window* content_window,
-      const Widget::InitParams& params,
-      aura::WindowEventDispatcher::CreateParams* rw_create_params) = 0;
+  virtual void Init(aura::Window* content_window,
+                    const Widget::InitParams& params) = 0;
 
   // Invoked once the WindowEventDispatcher has been created. Caller owns the
   // WindowEventDispatcher.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index a644803..02a7e436 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -93,6 +93,7 @@
   // WARNING: |content_window_| has been destroyed by the time we get here.
   desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(
       dispatcher_);
+  DestroyDispatcher();
 }
 
 // static
@@ -122,10 +123,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 // DesktopWindowTreeHostWin, DesktopWindowTreeHost implementation:
 
-void DesktopWindowTreeHostWin::Init(
-    aura::Window* content_window,
-    const Widget::InitParams& params,
-    aura::WindowEventDispatcher::CreateParams* rw_create_params) {
+void DesktopWindowTreeHostWin::Init(aura::Window* content_window,
+                                    const Widget::InitParams& params) {
   // TODO(beng): SetInitParams().
   content_window_ = content_window;
 
@@ -153,8 +152,6 @@
               reinterpret_cast<HANDLE>(true));
   }
   CreateCompositor(GetAcceleratedWidget());
-
-  rw_create_params->host = this;
 }
 
 void DesktopWindowTreeHostWin::OnRootWindowCreated(
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index 4bde34d..8375ae0 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -45,10 +45,8 @@
 
  protected:
   // Overridden from DesktopWindowTreeHost:
-  virtual void Init(
-      aura::Window* content_window,
-      const Widget::InitParams& params,
-      aura::WindowEventDispatcher::CreateParams* rw_create_params) OVERRIDE;
+  virtual void Init(aura::Window* content_window,
+                    const Widget::InitParams& params) OVERRIDE;
   virtual void OnRootWindowCreated(aura::WindowEventDispatcher* dispatcher,
                                    const Widget::InitParams& params) OVERRIDE;
   virtual scoped_ptr<corewm::Tooltip> CreateTooltip() OVERRIDE;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index 3c2423e..5f390c46 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -149,6 +149,7 @@
   desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(dispatcher_);
   if (custom_window_shape_)
     XDestroyRegion(custom_window_shape_);
+  DestroyDispatcher();
 }
 
 // static
@@ -212,10 +213,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 // DesktopWindowTreeHostX11, DesktopWindowTreeHost implementation:
 
-void DesktopWindowTreeHostX11::Init(
-    aura::Window* content_window,
-    const Widget::InitParams& params,
-    aura::WindowEventDispatcher::CreateParams* rw_create_params) {
+void DesktopWindowTreeHostX11::Init(aura::Window* content_window,
+                                    const Widget::InitParams& params) {
   content_window_ = content_window;
 
   // TODO(erg): Check whether we *should* be building a WindowTreeHost here, or
@@ -230,9 +229,6 @@
     sanitized_params.bounds.set_height(100);
 
   InitX11Window(sanitized_params);
-
-  rw_create_params->initial_bounds = bounds_;
-  rw_create_params->host = this;
 }
 
 void DesktopWindowTreeHostX11::OnRootWindowCreated(
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index f10e646..2440b1b 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -68,10 +68,8 @@
 
  protected:
   // Overridden from DesktopWindowTreeHost:
-  virtual void Init(
-      aura::Window* content_window,
-      const Widget::InitParams& params,
-      aura::WindowEventDispatcher::CreateParams* rw_create_params) OVERRIDE;
+  virtual void Init(aura::Window* content_window,
+                    const Widget::InitParams& params) OVERRIDE;
   virtual void OnRootWindowCreated(aura::WindowEventDispatcher* dispatcher,
                                    const Widget::InitParams& params) OVERRIDE;
   virtual scoped_ptr<corewm::Tooltip> CreateTooltip() OVERRIDE;
diff --git a/ui/wm/test/wm_test_helper.cc b/ui/wm/test/wm_test_helper.cc
index 1df8ec0..a1d7c3c 100644
--- a/ui/wm/test/wm_test_helper.cc
+++ b/ui/wm/test/wm_test_helper.cc
@@ -8,7 +8,6 @@
 #include "ui/aura/client/default_capture_client.h"
 #include "ui/aura/env.h"
 #include "ui/aura/test/test_focus_client.h"
-#include "ui/aura/window_event_dispatcher.h"
 #include "ui/views/corewm/compound_event_filter.h"
 #include "ui/views/corewm/input_method_event_filter.h"
 
@@ -16,30 +15,27 @@
 
 WMTestHelper::WMTestHelper(const gfx::Size& default_window_size) {
   aura::Env::CreateInstance();
-  dispatcher_.reset(new aura::WindowEventDispatcher(
-      aura::WindowEventDispatcher::CreateParams(
-          gfx::Rect(default_window_size))));
-  dispatcher_->host()->InitHost();
-  aura::client::SetWindowTreeClient(dispatcher_->window(), this);
+  host_.reset(aura::WindowTreeHost::Create(gfx::Rect(default_window_size)));
+  host_->InitHost();
+  aura::client::SetWindowTreeClient(host_->window(), this);
 
   focus_client_.reset(new aura::test::TestFocusClient);
-  aura::client::SetFocusClient(dispatcher_->window(), focus_client_.get());
+  aura::client::SetFocusClient(host_->window(), focus_client_.get());
 
   root_window_event_filter_ = new views::corewm::CompoundEventFilter;
   // Pass ownership of the filter to the root_window.
-  dispatcher_->window()->SetEventFilter(root_window_event_filter_);
+  host_->window()->SetEventFilter(root_window_event_filter_);
 
   input_method_filter_.reset(new views::corewm::InputMethodEventFilter(
-      dispatcher_->host()->GetAcceleratedWidget()));
-  input_method_filter_->SetInputMethodPropertyInRootWindow(
-      dispatcher_->window());
+      host_->GetAcceleratedWidget()));
+  input_method_filter_->SetInputMethodPropertyInRootWindow(host_->window());
   root_window_event_filter_->AddHandler(input_method_filter_.get());
 
   activation_client_.reset(
-      new aura::client::DefaultActivationClient(dispatcher_->window()));
+      new aura::client::DefaultActivationClient(host_->window()));
 
   capture_client_.reset(
-      new aura::client::DefaultCaptureClient(dispatcher_->window()));
+      new aura::client::DefaultCaptureClient(host_->window()));
 }
 
 WMTestHelper::~WMTestHelper() {
@@ -49,7 +45,7 @@
 aura::Window* WMTestHelper::GetDefaultParent(aura::Window* context,
                                              aura::Window* window,
                                              const gfx::Rect& bounds) {
-  return dispatcher_->window();
+  return host_->window();
 }
 
 }  // namespace wm
diff --git a/ui/wm/test/wm_test_helper.h b/ui/wm/test/wm_test_helper.h
index da2d153..832a557f 100644
--- a/ui/wm/test/wm_test_helper.h
+++ b/ui/wm/test/wm_test_helper.h
@@ -8,10 +8,12 @@
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
 #include "ui/aura/client/window_tree_client.h"
+#include "ui/aura/window_tree_host.h"
 
 namespace aura {
 class Window;
 class WindowEventDispatcher;
+class WindowTreeHost;
 namespace client {
 class DefaultActivationClient;
 class DefaultCaptureClient;
@@ -41,7 +43,7 @@
   explicit WMTestHelper(const gfx::Size& default_window_size);
   virtual ~WMTestHelper();
 
-  aura::WindowEventDispatcher* dispatcher() { return dispatcher_.get(); }
+  aura::WindowEventDispatcher* dispatcher() { return host_->dispatcher(); }
 
   // Overridden from client::WindowTreeClient:
   virtual aura::Window* GetDefaultParent(aura::Window* context,
@@ -49,7 +51,7 @@
                                          const gfx::Rect& bounds) OVERRIDE;
 
  private:
-  scoped_ptr<aura::WindowEventDispatcher> dispatcher_;
+  scoped_ptr<aura::WindowTreeHost> host_;
 
   // Owned by the root Window.
   views::corewm::CompoundEventFilter* root_window_event_filter_;