blob: 6823a4d0270495281df5817db94421e79886b386 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "athena/wm/window_list_provider_impl.h"
#include <algorithm>
#include "athena/athena_export.h"
#include "athena/wm/public/window_list_provider_observer.h"
#include "ui/aura/window.h"
#include "ui/aura/window_property.h"
#include "ui/wm/core/transient_window_manager.h"
#include "ui/wm/core/window_util.h"
DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(ATHENA_EXPORT, bool);
namespace athena {
namespace {
// Used to keep track of which window should be managed. This is necessary
// as the necessary informatino used in IsValidWindow (transient parent
// for example) may not available during destruction.
DEFINE_WINDOW_PROPERTY_KEY(bool, kManagedKey, false);
} // namespace
WindowListProviderImpl::WindowListProviderImpl(aura::Window* container)
: container_(container) {
CHECK(container_);
container_->AddObserver(this);
RecreateWindowList();
for (auto* window : window_list_)
window->AddObserver(this);
}
WindowListProviderImpl::~WindowListProviderImpl() {
// Remove all remaining window observers.
for (auto* window : window_list_) {
CHECK(window->GetProperty(kManagedKey));
window->RemoveObserver(this);
}
container_->RemoveObserver(this);
}
bool WindowListProviderImpl::IsValidWindow(aura::Window* window) const {
if (wm::GetTransientParent(window))
return false;
// TODO(oshima): crbug.com/413912.
return window->type() == ui::wm::WINDOW_TYPE_NORMAL ||
window->type() == ui::wm::WINDOW_TYPE_PANEL;
}
void WindowListProviderImpl::AddObserver(WindowListProviderObserver* observer) {
observers_.AddObserver(observer);
}
void WindowListProviderImpl::RemoveObserver(
WindowListProviderObserver* observer) {
observers_.RemoveObserver(observer);
}
const aura::Window::Windows& WindowListProviderImpl::GetWindowList() const {
return window_list_;
}
bool WindowListProviderImpl::IsWindowInList(aura::Window* window) const {
return std::find(window_list_.begin(), window_list_.end(), window) !=
window_list_.end();
}
void WindowListProviderImpl::StackWindowFrontOf(
aura::Window* window,
aura::Window* reference_window) {
DCHECK_NE(window, reference_window);
DCHECK(IsWindowInList(window));
DCHECK(IsWindowInList(reference_window));
container_->StackChildAbove(window, reference_window);
}
void WindowListProviderImpl::StackWindowBehindTo(
aura::Window* window,
aura::Window* reference_window) {
DCHECK_NE(window, reference_window);
DCHECK(IsWindowInList(window));
DCHECK(IsWindowInList(reference_window));
container_->StackChildBelow(window, reference_window);
}
void WindowListProviderImpl::RecreateWindowList() {
window_list_.clear();
for (auto* window : container_->children()) {
if (window->GetProperty(kManagedKey))
window_list_.push_back(window);
}
}
void WindowListProviderImpl::OnWindowAdded(aura::Window* window) {
if (!IsValidWindow(window) || window->parent() != container_)
return;
window->SetProperty(kManagedKey, true);
RecreateWindowList();
DCHECK(IsWindowInList(window));
window->AddObserver(this);
FOR_EACH_OBSERVER(
WindowListProviderObserver, observers_, OnWindowAddedToList(window));
}
void WindowListProviderImpl::OnWillRemoveWindow(aura::Window* window) {
if (!window->GetProperty(kManagedKey))
return;
DCHECK(IsWindowInList(window));
aura::Window::Windows::iterator find = std::find(window_list_.begin(),
window_list_.end(),
window);
CHECK(find != window_list_.end());
int index = find - window_list_.begin();
window_list_.erase(find);
window->ClearProperty(kManagedKey);
window->RemoveObserver(this);
FOR_EACH_OBSERVER(WindowListProviderObserver,
observers_,
OnWindowRemovedFromList(window, index));
}
void WindowListProviderImpl::OnWindowStackingChanged(aura::Window* window) {
if (window == container_)
return;
DCHECK(IsWindowInList(window));
RecreateWindowList();
// Inform our listeners that the stacking has been changed.
FOR_EACH_OBSERVER(
WindowListProviderObserver, observers_, OnWindowStackingChangedInList());
}
} // namespace athena