16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file.
46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "athena/wm/window_list_provider_impl.h"
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <algorithm>
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "athena/wm/public/window_list_provider_observer.h"
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/aura/window.h"
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace athena {
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)WindowListProviderImpl::WindowListProviderImpl(aura::Window* container)
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : container_(container) {
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  CHECK(container_);
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  container_->AddObserver(this);
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RecreateWindowList();
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::for_each(window_list_.begin(), window_list_.end(),
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                std::bind2nd(std::mem_fun(&aura::Window::AddObserver),
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             this));
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)WindowListProviderImpl::~WindowListProviderImpl() {
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Remove all remaining window observers.
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (aura::Window::Windows::const_iterator iter = window_list_.begin();
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       iter != window_list_.end();
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++iter) {
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CHECK(IsValidWindow(*iter));
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    (*iter)->RemoveObserver(this);
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  container_->RemoveObserver(this);
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WindowListProviderImpl::RecreateWindowList() {
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  window_list_.clear();
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const aura::Window::Windows& container_children = container_->children();
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (aura::Window::Windows::const_iterator iter = container_children.begin();
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       iter != container_children.end();
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       ++iter) {
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (IsValidWindow(*iter))
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      window_list_.push_back(*iter);
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WindowListProviderImpl::AddObserver(WindowListProviderObserver* observer) {
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  observers_.AddObserver(observer);
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WindowListProviderImpl::RemoveObserver(
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    WindowListProviderObserver* observer) {
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  observers_.RemoveObserver(observer);
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst aura::Window::Windows& WindowListProviderImpl::GetWindowList() const {
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return window_list_;
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool WindowListProviderImpl::IsWindowInList(aura::Window* window) const {
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return window->parent() == container_ && IsValidWindow(window);
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool WindowListProviderImpl::IsValidWindow(aura::Window* window) const {
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(oshima): crbug.com/413912
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return window->type() == ui::wm::WINDOW_TYPE_NORMAL ||
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      window->type() == ui::wm::WINDOW_TYPE_PANEL;
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WindowListProviderImpl::StackWindowFrontOf(
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    aura::Window* window,
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    aura::Window* reference_window) {
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_NE(window, reference_window);
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(IsWindowInList(window));
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(IsWindowInList(reference_window));
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  container_->StackChildAbove(window, reference_window);
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WindowListProviderImpl::StackWindowBehindTo(
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    aura::Window* window,
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    aura::Window* reference_window) {
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_NE(window, reference_window);
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(IsWindowInList(window));
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(IsWindowInList(reference_window));
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  container_->StackChildBelow(window, reference_window);
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WindowListProviderImpl::OnWindowAdded(aura::Window* window) {
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!IsValidWindow(window) || window->parent() != container_)
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RecreateWindowList();
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(IsWindowInList(window));
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  window->AddObserver(this);
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WindowListProviderImpl::OnWillRemoveWindow(aura::Window* window) {
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!IsValidWindow(window) || window->parent() != container_)
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(IsWindowInList(window));
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  aura::Window::Windows::iterator find = std::find(window_list_.begin(),
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   window_list_.end(),
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   window);
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(find != window_list_.end());
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int index = find - window_list_.begin();
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  window_list_.erase(find);
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  window->RemoveObserver(this);
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WindowListProviderObserver, observers_, OnWindowRemoved(window, index));
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WindowListProviderImpl::OnWindowStackingChanged(aura::Window* window) {
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (window == container_)
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(IsWindowInList(window));
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RecreateWindowList();
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Inform our listeners that the stacking has been changed.
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(WindowListProviderObserver,
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    observers_,
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    OnWindowStackingChanged());
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace athena
122