15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_cycle_list.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ash/shell.h" 8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ash/wm/mru_window_tracker.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_util.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/views/corewm/window_animations.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WindowCycleList::WindowCycleList(const WindowList& windows) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : windows_(windows), 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_index_(-1) { 18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ash::Shell::GetInstance()->mru_window_tracker()->SetIgnoreActivations(true); 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Locate the currently active window in the list to use as our start point. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window* active_window = wm::GetActiveWindow(); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The active window may not be in the cycle list, which is expected if there 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are additional modal windows on the screen. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_index_ = GetWindowIndex(active_window); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (WindowList::const_iterator i = windows_.begin(); i != windows_.end(); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->AddObserver(this); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WindowCycleList::~WindowCycleList() { 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ash::Shell::GetInstance()->mru_window_tracker()->SetIgnoreActivations(false); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (WindowList::const_iterator i = windows_.begin(); i != windows_.end(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->RemoveObserver(this); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WindowCycleList::Step(Direction direction) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (windows_.empty()) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_index_ == -1) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We weren't able to find our active window in the shell delegate's 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provided window list. Just switch to the first (or last) one. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_index_ = (direction == FORWARD ? 0 : windows_.size() - 1); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // When there is only one window, we should give a feedback to user. 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (windows_.size() == 1) { 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AnimateWindow(windows_[0], 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::corewm::WINDOW_ANIMATION_TYPE_BOUNCE); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're in a valid cycle, so step forward or backward. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_index_ += (direction == FORWARD ? 1 : -1); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wrap to window list size. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_index_ = (current_index_ + windows_.size()) % windows_.size(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(windows_[current_index_]); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the next window is visible. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windows_[current_index_]->Show(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wm::ActivateWindow(windows_[current_index_]); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int WindowCycleList::GetWindowIndex(aura::Window* window) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowList::const_iterator it = 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::find(windows_.begin(), windows_.end(), window); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it == windows_.end()) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; // Not found. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return it - windows_.begin(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WindowCycleList::OnWindowDestroyed(aura::Window* window) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->RemoveObserver(this); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowList::iterator i = std::find(windows_.begin(), windows_.end(), window); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(i != windows_.end()); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int removed_index = static_cast<int>(i - windows_.begin()); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windows_.erase(i); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_index_ > removed_index) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_index_--; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (current_index_ == static_cast<int>(windows_.size())) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_index_--; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 88