Enable snappy for IndexedDB.
[chromium-blink-merge.git] / ash / wm / system_modal_container_layout_manager.cc
blob99889d2f5948fcef4521c1e6c393d57bc59b0611
1 // Copyright (c) 2012 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 "ash/wm/system_modal_container_layout_manager.h"
7 #include "ash/session_state_delegate.h"
8 #include "ash/shell.h"
9 #include "ash/shell_window_ids.h"
10 #include "ash/wm/system_modal_container_event_filter.h"
11 #include "ash/wm/window_animations.h"
12 #include "ash/wm/window_util.h"
13 #include "base/bind.h"
14 #include "ui/aura/client/aura_constants.h"
15 #include "ui/aura/client/capture_client.h"
16 #include "ui/aura/root_window.h"
17 #include "ui/aura/window.h"
18 #include "ui/base/ui_base_switches_util.h"
19 #include "ui/compositor/layer.h"
20 #include "ui/compositor/layer_animator.h"
21 #include "ui/compositor/scoped_layer_animation_settings.h"
22 #include "ui/events/event.h"
23 #include "ui/gfx/screen.h"
24 #include "ui/views/corewm/compound_event_filter.h"
25 #include "ui/views/view.h"
26 #include "ui/views/widget/widget.h"
28 namespace ash {
29 namespace internal {
31 ////////////////////////////////////////////////////////////////////////////////
32 // SystemModalContainerLayoutManager, public:
34 SystemModalContainerLayoutManager::SystemModalContainerLayoutManager(
35 aura::Window* container)
36 : container_(container),
37 modal_background_(NULL) {
40 SystemModalContainerLayoutManager::~SystemModalContainerLayoutManager() {
43 ////////////////////////////////////////////////////////////////////////////////
44 // SystemModalContainerLayoutManager, aura::LayoutManager implementation:
46 void SystemModalContainerLayoutManager::OnWindowResized() {
47 if (modal_background_) {
48 // Note: we have to set the entire bounds with the screen offset.
49 modal_background_->SetBounds(
50 Shell::GetScreen()->GetDisplayNearestWindow(container_).bounds());
52 if (!modal_windows_.empty()) {
53 aura::Window::Windows::iterator it = modal_windows_.begin();
54 for (it = modal_windows_.begin(); it != modal_windows_.end(); ++it) {
55 gfx::Rect bounds = (*it)->bounds();
56 bounds.AdjustToFit(container_->bounds());
57 (*it)->SetBounds(bounds);
62 void SystemModalContainerLayoutManager::OnWindowAddedToLayout(
63 aura::Window* child) {
64 DCHECK((modal_background_ && child == modal_background_->GetNativeView()) ||
65 child->type() == aura::client::WINDOW_TYPE_NORMAL ||
66 child->type() == aura::client::WINDOW_TYPE_POPUP);
67 DCHECK(
68 container_->id() != internal::kShellWindowId_LockSystemModalContainer ||
69 Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked());
71 child->AddObserver(this);
72 if (child->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_NONE)
73 AddModalWindow(child);
76 void SystemModalContainerLayoutManager::OnWillRemoveWindowFromLayout(
77 aura::Window* child) {
78 child->RemoveObserver(this);
79 if (child->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_NONE)
80 RemoveModalWindow(child);
83 void SystemModalContainerLayoutManager::OnWindowRemovedFromLayout(
84 aura::Window* child) {
87 void SystemModalContainerLayoutManager::OnChildWindowVisibilityChanged(
88 aura::Window* child,
89 bool visible) {
92 void SystemModalContainerLayoutManager::SetChildBounds(
93 aura::Window* child,
94 const gfx::Rect& requested_bounds) {
95 SetChildBoundsDirect(child, requested_bounds);
98 ////////////////////////////////////////////////////////////////////////////////
99 // SystemModalContainerLayoutManager, aura::WindowObserver implementation:
101 void SystemModalContainerLayoutManager::OnWindowPropertyChanged(
102 aura::Window* window,
103 const void* key,
104 intptr_t old) {
105 if (key != aura::client::kModalKey)
106 return;
108 if (window->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_NONE) {
109 AddModalWindow(window);
110 } else if (static_cast<ui::ModalType>(old) != ui::MODAL_TYPE_NONE) {
111 RemoveModalWindow(window);
112 Shell::GetInstance()->OnModalWindowRemoved(window);
116 void SystemModalContainerLayoutManager::OnWindowDestroying(
117 aura::Window* window) {
118 if (modal_background_ && modal_background_->GetNativeView() == window)
119 modal_background_ = NULL;
122 bool SystemModalContainerLayoutManager::CanWindowReceiveEvents(
123 aura::Window* window) {
124 // We could get when we're at lock screen and there is modal window at
125 // system modal window layer which added event filter.
126 // Now this lock modal windows layer layout manager should not block events
127 // for windows at lock layer.
128 // See SystemModalContainerLayoutManagerTest.EventFocusContainers and
129 // http://crbug.com/157469
130 if (modal_windows_.empty())
131 return true;
132 // This container can not handle events if the screen is locked and it is not
133 // above the lock screen layer (crbug.com/110920).
134 if (Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked() &&
135 container_->id() < ash::internal::kShellWindowId_LockScreenContainer)
136 return true;
137 return wm::GetActivatableWindow(window) == modal_window();
140 bool SystemModalContainerLayoutManager::ActivateNextModalWindow() {
141 if (modal_windows_.empty())
142 return false;
143 wm::ActivateWindow(modal_window());
144 return true;
147 void SystemModalContainerLayoutManager::CreateModalBackground() {
148 if (!modal_background_) {
149 modal_background_ = new views::Widget;
150 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
151 params.parent = container_;
152 params.bounds = Shell::GetScreen()->GetDisplayNearestWindow(
153 container_).bounds();
154 modal_background_->Init(params);
155 modal_background_->GetNativeView()->SetName(
156 "SystemModalContainerLayoutManager.ModalBackground");
157 views::View* contents_view = new views::View();
158 // TODO(jamescook): This could be SK_ColorWHITE for the new dialog style.
159 contents_view->set_background(
160 views::Background::CreateSolidBackground(SK_ColorBLACK));
161 modal_background_->SetContentsView(contents_view);
162 modal_background_->GetNativeView()->layer()->SetOpacity(0.0f);
165 ui::ScopedLayerAnimationSettings settings(
166 modal_background_->GetNativeView()->layer()->GetAnimator());
167 modal_background_->Show();
168 modal_background_->GetNativeView()->layer()->SetOpacity(0.5f);
169 container_->StackChildAtTop(modal_background_->GetNativeView());
172 void SystemModalContainerLayoutManager::DestroyModalBackground() {
173 // modal_background_ can be NULL when a root window is shutting down
174 // and OnWindowDestroying is called first.
175 if (modal_background_) {
176 ui::ScopedLayerAnimationSettings settings(
177 modal_background_->GetNativeView()->layer()->GetAnimator());
178 modal_background_->Close();
179 settings.AddObserver(views::corewm::CreateHidingWindowAnimationObserver(
180 modal_background_->GetNativeView()));
181 modal_background_->GetNativeView()->layer()->SetOpacity(0.0f);
182 modal_background_ = NULL;
186 // static
187 bool SystemModalContainerLayoutManager::IsModalBackground(
188 aura::Window* window) {
189 int id = window->parent()->id();
190 if (id != internal::kShellWindowId_SystemModalContainer &&
191 id != internal::kShellWindowId_LockSystemModalContainer)
192 return false;
193 SystemModalContainerLayoutManager* layout_manager =
194 static_cast<SystemModalContainerLayoutManager*>(
195 window->parent()->layout_manager());
196 return layout_manager->modal_background_ &&
197 layout_manager->modal_background_->GetNativeWindow() == window;
200 ////////////////////////////////////////////////////////////////////////////////
201 // SystemModalContainerLayoutManager, private:
203 void SystemModalContainerLayoutManager::AddModalWindow(aura::Window* window) {
204 if (modal_windows_.empty()) {
205 aura::Window* capture_window = aura::client::GetCaptureWindow(container_);
206 if (capture_window)
207 capture_window->ReleaseCapture();
209 modal_windows_.push_back(window);
210 Shell::GetInstance()->CreateModalBackground(window);
211 window->parent()->StackChildAtTop(window);
214 void SystemModalContainerLayoutManager::RemoveModalWindow(
215 aura::Window* window) {
216 aura::Window::Windows::iterator it =
217 std::find(modal_windows_.begin(), modal_windows_.end(), window);
218 if (it != modal_windows_.end())
219 modal_windows_.erase(it);
222 } // namespace internal
223 } // namespace ash