1// Copyright 2014 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. 4 5#include "athena/wm/window_list_provider_impl.h" 6 7#include <algorithm> 8 9#include "athena/wm/public/window_list_provider_observer.h" 10#include "ui/aura/window.h" 11 12namespace athena { 13 14WindowListProviderImpl::WindowListProviderImpl(aura::Window* container) 15 : container_(container) { 16 CHECK(container_); 17 container_->AddObserver(this); 18 RecreateWindowList(); 19 std::for_each(window_list_.begin(), window_list_.end(), 20 std::bind2nd(std::mem_fun(&aura::Window::AddObserver), 21 this)); 22} 23 24WindowListProviderImpl::~WindowListProviderImpl() { 25 // Remove all remaining window observers. 26 for (aura::Window::Windows::const_iterator iter = window_list_.begin(); 27 iter != window_list_.end(); 28 ++iter) { 29 CHECK(IsValidWindow(*iter)); 30 (*iter)->RemoveObserver(this); 31 } 32 container_->RemoveObserver(this); 33} 34 35void WindowListProviderImpl::RecreateWindowList() { 36 window_list_.clear(); 37 const aura::Window::Windows& container_children = container_->children(); 38 for (aura::Window::Windows::const_iterator iter = container_children.begin(); 39 iter != container_children.end(); 40 ++iter) { 41 if (IsValidWindow(*iter)) 42 window_list_.push_back(*iter); 43 } 44} 45 46void WindowListProviderImpl::AddObserver(WindowListProviderObserver* observer) { 47 observers_.AddObserver(observer); 48} 49 50void WindowListProviderImpl::RemoveObserver( 51 WindowListProviderObserver* observer) { 52 observers_.RemoveObserver(observer); 53} 54 55const aura::Window::Windows& WindowListProviderImpl::GetWindowList() const { 56 return window_list_; 57} 58 59bool WindowListProviderImpl::IsWindowInList(aura::Window* window) const { 60 return window->parent() == container_ && IsValidWindow(window); 61} 62 63bool WindowListProviderImpl::IsValidWindow(aura::Window* window) const { 64 // TODO(oshima): crbug.com/413912 65 return window->type() == ui::wm::WINDOW_TYPE_NORMAL || 66 window->type() == ui::wm::WINDOW_TYPE_PANEL; 67} 68 69void WindowListProviderImpl::StackWindowFrontOf( 70 aura::Window* window, 71 aura::Window* reference_window) { 72 DCHECK_NE(window, reference_window); 73 DCHECK(IsWindowInList(window)); 74 DCHECK(IsWindowInList(reference_window)); 75 container_->StackChildAbove(window, reference_window); 76} 77 78void WindowListProviderImpl::StackWindowBehindTo( 79 aura::Window* window, 80 aura::Window* reference_window) { 81 DCHECK_NE(window, reference_window); 82 DCHECK(IsWindowInList(window)); 83 DCHECK(IsWindowInList(reference_window)); 84 container_->StackChildBelow(window, reference_window); 85} 86 87void WindowListProviderImpl::OnWindowAdded(aura::Window* window) { 88 if (!IsValidWindow(window) || window->parent() != container_) 89 return; 90 RecreateWindowList(); 91 DCHECK(IsWindowInList(window)); 92 window->AddObserver(this); 93} 94 95void WindowListProviderImpl::OnWillRemoveWindow(aura::Window* window) { 96 if (!IsValidWindow(window) || window->parent() != container_) 97 return; 98 DCHECK(IsWindowInList(window)); 99 aura::Window::Windows::iterator find = std::find(window_list_.begin(), 100 window_list_.end(), 101 window); 102 CHECK(find != window_list_.end()); 103 int index = find - window_list_.begin(); 104 window_list_.erase(find); 105 window->RemoveObserver(this); 106 FOR_EACH_OBSERVER( 107 WindowListProviderObserver, observers_, OnWindowRemoved(window, index)); 108} 109 110void WindowListProviderImpl::OnWindowStackingChanged(aura::Window* window) { 111 if (window == container_) 112 return; 113 DCHECK(IsWindowInList(window)); 114 RecreateWindowList(); 115 // Inform our listeners that the stacking has been changed. 116 FOR_EACH_OBSERVER(WindowListProviderObserver, 117 observers_, 118 OnWindowStackingChanged()); 119} 120 121} // namespace athena 122