1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "athena/screen/public/screen_manager.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "athena/input/public/accelerator_manager.h"
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "athena/screen/screen_accelerator_handler.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "athena/util/container_priorities.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "athena/util/fill_layout_manager.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/logging.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "ui/aura/client/screen_position_client.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/aura/client/window_tree_client.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/aura/layout_manager.h"
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/aura/test/test_screen.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/aura/window.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/aura/window_property.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/aura/window_targeter.h"
206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "ui/aura/window_tree_host.h"
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/compositor/layer.h"
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/gfx/display.h"
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/gfx/screen.h"
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/wm/core/base_focus_rules.h"
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/wm/core/capture_controller.h"
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/wm/core/focus_controller.h"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/wm/core/window_util.h"
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace athena {
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
32116680a4aac90f2aa7413d9095a592090648e557Ben MurdochDEFINE_OWNED_WINDOW_PROPERTY_KEY(ScreenManager::ContainerParams,
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 kContainerParamsKey,
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 NULL);
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ScreenManager* instance = NULL;
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool GrabsInput(aura::Window* container) {
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ScreenManager::ContainerParams* params =
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      container->GetProperty(kContainerParamsKey);
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return params && params->grab_inputs;
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Returns the container which contains |window|.
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)aura::Window* GetContainer(aura::Window* window) {
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  aura::Window* container = window;
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  while (container && !container->GetProperty(kContainerParamsKey))
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    container = container->parent();
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return container;
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass AthenaFocusRules : public wm::BaseFocusRules {
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AthenaFocusRules() {}
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~AthenaFocusRules() {}
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // wm::BaseFocusRules:
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool SupportsChildActivation(aura::Window* window) const OVERRIDE {
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScreenManager::ContainerParams* params =
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        window->GetProperty(kContainerParamsKey);
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return params && params->can_activate_children;
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual bool CanActivateWindow(aura::Window* window) const OVERRIDE {
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Check if containers of higher z-order than |window| have 'grab_inputs'
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // fields.
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (window) {
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const aura::Window::Windows& containers =
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          window->GetRootWindow()->children();
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      aura::Window::Windows::const_iterator iter =
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          std::find(containers.begin(), containers.end(), GetContainer(window));
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      DCHECK(iter != containers.end());
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      for (++iter; iter != containers.end(); ++iter) {
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if (GrabsInput(*iter))
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          return false;
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      }
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return BaseFocusRules::CanActivateWindow(window);
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(AthenaFocusRules);
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class AthenaWindowTreeClient : public aura::client::WindowTreeClient {
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  explicit AthenaWindowTreeClient(aura::Window* container)
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : container_(container) {}
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~AthenaWindowTreeClient() {}
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // aura::client::WindowTreeClient:
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual aura::Window* GetDefaultParent(aura::Window* context,
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         aura::Window* window,
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         const gfx::Rect& bounds) OVERRIDE {
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    aura::Window* transient_parent = wm::GetTransientParent(window);
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (transient_parent)
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return GetContainer(transient_parent);
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return container_;
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window* container_;
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AthenaWindowTreeClient);
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class AthenaScreenPositionClient : public aura::client::ScreenPositionClient {
1086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) public:
1096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AthenaScreenPositionClient() {
1106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual ~AthenaScreenPositionClient() {
1126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) private:
1156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // aura::client::ScreenPositionClient:
1166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual void ConvertPointToScreen(const aura::Window* window,
1176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                    gfx::Point* point) OVERRIDE {
1186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const aura::Window* root = window->GetRootWindow();
1196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    aura::Window::ConvertPointToTarget(window, root, point);
1206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual void ConvertPointFromScreen(const aura::Window* window,
1236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                      gfx::Point* point) OVERRIDE {
1246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const aura::Window* root = window->GetRootWindow();
1256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    aura::Window::ConvertPointToTarget(root, window, point);
1266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual void ConvertHostPointToScreen(aura::Window* window,
1296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                        gfx::Point* point) OVERRIDE {
1306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // TODO(oshima): Implement this when adding multiple display support.
1316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    NOTREACHED();
1326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual void SetBounds(aura::Window* window,
1356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         const gfx::Rect& bounds,
1366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         const gfx::Display& display) OVERRIDE {
1376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    window->SetBounds(bounds);
1386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AthenaScreenPositionClient);
1416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
1426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class AthenaEventTargeter : public aura::WindowTargeter,
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            public aura::WindowObserver {
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  explicit AthenaEventTargeter(aura::Window* container)
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : container_(container) {
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    container_->AddObserver(this);
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~AthenaEventTargeter() {
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Removed before the container is removed.
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (container_)
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      container_->RemoveObserver(this);
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // aura::WindowTargeter:
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual bool SubtreeCanAcceptEvent(
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::EventTarget* target,
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const ui::LocatedEvent& event) const OVERRIDE {
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    aura::Window* window = static_cast<aura::Window*>(target);
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const aura::Window::Windows& containers =
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        container_->GetRootWindow()->children();
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    aura::Window::Windows::const_iterator iter =
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        std::find(containers.begin(), containers.end(), container_);
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DCHECK(iter != containers.end());
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for (; iter != containers.end(); ++iter) {
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      if ((*iter)->Contains(window))
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return true;
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // aura::WindowObserver:
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    aura::Window* root_window = container_->GetRootWindow();
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DCHECK_EQ(window, container_);
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DCHECK_EQ(
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        this, static_cast<ui::EventTarget*>(root_window)->GetEventTargeter());
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    container_->RemoveObserver(this);
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    container_ = NULL;
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // This will remove myself.
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    root_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>());
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  aura::Window* container_;
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AthenaEventTargeter);
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class ScreenManagerImpl : public ScreenManager {
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  explicit ScreenManagerImpl(aura::Window* root_window);
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~ScreenManagerImpl();
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void Init();
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // ScreenManager:
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual aura::Window* CreateDefaultContainer(
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const ContainerParams& params) OVERRIDE;
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual aura::Window* CreateContainer(const ContainerParams& params) OVERRIDE;
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual aura::Window* GetContext() OVERRIDE { return root_window_; }
2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void SetRotation(gfx::Display::Rotation rotation) OVERRIDE;
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void SetRotationLocked(bool rotation_locked) OVERRIDE;
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Not owned.
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window* root_window_;
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<aura::client::FocusClient> focus_client_;
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<aura::client::WindowTreeClient> window_tree_client_;
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<AcceleratorHandler> accelerator_handler_;
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr< ::wm::ScopedCaptureClient> capture_client_;
2176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<aura::client::ScreenPositionClient> screen_position_client_;
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Display::Rotation last_requested_rotation_;
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool rotation_locked_;
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScreenManagerImpl);
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciScreenManagerImpl::ScreenManagerImpl(aura::Window* root_window)
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : root_window_(root_window),
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      last_requested_rotation_(gfx::Display::ROTATE_0),
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      rotation_locked_(false) {
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(root_window_);
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!instance);
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  instance = this;
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ScreenManagerImpl::~ScreenManagerImpl() {
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  aura::client::SetScreenPositionClient(root_window_, NULL);
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  aura::client::SetWindowTreeClient(root_window_, NULL);
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  wm::FocusController* focus_controller =
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static_cast<wm::FocusController*>(focus_client_.get());
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  root_window_->RemovePreTargetHandler(focus_controller);
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  aura::client::SetActivationClient(root_window_, NULL);
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  aura::client::SetFocusClient(root_window_, NULL);
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  aura::Window::Windows children = root_window_->children();
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Close All children:
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (aura::Window::Windows::iterator iter = children.begin();
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       iter != children.end();
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++iter) {
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    delete *iter;
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  instance = NULL;
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ScreenManagerImpl::Init() {
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  wm::FocusController* focus_controller =
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new wm::FocusController(new AthenaFocusRules());
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  aura::client::SetFocusClient(root_window_, focus_controller);
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  root_window_->AddPreTargetHandler(focus_controller);
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  aura::client::SetActivationClient(root_window_, focus_controller);
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  focus_client_.reset(focus_controller);
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  root_window_->SetLayoutManager(new FillLayoutManager(root_window_));
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  capture_client_.reset(new ::wm::ScopedCaptureClient(root_window_));
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  accelerator_handler_.reset(new ScreenAcceleratorHandler(root_window_));
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)aura::Window* ScreenManagerImpl::CreateDefaultContainer(
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const ContainerParams& params) {
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  aura::Window* container = CreateContainer(params);
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  window_tree_client_.reset(new AthenaWindowTreeClient(container));
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::client::SetWindowTreeClient(root_window_, window_tree_client_.get());
2716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  screen_position_client_.reset(new AthenaScreenPositionClient());
2736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  aura::client::SetScreenPositionClient(root_window_,
2746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                        screen_position_client_.get());
2756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return container;
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A functor to find a container that has the higher priority.
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct HigherPriorityFinder {
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HigherPriorityFinder(int p) : priority(p) {}
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool operator()(aura::Window* window) {
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return window->GetProperty(kContainerParamsKey)->z_order_priority >
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           priority;
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int priority;
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if !defined(NDEBUG)
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct PriorityMatcher {
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PriorityMatcher(int p) : priority(p) {}
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool operator()(aura::Window* window) {
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return window->GetProperty(kContainerParamsKey)->z_order_priority ==
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           priority;
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int priority;
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdochaura::Window* ScreenManagerImpl::CreateContainer(
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const ContainerParams& params) {
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  aura::Window* container = new aura::Window(NULL);
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CHECK_GE(params.z_order_priority, 0);
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  container->Init(aura::WINDOW_LAYER_NOT_DRAWN);
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  container->SetName(params.name);
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const aura::Window::Windows& children = root_window_->children();
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if !defined(NDEBUG)
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(std::find_if(children.begin(),
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      children.end(),
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      PriorityMatcher(params.z_order_priority))
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         == children.end())
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      << "The container with the priority "
3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      << params.z_order_priority << " already exists.";
3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  container->SetProperty(kContainerParamsKey, new ContainerParams(params));
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If another container is already grabbing the input, SetEventTargeter
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // implicitly release the grabbing and remove the EventTargeter instance.
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // TODO(mukai|oshima): think about the ideal behavior of multiple grabbing
3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // and implement it.
3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (params.grab_inputs) {
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DCHECK(std::find_if(children.begin(), children.end(), &GrabsInput)
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           == children.end())
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        << "input has already been grabbed by another container";
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    root_window_->SetEventTargeter(
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        scoped_ptr<ui::EventTargeter>(new AthenaEventTargeter(container)));
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  root_window_->AddChild(container);
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  aura::Window::Windows::const_iterator iter =
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      std::find_if(children.begin(),
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   children.end(),
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   HigherPriorityFinder(params.z_order_priority));
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (iter != children.end())
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    root_window_->StackChildBelow(container, *iter);
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  container->Show();
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return container;
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ScreenManagerImpl::SetRotation(gfx::Display::Rotation rotation) {
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  last_requested_rotation_ = rotation;
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (rotation_locked_ || rotation ==
3486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().rotation()) {
3496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
3506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
3516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // TODO(flackr): Use display manager to update display rotation:
3536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // http://crbug.com/401044.
3546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static_cast<aura::TestScreen*>(gfx::Screen::GetNativeScreen())->
3556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      SetDisplayRotation(rotation);
3566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
3576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ScreenManagerImpl::SetRotationLocked(bool rotation_locked) {
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  rotation_locked_ = rotation_locked;
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!rotation_locked_)
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SetRotation(last_requested_rotation_);
3626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
3636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ScreenManager::ContainerParams::ContainerParams(const std::string& n,
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                int priority)
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : name(n),
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      can_activate_children(false),
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      grab_inputs(false),
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      z_order_priority(priority) {
372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciScreenManager* ScreenManager::Create(aura::Window* root_window) {
3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  (new ScreenManagerImpl(root_window))->Init();
377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(instance);
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return instance;
379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static
382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ScreenManager* ScreenManager::Get() {
383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(instance);
384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return instance;
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ScreenManager::Shutdown() {
389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(instance);
390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  delete instance;
391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!instance);
392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace athena
395