1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/maximize_mode/maximize_mode_window_manager.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/root_window_controller.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/shell.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/shell_window_ids.h"
1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/wm/maximize_mode/maximize_mode_window_state.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/maximize_mode/workspace_backdrop_delegate.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/mru_window_tracker.h"
1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/wm/overview/window_selector_controller.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/wm/window_state.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/wm/window_util.h"
16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/wm/wm_event.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/workspace_controller.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gfx/screen.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ash {
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace {
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// The height of the area in which a touch operation leads to exiting the
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// full screen mode.
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kLeaveFullScreenAreaHeightInPixel = 2;
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Exits overview mode if it is currently active.
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CancelOverview() {
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  WindowSelectorController* controller =
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      Shell::GetInstance()->window_selector_controller();
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (controller && controller->IsSelecting())
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    controller->OnSelectionEnded();
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MaximizeModeWindowManager::~MaximizeModeWindowManager() {
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Overview mode needs to be ended before exiting maximize mode to prevent
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // transforming windows which are currently in
425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // overview: http://crbug.com/366605
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CancelOverview();
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Shell::GetInstance()->RemovePreTargetHandler(this);
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Shell::GetInstance()->RemoveShellObserver(this);
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Shell::GetScreen()->RemoveObserver(this);
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EnableBackdropBehindTopWindowOnEachDisplay(false);
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RemoveWindowCreationObservers();
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RestoreAllWindows();
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int MaximizeModeWindowManager::GetNumberOfManagedWindows() {
5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return window_state_map_.size();
5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void MaximizeModeWindowManager::AddWindow(aura::Window* window) {
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Only add the window if it is a direct dependent of a container window
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // and not yet tracked.
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!ShouldHandleWindow(window) ||
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      window_state_map_.find(window) != window_state_map_.end() ||
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      !IsContainerWindow(window->parent())) {
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  MaximizeAndTrackWindow(window);
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void MaximizeModeWindowManager::WindowStateDestroyed(aura::Window* window) {
7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // At this time ForgetWindow() should already have been called. If not,
7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // someone else must have replaced the "window manager's state object".
7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(!window->HasObserver(this));
7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  WindowToState::iterator it = window_state_map_.find(window);
7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(it != window_state_map_.end());
7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  window_state_map_.erase(it);
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid MaximizeModeWindowManager::OnOverviewModeStarting() {
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (backdrops_hidden_)
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EnableBackdropBehindTopWindowOnEachDisplay(false);
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  backdrops_hidden_ = true;
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid MaximizeModeWindowManager::OnOverviewModeEnding() {
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!backdrops_hidden_)
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  backdrops_hidden_ = false;
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EnableBackdropBehindTopWindowOnEachDisplay(true);
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MaximizeModeWindowManager::OnWindowDestroying(aura::Window* window) {
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // If a known window gets destroyed we need to remove all knowledge about it.
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!IsContainerWindow(window))
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ForgetWindow(window);
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid MaximizeModeWindowManager::OnWindowAdded(aura::Window* window) {
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // A window can get removed and then re-added by a drag and drop operation.
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (IsContainerWindow(window->parent()) &&
104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      window_state_map_.find(window) == window_state_map_.end()) {
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MaximizeAndTrackWindow(window);
106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // When the state got added, the "WM_EVENT_ADDED_TO_WORKSPACE" event got
107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // already sent and we have to notify our state again.
108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (window_state_map_.find(window) != window_state_map_.end()) {
109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      wm::WMEvent event(wm::WM_EVENT_ADDED_TO_WORKSPACE);
110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      wm::GetWindowState(window)->OnWMEvent(&event);
111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    }
112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MaximizeModeWindowManager::OnWindowBoundsChanged(
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    aura::Window* window,
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const gfx::Rect& old_bounds,
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const gfx::Rect& new_bounds) {
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!IsContainerWindow(window))
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Reposition all non maximizeable windows.
12223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  for (WindowToState::iterator it = window_state_map_.begin();
12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)       it != window_state_map_.end();
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    it->second->UpdateWindowPosition(wm::GetWindowState(it->first), false);
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MaximizeModeWindowManager::OnDisplayAdded(const gfx::Display& display) {
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DisplayConfigurationChanged();
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MaximizeModeWindowManager::OnDisplayRemoved(const gfx::Display& display) {
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DisplayConfigurationChanged();
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void MaximizeModeWindowManager::OnDisplayMetricsChanged(const gfx::Display&,
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                        uint32_t) {
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Nothing to do here.
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void MaximizeModeWindowManager::OnTouchEvent(ui::TouchEvent* event) {
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (event->type() != ui::ET_TOUCH_PRESSED)
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Find the active window (from the primary screen) to un-fullscreen.
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window* window = wm::GetActiveWindow();
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!window)
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window);
15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!window_state->IsFullscreen() || window_state->in_immersive_fullscreen())
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Test that the touch happened in the top or bottom lines.
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int y = event->y();
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (y >= kLeaveFullScreenAreaHeightInPixel &&
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      y < (window->bounds().height() - kLeaveFullScreenAreaHeightInPixel)) {
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Leave full screen mode.
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  event->StopPropagation();
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  wm::WMEvent toggle_fullscreen(wm::WM_EVENT_TOGGLE_FULLSCREEN);
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  window_state->OnWMEvent(&toggle_fullscreen);
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MaximizeModeWindowManager::MaximizeModeWindowManager()
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      : backdrops_hidden_(false) {
17023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // The overview mode needs to be ended before the maximize mode is started. To
17123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // guarantee the proper order, it will be turned off from here.
1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CancelOverview();
17323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MaximizeAllWindows();
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AddWindowCreationObservers();
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EnableBackdropBehindTopWindowOnEachDisplay(true);
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Shell::GetScreen()->AddObserver(this);
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Shell::GetInstance()->AddShellObserver(this);
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Shell::GetInstance()->AddPreTargetHandler(this);
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MaximizeModeWindowManager::MaximizeAllWindows() {
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MruWindowTracker::WindowList windows =
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      MruWindowTracker::BuildWindowList(false);
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Add all existing Mru windows.
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (MruWindowTracker::WindowList::iterator window = windows.begin();
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      window != windows.end(); ++window) {
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MaximizeAndTrackWindow(*window);
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MaximizeModeWindowManager::RestoreAllWindows() {
19323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  while (window_state_map_.size())
19423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ForgetWindow(window_state_map_.begin()->first);
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MaximizeModeWindowManager::MaximizeAndTrackWindow(
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    aura::Window* window) {
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!ShouldHandleWindow(window))
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(window_state_map_.find(window) == window_state_map_.end());
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window->AddObserver(this);
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
20523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // We create and remember a maximize mode state which will attach itself to
20623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // the provided state object.
20723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  window_state_map_[window] = new MaximizeModeWindowState(window, this);
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void MaximizeModeWindowManager::ForgetWindow(aura::Window* window) {
21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  WindowToState::iterator it = window_state_map_.find(window);
21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // The following DCHECK could fail if our window state object was destroyed
21423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // earlier by someone else. However - at this point there is no other client
21523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // which replaces the state object and therefore this should not happen.
21623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(it != window_state_map_.end());
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window->RemoveObserver(this);
21823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
21923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // By telling the state object to revert, it will switch back the old
22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // State object and destroy itself, calling WindowStateDerstroyed().
22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  it->second->LeaveMaximizeMode(wm::GetWindowState(it->first));
22223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(window_state_map_.find(window) == window_state_map_.end());
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool MaximizeModeWindowManager::ShouldHandleWindow(aura::Window* window) {
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(window);
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return window->type() == ui::wm::WINDOW_TYPE_NORMAL;
228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MaximizeModeWindowManager::AddWindowCreationObservers() {
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(observed_container_windows_.empty());
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Observe window activations/creations in the default containers on all root
233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // windows.
234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (aura::Window::Windows::const_iterator iter = root_windows.begin();
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       iter != root_windows.end(); ++iter) {
237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    aura::Window* container =
238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        Shell::GetContainer(*iter, kShellWindowId_DefaultContainer);
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(observed_container_windows_.find(container) ==
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              observed_container_windows_.end());
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    container->AddObserver(this);
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    observed_container_windows_.insert(container);
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MaximizeModeWindowManager::RemoveWindowCreationObservers() {
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (std::set<aura::Window*>::iterator iter =
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           observed_container_windows_.begin();
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       iter != observed_container_windows_.end(); ++iter) {
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    (*iter)->RemoveObserver(this);
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  observed_container_windows_.clear();
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MaximizeModeWindowManager::DisplayConfigurationChanged() {
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EnableBackdropBehindTopWindowOnEachDisplay(false);
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RemoveWindowCreationObservers();
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AddWindowCreationObservers();
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EnableBackdropBehindTopWindowOnEachDisplay(true);
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool MaximizeModeWindowManager::IsContainerWindow(aura::Window* window) {
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return observed_container_windows_.find(window) !=
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             observed_container_windows_.end();
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MaximizeModeWindowManager::EnableBackdropBehindTopWindowOnEachDisplay(
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool enable) {
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (backdrops_hidden_)
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Inform the WorkspaceLayoutManager that we want to show a backdrop behind
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the topmost window of its container.
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Shell::RootWindowControllerList controllers =
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      Shell::GetAllRootWindowControllers();
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (Shell::RootWindowControllerList::iterator iter = controllers.begin();
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       iter != controllers.end(); ++iter) {
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RootWindowController* controller = *iter;
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    aura::Window* container = Shell::GetContainer(
279a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        controller->GetRootWindow(), kShellWindowId_DefaultContainer);
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    controller->workspace_controller()->SetMaximizeBackdropDelegate(
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        scoped_ptr<WorkspaceLayoutManagerDelegate>(
282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            enable ? new WorkspaceBackdropDelegate(container) : NULL));
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace ash
287