1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file.
4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ash/wm/mru_window_tracker.h"
6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <algorithm>
8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/session/session_state_delegate.h"
10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ash/shell.h"
11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ash/shell_window_ids.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/switchable_windows.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/window_state.h"
14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ash/wm/window_util.h"
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ash/wm/workspace_controller.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_handler.h"
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/activation_client.h"
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace ash {
22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace {
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Adds the windows that can be cycled through for the specified window id to
26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// |windows|.
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AddTrackedWindows(aura::Window* root,
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                       int container_id,
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                       MruWindowTracker::WindowList* windows) {
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  aura::Window* container = Shell::GetContainer(root, container_id);
312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const MruWindowTracker::WindowList& children(container->children());
322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  windows->insert(windows->end(), children.begin(), children.end());
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Adds windows being dragged in the docked container to |windows| list.
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AddDraggedWindows(aura::Window* root,
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       MruWindowTracker::WindowList* windows) {
38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  aura::Window* container =
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Shell::GetContainer(root, kShellWindowId_DockedContainer);
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const MruWindowTracker::WindowList& children = container->children();
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (MruWindowTracker::WindowList::const_iterator iter = children.begin();
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       iter != children.end(); ++iter) {
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (wm::GetWindowState(*iter)->is_dragged())
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      windows->insert(windows->end(), *iter);
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Returns whether |w1| should be considered less recently used than |w2|. This
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// is used for a stable sort to move minimized windows to the LRU end of the
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// list.
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool CompareWindowState(aura::Window* w1, aura::Window* w2) {
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return ash::wm::IsWindowMinimized(w1) && !ash::wm::IsWindowMinimized(w2);
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Returns a list of windows ordered by their stacking order.
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// If |mru_windows| is passed, these windows are moved to the front of the list.
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// If |top_most_at_end|, the list is returned in descending (bottom-most / least
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// recently used) order.
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)MruWindowTracker::WindowList BuildWindowListInternal(
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::list<aura::Window*>* mru_windows,
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    bool top_most_at_end) {
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  MruWindowTracker::WindowList windows;
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* active_root = Shell::GetTargetRootWindow();
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (aura::Window::Windows::const_iterator iter = root_windows.begin();
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)       iter != root_windows.end(); ++iter) {
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (*iter == active_root)
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      continue;
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i)
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      AddTrackedWindows(*iter, kSwitchableWindowContainerIds[i], &windows);
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Add windows in the active root windows last so that the topmost window
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // in the active root window becomes the front of the list.
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i)
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    AddTrackedWindows(active_root, kSwitchableWindowContainerIds[i], &windows);
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Dragged windows are temporarily parented in docked container. Include them
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in the in tracked list.
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddDraggedWindows(active_root, &windows);
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Removes unfocusable windows.
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  MruWindowTracker::WindowList::iterator last =
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      std::remove_if(
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          windows.begin(),
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          windows.end(),
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          std::not1(std::ptr_fun(ash::wm::CanActivateWindow)));
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  windows.erase(last, windows.end());
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Put the windows in the mru_windows list at the head, if it's available.
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (mru_windows) {
93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Iterate through the list backwards, so that we can move each window to
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // the front of the windows list as we find them.
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    for (std::list<aura::Window*>::const_reverse_iterator ix =
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)         mru_windows->rbegin();
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)         ix != mru_windows->rend(); ++ix) {
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // Exclude windows in non-switchable containers and those which cannot
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // be activated.
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (!IsSwitchableContainer((*ix)->parent()) ||
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          !ash::wm::CanActivateWindow(*ix)) {
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        continue;
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      }
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      MruWindowTracker::WindowList::iterator window =
106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          std::find(windows.begin(), windows.end(), *ix);
107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      if (window != windows.end()) {
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        windows.erase(window);
109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        windows.push_back(*ix);
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      }
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Move minimized windows to the beginning (LRU end) of the list.
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::stable_sort(windows.begin(), windows.end(), CompareWindowState);
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Window cycling expects the topmost window at the front of the list.
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!top_most_at_end)
119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::reverse(windows.begin(), windows.end());
120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return windows;
122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace
125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////
127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// MruWindowTracker, public:
128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)MruWindowTracker::MruWindowTracker(
130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    aura::client::ActivationClient* activation_client)
131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : activation_client_(activation_client),
132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ignore_window_activations_(false) {
133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  activation_client_->AddObserver(this);
134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)MruWindowTracker::~MruWindowTracker() {
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (std::list<aura::Window*>::iterator iter = mru_windows_.begin();
13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)       iter != mru_windows_.end(); ++iter) {
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    (*iter)->RemoveObserver(this);
140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  activation_client_->RemoveObserver(this);
143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)MruWindowTracker::WindowList MruWindowTracker::BuildWindowList(
147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    bool top_most_at_end) {
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return BuildWindowListInternal(NULL, top_most_at_end);
149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)MruWindowTracker::WindowList MruWindowTracker::BuildMruWindowList() {
152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return BuildWindowListInternal(&mru_windows_, false);
153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void MruWindowTracker::SetIgnoreActivations(bool ignore) {
156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ignore_window_activations_ = ignore;
157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // If no longer ignoring window activations, move currently active window
159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // to front.
16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!ignore)
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SetActiveWindow(wm::GetActiveWindow());
162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////
165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// MruWindowTracker, private:
166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MruWindowTracker::SetActiveWindow(aura::Window* active_window) {
16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!active_window)
16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::list<aura::Window*>::iterator iter =
17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      std::find(mru_windows_.begin(), mru_windows_.end(), active_window);
17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Observe all newly tracked windows.
17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (iter == mru_windows_.end())
17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    active_window->AddObserver(this);
17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  else
17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    mru_windows_.erase(iter);
17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // TODO(flackr): Remove this check if this doesn't fire for a while. This
17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // should verify that all tracked windows start with a layer, see
18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // http://crbug.com/291354.
18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  CHECK(active_window->layer());
18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  mru_windows_.push_front(active_window);
183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void MruWindowTracker::OnWindowActivated(aura::Window* gained_active,
186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                         aura::Window* lost_active) {
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!ignore_window_activations_)
18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SetActiveWindow(gained_active);
189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
190a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MruWindowTracker::OnWindowDestroyed(aura::Window* window) {
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // It's possible for OnWindowActivated() to be called after
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // OnWindowDestroying(). This means we need to override OnWindowDestroyed()
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // else we may end up with a deleted window in |mru_windows_|.
19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  mru_windows_.remove(window);
196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  window->RemoveObserver(this);
197a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace ash
200