Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / athena / screen / screen_manager_impl.cc
bloba154d522f2edcec74117a63d3aacab35e7fd2054
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "athena/screen/public/screen_manager.h"
7 #include "athena/common/container_priorities.h"
8 #include "athena/common/fill_layout_manager.h"
9 #include "athena/input/public/accelerator_manager.h"
10 #include "athena/screen/background_controller.h"
11 #include "athena/screen/screen_accelerator_handler.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "ui/aura/client/screen_position_client.h"
15 #include "ui/aura/client/window_tree_client.h"
16 #include "ui/aura/layout_manager.h"
17 #include "ui/aura/test/test_screen.h"
18 #include "ui/aura/window.h"
19 #include "ui/aura/window_property.h"
20 #include "ui/aura/window_targeter.h"
21 #include "ui/aura/window_tree_host.h"
22 #include "ui/compositor/layer.h"
23 #include "ui/gfx/display.h"
24 #include "ui/gfx/screen.h"
25 #include "ui/wm/core/base_focus_rules.h"
26 #include "ui/wm/core/capture_controller.h"
27 #include "ui/wm/core/focus_controller.h"
29 namespace athena {
30 namespace {
32 DEFINE_OWNED_WINDOW_PROPERTY_KEY(ScreenManager::ContainerParams,
33 kContainerParamsKey,
34 NULL);
36 ScreenManager* instance = NULL;
38 bool GrabsInput(aura::Window* container) {
39 ScreenManager::ContainerParams* params =
40 container->GetProperty(kContainerParamsKey);
41 return params && params->grab_inputs;
44 // Returns the container which contains |window|.
45 aura::Window* GetContainer(aura::Window* window) {
46 // No containers for NULL or the root window itself.
47 if (!window || !window->parent())
48 return NULL;
49 if (window->parent()->IsRootWindow())
50 return window;
51 return GetContainer(window->parent());
54 class AthenaFocusRules : public wm::BaseFocusRules {
55 public:
56 AthenaFocusRules() {}
57 virtual ~AthenaFocusRules() {}
59 // wm::BaseFocusRules:
60 virtual bool SupportsChildActivation(aura::Window* window) const OVERRIDE {
61 ScreenManager::ContainerParams* params =
62 window->GetProperty(kContainerParamsKey);
63 return params && params->can_activate_children;
65 virtual bool CanActivateWindow(aura::Window* window) const OVERRIDE {
66 // Check if containers of higher z-order than |window| have 'grab_inputs'
67 // fields.
68 if (window) {
69 const aura::Window::Windows& containers =
70 window->GetRootWindow()->children();
71 aura::Window::Windows::const_iterator iter =
72 std::find(containers.begin(), containers.end(), GetContainer(window));
73 DCHECK(iter != containers.end());
74 for (++iter; iter != containers.end(); ++iter) {
75 if (GrabsInput(*iter))
76 return false;
79 return BaseFocusRules::CanActivateWindow(window);
82 private:
83 DISALLOW_COPY_AND_ASSIGN(AthenaFocusRules);
86 class AthenaWindowTreeClient : public aura::client::WindowTreeClient {
87 public:
88 explicit AthenaWindowTreeClient(aura::Window* container)
89 : container_(container) {}
91 private:
92 virtual ~AthenaWindowTreeClient() {}
94 // aura::client::WindowTreeClient:
95 virtual aura::Window* GetDefaultParent(aura::Window* context,
96 aura::Window* window,
97 const gfx::Rect& bounds) OVERRIDE {
98 return container_;
101 aura::Window* container_;
103 DISALLOW_COPY_AND_ASSIGN(AthenaWindowTreeClient);
106 class AthenaScreenPositionClient : public aura::client::ScreenPositionClient {
107 public:
108 AthenaScreenPositionClient() {
110 virtual ~AthenaScreenPositionClient() {
113 private:
114 // aura::client::ScreenPositionClient:
115 virtual void ConvertPointToScreen(const aura::Window* window,
116 gfx::Point* point) OVERRIDE {
117 const aura::Window* root = window->GetRootWindow();
118 aura::Window::ConvertPointToTarget(window, root, point);
121 virtual void ConvertPointFromScreen(const aura::Window* window,
122 gfx::Point* point) OVERRIDE {
123 const aura::Window* root = window->GetRootWindow();
124 aura::Window::ConvertPointToTarget(root, window, point);
127 virtual void ConvertHostPointToScreen(aura::Window* window,
128 gfx::Point* point) OVERRIDE {
129 // TODO(oshima): Implement this when adding multiple display support.
130 NOTREACHED();
133 virtual void SetBounds(aura::Window* window,
134 const gfx::Rect& bounds,
135 const gfx::Display& display) OVERRIDE {
136 window->SetBounds(bounds);
139 DISALLOW_COPY_AND_ASSIGN(AthenaScreenPositionClient);
142 class AthenaEventTargeter : public aura::WindowTargeter,
143 public aura::WindowObserver {
144 public:
145 explicit AthenaEventTargeter(aura::Window* container)
146 : container_(container) {
147 container_->AddObserver(this);
150 virtual ~AthenaEventTargeter() {
151 // Removed before the container is removed.
152 if (container_)
153 container_->RemoveObserver(this);
156 private:
157 // aura::WindowTargeter:
158 virtual bool SubtreeCanAcceptEvent(
159 ui::EventTarget* target,
160 const ui::LocatedEvent& event) const OVERRIDE {
161 aura::Window* window = static_cast<aura::Window*>(target);
162 const aura::Window::Windows& containers =
163 container_->GetRootWindow()->children();
164 aura::Window::Windows::const_iterator iter =
165 std::find(containers.begin(), containers.end(), container_);
166 DCHECK(iter != containers.end());
167 for (; iter != containers.end(); ++iter) {
168 if ((*iter)->Contains(window))
169 return true;
171 return false;
174 // aura::WindowObserver:
175 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
176 aura::Window* root_window = container_->GetRootWindow();
177 DCHECK_EQ(window, container_);
178 DCHECK_EQ(
179 this, static_cast<ui::EventTarget*>(root_window)->GetEventTargeter());
181 container_->RemoveObserver(this);
182 container_ = NULL;
184 // This will remove myself.
185 root_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>());
188 aura::Window* container_;
190 DISALLOW_COPY_AND_ASSIGN(AthenaEventTargeter);
193 class ScreenManagerImpl : public ScreenManager {
194 public:
195 ScreenManagerImpl(aura::Window* root_window);
196 virtual ~ScreenManagerImpl();
198 void Init();
200 private:
201 // ScreenManager:
202 virtual aura::Window* CreateDefaultContainer(
203 const ContainerParams& params) OVERRIDE;
204 virtual aura::Window* CreateContainer(const ContainerParams& params) OVERRIDE;
205 virtual aura::Window* GetContext() OVERRIDE { return root_window_; }
206 virtual void SetBackgroundImage(const gfx::ImageSkia& image) OVERRIDE;
207 virtual void SetRotation(gfx::Display::Rotation rotation) OVERRIDE;
208 virtual ui::LayerAnimator* GetScreenAnimator() OVERRIDE;
210 // Not owned.
211 aura::Window* root_window_;
212 aura::Window* background_window_;
214 scoped_ptr<aura::client::FocusClient> focus_client_;
215 scoped_ptr<BackgroundController> background_controller_;
216 scoped_ptr<aura::client::WindowTreeClient> window_tree_client_;
217 scoped_ptr<AcceleratorHandler> accelerator_handler_;
218 scoped_ptr< ::wm::ScopedCaptureClient> capture_client_;
219 scoped_ptr<aura::client::ScreenPositionClient> screen_position_client_;
221 DISALLOW_COPY_AND_ASSIGN(ScreenManagerImpl);
224 ScreenManagerImpl::ScreenManagerImpl(aura::Window* root_window)
225 : root_window_(root_window) {
226 DCHECK(root_window_);
227 DCHECK(!instance);
228 instance = this;
231 ScreenManagerImpl::~ScreenManagerImpl() {
232 aura::client::SetScreenPositionClient(root_window_, NULL);
233 aura::client::SetWindowTreeClient(root_window_, NULL);
234 wm::FocusController* focus_controller =
235 static_cast<wm::FocusController*>(focus_client_.get());
236 root_window_->RemovePreTargetHandler(focus_controller);
237 aura::client::SetActivationClient(root_window_, NULL);
238 aura::client::SetFocusClient(root_window_, NULL);
239 instance = NULL;
242 void ScreenManagerImpl::Init() {
243 wm::FocusController* focus_controller =
244 new wm::FocusController(new AthenaFocusRules());
246 aura::client::SetFocusClient(root_window_, focus_controller);
247 root_window_->AddPreTargetHandler(focus_controller);
248 aura::client::SetActivationClient(root_window_, focus_controller);
249 focus_client_.reset(focus_controller);
251 // TODO(oshima): Move the background out from ScreenManager.
252 root_window_->SetLayoutManager(new FillLayoutManager(root_window_));
253 background_window_ =
254 CreateContainer(ContainerParams("AthenaBackground", CP_BACKGROUND));
256 background_window_->SetLayoutManager(
257 new FillLayoutManager(background_window_));
258 background_controller_.reset(new BackgroundController(background_window_));
260 capture_client_.reset(new ::wm::ScopedCaptureClient(root_window_));
261 accelerator_handler_.reset(new ScreenAcceleratorHandler(root_window_));
264 aura::Window* ScreenManagerImpl::CreateDefaultContainer(
265 const ContainerParams& params) {
266 aura::Window* container = CreateContainer(params);
267 window_tree_client_.reset(new AthenaWindowTreeClient(container));
268 aura::client::SetWindowTreeClient(root_window_, window_tree_client_.get());
270 screen_position_client_.reset(new AthenaScreenPositionClient());
271 aura::client::SetScreenPositionClient(root_window_,
272 screen_position_client_.get());
274 return container;
277 // A functor to find a container that has the higher priority.
278 struct HigherPriorityFinder {
279 HigherPriorityFinder(int p) : priority(p) {}
280 bool operator()(aura::Window* window) {
281 return window->GetProperty(kContainerParamsKey)->z_order_priority >
282 priority;
284 int priority;
287 #if !defined(NDEBUG)
288 struct PriorityMatcher {
289 PriorityMatcher(int p) : priority(p) {}
290 bool operator()(aura::Window* window) {
291 return window->GetProperty(kContainerParamsKey)->z_order_priority ==
292 priority;
294 int priority;
296 #endif
298 aura::Window* ScreenManagerImpl::CreateContainer(
299 const ContainerParams& params) {
300 aura::Window* container = new aura::Window(NULL);
301 CHECK_GE(params.z_order_priority, 0);
302 container->Init(aura::WINDOW_LAYER_NOT_DRAWN);
303 container->SetName(params.name);
305 const aura::Window::Windows& children = root_window_->children();
307 #if !defined(NDEBUG)
308 DCHECK(std::find_if(children.begin(),
309 children.end(),
310 PriorityMatcher(params.z_order_priority))
311 == children.end())
312 << "The container with the priority "
313 << params.z_order_priority << " already exists.";
314 #endif
316 container->SetProperty(kContainerParamsKey, new ContainerParams(params));
318 // If another container is already grabbing the input, SetEventTargeter
319 // implicitly release the grabbing and remove the EventTargeter instance.
320 // TODO(mukai|oshima): think about the ideal behavior of multiple grabbing
321 // and implement it.
322 if (params.grab_inputs) {
323 DCHECK(std::find_if(children.begin(), children.end(), &GrabsInput)
324 == children.end())
325 << "input has already been grabbed by another container";
326 root_window_->SetEventTargeter(
327 scoped_ptr<ui::EventTargeter>(new AthenaEventTargeter(container)));
330 root_window_->AddChild(container);
332 aura::Window::Windows::const_iterator iter =
333 std::find_if(children.begin(),
334 children.end(),
335 HigherPriorityFinder(params.z_order_priority));
336 if (iter != children.end())
337 root_window_->StackChildBelow(container, *iter);
339 container->Show();
340 return container;
343 void ScreenManagerImpl::SetBackgroundImage(const gfx::ImageSkia& image) {
344 background_controller_->SetImage(image);
347 void ScreenManagerImpl::SetRotation(gfx::Display::Rotation rotation) {
348 if (rotation ==
349 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().rotation()) {
350 return;
353 // TODO(flackr): Use display manager to update display rotation:
354 // http://crbug.com/401044.
355 static_cast<aura::TestScreen*>(gfx::Screen::GetNativeScreen())->
356 SetDisplayRotation(rotation);
359 ui::LayerAnimator* ScreenManagerImpl::GetScreenAnimator() {
360 return root_window_->layer()->GetAnimator();
363 } // namespace
365 ScreenManager::ContainerParams::ContainerParams(const std::string& n,
366 int priority)
367 : name(n),
368 can_activate_children(false),
369 grab_inputs(false),
370 z_order_priority(priority) {
373 // static
374 ScreenManager* ScreenManager::Create(aura::Window* root_window) {
375 (new ScreenManagerImpl(root_window))->Init();
376 DCHECK(instance);
377 return instance;
380 // static
381 ScreenManager* ScreenManager::Get() {
382 DCHECK(instance);
383 return instance;
386 // static
387 void ScreenManager::Shutdown() {
388 DCHECK(instance);
389 delete instance;
390 DCHECK(!instance);
393 } // namespace athena