workspace_backdrop_delegate.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/maximize_mode/workspace_backdrop_delegate.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/window_animations.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/window_util.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/auto_reset.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/compositor/layer.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/background.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/widget/widget.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_util.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ash {
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace internal {
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// The opacity of the backdrop.
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const float kBackdropOpacity = 0.5f;
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WorkspaceBackdropDelegate::WorkspaceBackdropDelegate(aura::Window* container)
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : background_(NULL),
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      container_(container),
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      in_restacking_(false) {
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  background_ = new views::Widget;
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  views::Widget::InitParams params(
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  params.parent = container_;
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  params.bounds = container_->bounds();
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  params.layer_type = aura::WINDOW_LAYER_SOLID_COLOR;
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // To disallow the MRU list from picking this window up it should not be
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // activateable.
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  params.can_activate = false;
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  background_->Init(params);
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  background_->GetNativeView()->SetName("WorkspaceBackdropDelegate");
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  background_->GetNativeView()->layer()->SetColor(SK_ColorBLACK);
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Show();
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RestackBackdrop();
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  container_->AddObserver(this);
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WorkspaceBackdropDelegate::~WorkspaceBackdropDelegate() {
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  container_->RemoveObserver(this);
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ui::ScopedLayerAnimationSettings settings(
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      background_->GetNativeView()->layer()->GetAnimator());
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  background_->Close();
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  settings.AddObserver(::wm::CreateHidingWindowAnimationObserver(
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      background_->GetNativeView()));
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  background_->GetNativeView()->layer()->SetOpacity(0.0f);
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowBoundsChanged(
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    aura::Window* window,
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const gfx::Rect& old_bounds,
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const gfx::Rect& new_bounds) {
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The container size has changed and the layer needs to be adapt to it.
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AdjustToContainerBounds();
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowAddedToLayout(aura::Window* child) {
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RestackBackdrop();
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowRemovedFromLayout(aura::Window* child) {
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RestackBackdrop();
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnChildWindowVisibilityChanged(
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    aura::Window* child,
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool visible) {
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RestackBackdrop();
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowStackingChanged(aura::Window* window) {
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RestackBackdrop();
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnPostWindowStateTypeChange(
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    wm::WindowState* window_state,
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    wm::WindowStateType old_type) {
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RestackBackdrop();
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::RestackBackdrop() {
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Avoid recursive calls.
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (in_restacking_)
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::Window* window = GetCurrentTopWindow();
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!window) {
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Hide backdrop since no suitable window was found.
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    background_->Hide();
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (window == background_->GetNativeWindow() &&
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      background_->IsVisible()) {
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // We are changing the order of windows which will cause recursion.
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::AutoReset<bool> lock(&in_restacking_, true);
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!background_->IsVisible())
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Show();
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Since the backdrop needs to be immediately behind the window and the
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // stacking functions only guarantee a "it's above or below", we need
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // to re-arrange the two windows twice.
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  container_->StackChildAbove(background_->GetNativeView(), window);
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  container_->StackChildAbove(window, background_->GetNativeView());
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)aura::Window* WorkspaceBackdropDelegate::GetCurrentTopWindow() {
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const aura::Window::Windows& windows = container_->children();
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (aura::Window::Windows::const_reverse_iterator window_iter =
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           windows.rbegin();
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       window_iter != windows.rend(); ++window_iter) {
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    aura::Window* window = *window_iter;
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (window->TargetVisibility() &&
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        window->type() == ui::wm::WINDOW_TYPE_NORMAL &&
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        ash::wm::CanActivateWindow(window))
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return window;
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return NULL;
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::AdjustToContainerBounds() {
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cover the entire container window.
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Rect target_rect(gfx::Point(0, 0), container_->bounds().size());
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (target_rect != background_->GetNativeWindow()->bounds()) {
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // This needs to be instant.
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::ScopedLayerAnimationSettings settings(
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        background_->GetNativeView()->layer()->GetAnimator());
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(0));
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    background_->GetNativeWindow()->SetBounds(target_rect);
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!background_->IsVisible())
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity);
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::Show() {
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  background_->GetNativeView()->layer()->SetOpacity(0.0f);
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  background_->Show();
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ui::ScopedLayerAnimationSettings settings(
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      background_->GetNativeView()->layer()->GetAnimator());
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity);
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace internal
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace ash
155