This source file includes following definitions.
- modal_background_
- OnWindowResized
- OnWindowAddedToLayout
- OnWillRemoveWindowFromLayout
- OnWindowRemovedFromLayout
- OnChildWindowVisibilityChanged
- SetChildBounds
- OnWindowPropertyChanged
- OnWindowDestroying
- CanWindowReceiveEvents
- ActivateNextModalWindow
- CreateModalBackground
- DestroyModalBackground
- IsModalBackground
- AddModalWindow
- RemoveModalWindow
#include "ash/wm/system_modal_container_layout_manager.h"
#include "ash/session_state_delegate.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/system_modal_container_event_filter.h"
#include "ash/wm/window_animations.h"
#include "ash/wm/window_util.h"
#include "base/bind.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/capture_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event.h"
#include "ui/gfx/screen.h"
#include "ui/views/background.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/compound_event_filter.h"
namespace ash {
SystemModalContainerLayoutManager::SystemModalContainerLayoutManager(
aura::Window* container)
: container_(container),
modal_background_(NULL) {
}
SystemModalContainerLayoutManager::~SystemModalContainerLayoutManager() {
}
void SystemModalContainerLayoutManager::OnWindowResized() {
if (modal_background_) {
modal_background_->SetBounds(
Shell::GetScreen()->GetDisplayNearestWindow(container_).bounds());
}
if (!modal_windows_.empty()) {
aura::Window::Windows::iterator it = modal_windows_.begin();
for (it = modal_windows_.begin(); it != modal_windows_.end(); ++it) {
gfx::Rect bounds = (*it)->bounds();
bounds.AdjustToFit(container_->bounds());
(*it)->SetBounds(bounds);
}
}
}
void SystemModalContainerLayoutManager::OnWindowAddedToLayout(
aura::Window* child) {
DCHECK((modal_background_ && child == modal_background_->GetNativeView()) ||
child->type() == ui::wm::WINDOW_TYPE_NORMAL ||
child->type() == ui::wm::WINDOW_TYPE_POPUP);
DCHECK(
container_->id() != kShellWindowId_LockSystemModalContainer ||
Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked());
child->AddObserver(this);
if (child->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_NONE)
AddModalWindow(child);
}
void SystemModalContainerLayoutManager::OnWillRemoveWindowFromLayout(
aura::Window* child) {
child->RemoveObserver(this);
if (child->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_NONE)
RemoveModalWindow(child);
}
void SystemModalContainerLayoutManager::OnWindowRemovedFromLayout(
aura::Window* child) {
}
void SystemModalContainerLayoutManager::OnChildWindowVisibilityChanged(
aura::Window* child,
bool visible) {
}
void SystemModalContainerLayoutManager::SetChildBounds(
aura::Window* child,
const gfx::Rect& requested_bounds) {
SetChildBoundsDirect(child, requested_bounds);
}
void SystemModalContainerLayoutManager::OnWindowPropertyChanged(
aura::Window* window,
const void* key,
intptr_t old) {
if (key != aura::client::kModalKey)
return;
if (window->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_NONE) {
AddModalWindow(window);
} else if (static_cast<ui::ModalType>(old) != ui::MODAL_TYPE_NONE) {
RemoveModalWindow(window);
Shell::GetInstance()->OnModalWindowRemoved(window);
}
}
void SystemModalContainerLayoutManager::OnWindowDestroying(
aura::Window* window) {
if (modal_background_ && modal_background_->GetNativeView() == window)
modal_background_ = NULL;
}
bool SystemModalContainerLayoutManager::CanWindowReceiveEvents(
aura::Window* window) {
if (modal_windows_.empty())
return true;
if (Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked() &&
container_->id() < ash::kShellWindowId_LockScreenContainer)
return true;
return wm::GetActivatableWindow(window) == modal_window();
}
bool SystemModalContainerLayoutManager::ActivateNextModalWindow() {
if (modal_windows_.empty())
return false;
wm::ActivateWindow(modal_window());
return true;
}
void SystemModalContainerLayoutManager::CreateModalBackground() {
if (!modal_background_) {
modal_background_ = new views::Widget;
views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
params.parent = container_;
params.bounds = Shell::GetScreen()->GetDisplayNearestWindow(
container_).bounds();
modal_background_->Init(params);
modal_background_->GetNativeView()->SetName(
"SystemModalContainerLayoutManager.ModalBackground");
views::View* contents_view = new views::View();
contents_view->set_background(
views::Background::CreateSolidBackground(SK_ColorBLACK));
modal_background_->SetContentsView(contents_view);
modal_background_->GetNativeView()->layer()->SetOpacity(0.0f);
}
ui::ScopedLayerAnimationSettings settings(
modal_background_->GetNativeView()->layer()->GetAnimator());
modal_background_->GetNativeView()->layer()->SetOpacity(0.5f);
modal_background_->Show();
container_->StackChildAtTop(modal_background_->GetNativeView());
}
void SystemModalContainerLayoutManager::DestroyModalBackground() {
if (modal_background_) {
::wm::ScopedHidingAnimationSettings settings(
modal_background_->GetNativeView());
modal_background_->Close();
modal_background_->GetNativeView()->layer()->SetOpacity(0.0f);
modal_background_ = NULL;
}
}
bool SystemModalContainerLayoutManager::IsModalBackground(
aura::Window* window) {
int id = window->parent()->id();
if (id != kShellWindowId_SystemModalContainer &&
id != kShellWindowId_LockSystemModalContainer)
return false;
SystemModalContainerLayoutManager* layout_manager =
static_cast<SystemModalContainerLayoutManager*>(
window->parent()->layout_manager());
return layout_manager->modal_background_ &&
layout_manager->modal_background_->GetNativeWindow() == window;
}
void SystemModalContainerLayoutManager::AddModalWindow(aura::Window* window) {
if (modal_windows_.empty()) {
aura::Window* capture_window = aura::client::GetCaptureWindow(container_);
if (capture_window)
capture_window->ReleaseCapture();
}
modal_windows_.push_back(window);
Shell::GetInstance()->CreateModalBackground(window);
window->parent()->StackChildAtTop(window);
}
void SystemModalContainerLayoutManager::RemoveModalWindow(
aura::Window* window) {
aura::Window::Windows::iterator it =
std::find(modal_windows_.begin(), modal_windows_.end(), window);
if (it != modal_windows_.end())
modal_windows_.erase(it);
}
}