| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/wm/overview/window_selector.h" | 5 #include "ash/wm/overview/window_selector.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ash/shell.h" | 9 #include "ash/shell.h" |
| 10 #include "ash/wm/mru_window_tracker.h" | 10 #include "ash/wm/mru_window_tracker.h" |
| 11 #include "ash/wm/overview/window_overview.h" | 11 #include "ash/wm/overview/window_overview.h" |
| 12 #include "ash/wm/overview/window_selector_delegate.h" | 12 #include "ash/wm/overview/window_selector_delegate.h" |
| 13 #include "ash/wm/overview/window_selector_panels.h" |
| 13 #include "ash/wm/overview/window_selector_window.h" | 14 #include "ash/wm/overview/window_selector_window.h" |
| 15 #include "ash/wm/window_settings.h" |
| 14 #include "base/auto_reset.h" | 16 #include "base/auto_reset.h" |
| 15 #include "base/timer/timer.h" | 17 #include "base/timer/timer.h" |
| 16 #include "ui/aura/client/activation_client.h" | 18 #include "ui/aura/client/activation_client.h" |
| 17 #include "ui/aura/client/focus_client.h" | 19 #include "ui/aura/client/focus_client.h" |
| 18 #include "ui/aura/root_window.h" | 20 #include "ui/aura/root_window.h" |
| 19 #include "ui/aura/window.h" | 21 #include "ui/aura/window.h" |
| 20 #include "ui/base/events/event.h" | 22 #include "ui/base/events/event.h" |
| 21 #include "ui/base/events/event_handler.h" | 23 #include "ui/base/events/event_handler.h" |
| 22 | 24 |
| 23 namespace ash { | 25 namespace ash { |
| 24 | 26 |
| 25 namespace { | 27 namespace { |
| 26 | 28 |
| 27 const int kOverviewDelayOnCycleMilliseconds = 300; | 29 const int kOverviewDelayOnCycleMilliseconds = 300; |
| 28 | 30 |
| 29 // A comparator for locating a given target window. | 31 // A comparator for locating a given target window. |
| 30 struct WindowSelectorWindowComparator | 32 struct WindowSelectorItemComparator |
| 31 : public std::unary_function<WindowSelectorWindow*, bool> { | 33 : public std::unary_function<WindowSelectorItem*, bool> { |
| 32 explicit WindowSelectorWindowComparator(const aura::Window* target_window) | 34 explicit WindowSelectorItemComparator(const aura::Window* target_window) |
| 33 : target(target_window) { | 35 : target(target_window) { |
| 34 } | 36 } |
| 35 | 37 |
| 36 bool operator()(const WindowSelectorWindow* window) const { | 38 bool operator()(const WindowSelectorItem* window) const { |
| 37 return target == window->window(); | 39 return window->TargetedWindow(target) != NULL; |
| 38 } | 40 } |
| 39 | 41 |
| 40 const aura::Window* target; | 42 const aura::Window* target; |
| 41 }; | 43 }; |
| 42 | 44 |
| 45 // A comparator for locating a selector item for a given root. |
| 46 struct WindowSelectorItemForRoot |
| 47 : public std::unary_function<WindowSelectorItem*, bool> { |
| 48 explicit WindowSelectorItemForRoot(const aura::RootWindow* root) |
| 49 : root_window(root) { |
| 50 } |
| 51 |
| 52 bool operator()(const WindowSelectorItem* item) const { |
| 53 return item->GetRootWindow() == root_window; |
| 54 } |
| 55 |
| 56 const aura::RootWindow* root_window; |
| 57 }; |
| 58 |
| 43 // Filter to watch for the termination of a keyboard gesture to cycle through | 59 // Filter to watch for the termination of a keyboard gesture to cycle through |
| 44 // multiple windows. | 60 // multiple windows. |
| 45 class WindowSelectorEventFilter : public ui::EventHandler { | 61 class WindowSelectorEventFilter : public ui::EventHandler { |
| 46 public: | 62 public: |
| 47 WindowSelectorEventFilter(WindowSelector* selector); | 63 WindowSelectorEventFilter(WindowSelector* selector); |
| 48 virtual ~WindowSelectorEventFilter(); | 64 virtual ~WindowSelectorEventFilter(); |
| 49 | 65 |
| 50 // Overridden from ui::EventHandler: | 66 // Overridden from ui::EventHandler: |
| 51 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE; | 67 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE; |
| 52 | 68 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 83 WindowSelectorDelegate* delegate) | 99 WindowSelectorDelegate* delegate) |
| 84 : mode_(mode), | 100 : mode_(mode), |
| 85 start_overview_timer_(FROM_HERE, | 101 start_overview_timer_(FROM_HERE, |
| 86 base::TimeDelta::FromMilliseconds(kOverviewDelayOnCycleMilliseconds), | 102 base::TimeDelta::FromMilliseconds(kOverviewDelayOnCycleMilliseconds), |
| 87 this, &WindowSelector::StartOverview), | 103 this, &WindowSelector::StartOverview), |
| 88 delegate_(delegate), | 104 delegate_(delegate), |
| 89 selected_window_(0), | 105 selected_window_(0), |
| 90 restore_focus_window_(NULL), | 106 restore_focus_window_(NULL), |
| 91 restoring_focus_(false) { | 107 restoring_focus_(false) { |
| 92 DCHECK(delegate_); | 108 DCHECK(delegate_); |
| 109 std::vector<WindowSelectorPanels*> panels_items; |
| 110 for (size_t i = 0; i < windows.size(); ++i) { |
| 111 windows[i]->AddObserver(this); |
| 112 observed_windows_.insert(windows[i]); |
| 113 |
| 114 if (windows[i]->type() == aura::client::WINDOW_TYPE_PANEL && |
| 115 wm::GetWindowSettings(windows[i])->panel_attached()) { |
| 116 // Attached panel windows are grouped into a single overview item per |
| 117 // root window (display). |
| 118 std::vector<WindowSelectorPanels*>::iterator iter = |
| 119 std::find_if(panels_items.begin(), panels_items.end(), |
| 120 WindowSelectorItemForRoot(windows[i]->GetRootWindow())); |
| 121 WindowSelectorPanels* panels_item = NULL; |
| 122 if (iter == panels_items.end()) { |
| 123 panels_item = new WindowSelectorPanels(); |
| 124 panels_items.push_back(panels_item); |
| 125 windows_.push_back(panels_item); |
| 126 } else { |
| 127 panels_item = *iter; |
| 128 } |
| 129 panels_item->AddWindow(windows[i]); |
| 130 } else { |
| 131 windows_.push_back(new WindowSelectorWindow(windows[i])); |
| 132 } |
| 133 } |
| 93 RemoveFocusAndSetRestoreWindow(); | 134 RemoveFocusAndSetRestoreWindow(); |
| 94 for (size_t i = 0; i < windows.size(); ++i) { | |
| 95 // restore_focus_window_ is already observed from the call to | |
| 96 // RemoveFocusAndSetRestoreWindow. | |
| 97 if (windows[i] != restore_focus_window_) | |
| 98 windows[i]->AddObserver(this); | |
| 99 windows_.push_back(new WindowSelectorWindow(windows[i])); | |
| 100 } | |
| 101 | 135 |
| 102 // Observe window activations and switchable containers on all root windows | 136 // Observe window activations and switchable containers on all root windows |
| 103 // for newly created windows during overview. | 137 // for newly created windows during overview. |
| 104 Shell::GetInstance()->activation_client()->AddObserver(this); | 138 Shell::GetInstance()->activation_client()->AddObserver(this); |
| 105 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); | 139 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
| 106 for (Shell::RootWindowList::const_iterator iter = root_windows.begin(); | 140 for (Shell::RootWindowList::const_iterator iter = root_windows.begin(); |
| 107 iter != root_windows.end(); ++iter) { | 141 iter != root_windows.end(); ++iter) { |
| 108 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { | 142 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { |
| 109 Shell::GetContainer(*iter, | 143 Shell::GetContainer(*iter, |
| 110 kSwitchableWindowContainerIds[i])->AddObserver(this); | 144 kSwitchableWindowContainerIds[i])->AddObserver(this); |
| 111 } | 145 } |
| 112 } | 146 } |
| 113 | 147 |
| 114 if (mode == WindowSelector::CYCLE) { | 148 if (mode == WindowSelector::CYCLE) { |
| 115 event_handler_.reset(new WindowSelectorEventFilter(this)); | 149 event_handler_.reset(new WindowSelectorEventFilter(this)); |
| 116 start_overview_timer_.Reset(); | 150 start_overview_timer_.Reset(); |
| 117 } else { | 151 } else { |
| 118 StartOverview(); | 152 StartOverview(); |
| 119 } | 153 } |
| 120 } | 154 } |
| 121 | 155 |
| 122 WindowSelector::~WindowSelector() { | 156 WindowSelector::~WindowSelector() { |
| 123 ResetFocusRestoreWindow(true); | 157 ResetFocusRestoreWindow(true); |
| 124 for (size_t i = 0; i < windows_.size(); i++) { | 158 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin(); |
| 125 windows_[i]->window()->RemoveObserver(this); | 159 iter != observed_windows_.end(); ++iter) { |
| 160 (*iter)->RemoveObserver(this); |
| 126 } | 161 } |
| 127 Shell::GetInstance()->activation_client()->RemoveObserver(this); | 162 Shell::GetInstance()->activation_client()->RemoveObserver(this); |
| 128 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); | 163 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
| 129 for (Shell::RootWindowList::const_iterator iter = root_windows.begin(); | 164 for (Shell::RootWindowList::const_iterator iter = root_windows.begin(); |
| 130 iter != root_windows.end(); ++iter) { | 165 iter != root_windows.end(); ++iter) { |
| 131 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { | 166 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { |
| 132 Shell::GetContainer(*iter, | 167 Shell::GetContainer(*iter, |
| 133 kSwitchableWindowContainerIds[i])->RemoveObserver(this); | 168 kSwitchableWindowContainerIds[i])->RemoveObserver(this); |
| 134 } | 169 } |
| 135 } | 170 } |
| 136 } | 171 } |
| 137 | 172 |
| 138 void WindowSelector::Step(WindowSelector::Direction direction) { | 173 void WindowSelector::Step(WindowSelector::Direction direction) { |
| 139 DCHECK_EQ(CYCLE, mode_); | 174 DCHECK_EQ(CYCLE, mode_); |
| 140 DCHECK(!windows_.empty()); | 175 DCHECK(!windows_.empty()); |
| 141 selected_window_ = (selected_window_ + windows_.size() + | 176 selected_window_ = (selected_window_ + windows_.size() + |
| 142 (direction == WindowSelector::FORWARD ? 1 : -1)) % windows_.size(); | 177 (direction == WindowSelector::FORWARD ? 1 : -1)) % windows_.size(); |
| 143 if (window_overview_) { | 178 if (window_overview_) { |
| 144 window_overview_->SetSelection(selected_window_); | 179 window_overview_->SetSelection(selected_window_); |
| 145 } else { | 180 } else { |
| 146 aura::Window* current_window = windows_[selected_window_]->window(); | 181 aura::Window* current_window = |
| 182 windows_[selected_window_]->SelectionWindow(); |
| 147 current_window->Show(); | 183 current_window->Show(); |
| 148 current_window->SetTransform(gfx::Transform()); | 184 current_window->SetTransform(gfx::Transform()); |
| 149 current_window->parent()->StackChildAtTop(current_window); | 185 current_window->parent()->StackChildAtTop(current_window); |
| 150 start_overview_timer_.Reset(); | 186 start_overview_timer_.Reset(); |
| 151 } | 187 } |
| 152 } | 188 } |
| 153 | 189 |
| 154 void WindowSelector::SelectWindow() { | 190 void WindowSelector::SelectWindow() { |
| 155 ResetFocusRestoreWindow(false); | 191 ResetFocusRestoreWindow(false); |
| 156 SelectWindow(windows_[selected_window_]->window()); | 192 SelectWindow(windows_[selected_window_]->SelectionWindow()); |
| 157 } | 193 } |
| 158 | 194 |
| 159 void WindowSelector::SelectWindow(aura::Window* window) { | 195 void WindowSelector::SelectWindow(aura::Window* window) { |
| 160 ScopedVector<WindowSelectorWindow>::iterator iter = | 196 ScopedVector<WindowSelectorItem>::iterator iter = |
| 161 std::find_if(windows_.begin(), windows_.end(), | 197 std::find_if(windows_.begin(), windows_.end(), |
| 162 WindowSelectorWindowComparator(window)); | 198 WindowSelectorItemComparator(window)); |
| 163 DCHECK(iter != windows_.end()); | 199 DCHECK(iter != windows_.end()); |
| 164 // The selected window should not be minimized when window selection is | 200 // The selected window should not be minimized when window selection is |
| 165 // ended. | 201 // ended. |
| 166 (*iter)->RestoreWindowOnExit(); | 202 (*iter)->RestoreWindowOnExit(window); |
| 167 delegate_->OnWindowSelected(window); | 203 delegate_->OnWindowSelected(window); |
| 168 } | 204 } |
| 169 | 205 |
| 170 void WindowSelector::CancelSelection() { | 206 void WindowSelector::CancelSelection() { |
| 171 delegate_->OnSelectionCanceled(); | 207 delegate_->OnSelectionCanceled(); |
| 172 } | 208 } |
| 173 | 209 |
| 174 void WindowSelector::OnWindowAdded(aura::Window* new_window) { | 210 void WindowSelector::OnWindowAdded(aura::Window* new_window) { |
| 175 if (new_window->type() != aura::client::WINDOW_TYPE_NORMAL && | 211 if (new_window->type() != aura::client::WINDOW_TYPE_NORMAL && |
| 176 new_window->type() != aura::client::WINDOW_TYPE_PANEL) { | 212 new_window->type() != aura::client::WINDOW_TYPE_PANEL) { |
| 177 return; | 213 return; |
| 178 } | 214 } |
| 179 | 215 |
| 180 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { | 216 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { |
| 181 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && | 217 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && |
| 182 !new_window->transient_parent()) { | 218 !new_window->transient_parent()) { |
| 183 // The new window is in one of the switchable containers, abort overview. | 219 // The new window is in one of the switchable containers, abort overview. |
| 184 CancelSelection(); | 220 CancelSelection(); |
| 185 return; | 221 return; |
| 186 } | 222 } |
| 187 } | 223 } |
| 188 } | 224 } |
| 189 | 225 |
| 190 void WindowSelector::OnWindowDestroyed(aura::Window* window) { | 226 void WindowSelector::OnWindowDestroyed(aura::Window* window) { |
| 191 ScopedVector<WindowSelectorWindow>::iterator iter = | 227 ScopedVector<WindowSelectorItem>::iterator iter = |
| 192 std::find_if(windows_.begin(), windows_.end(), | 228 std::find_if(windows_.begin(), windows_.end(), |
| 193 WindowSelectorWindowComparator(window)); | 229 WindowSelectorItemComparator(window)); |
| 194 DCHECK(window == restore_focus_window_ || iter != windows_.end()); | 230 DCHECK(window == restore_focus_window_ || iter != windows_.end()); |
| 195 window->RemoveObserver(this); | 231 window->RemoveObserver(this); |
| 196 if (window == restore_focus_window_) | 232 if (window == restore_focus_window_) |
| 197 restore_focus_window_ = NULL; | 233 restore_focus_window_ = NULL; |
| 198 if (iter == windows_.end()) | 234 if (iter == windows_.end()) |
| 199 return; | 235 return; |
| 200 | 236 |
| 237 observed_windows_.erase(window); |
| 238 (*iter)->RemoveWindow(window); |
| 239 // If there are still windows in this selector entry then the overview is |
| 240 // still active and the active selection remains the same. |
| 241 if (!(*iter)->empty()) |
| 242 return; |
| 243 |
| 201 size_t deleted_index = iter - windows_.begin(); | 244 size_t deleted_index = iter - windows_.begin(); |
| 202 (*iter)->OnWindowDestroyed(); | |
| 203 windows_.erase(iter); | 245 windows_.erase(iter); |
| 204 if (windows_.empty()) { | 246 if (windows_.empty()) { |
| 205 CancelSelection(); | 247 CancelSelection(); |
| 206 return; | 248 return; |
| 207 } | 249 } |
| 208 window_overview_->OnWindowsChanged(); | 250 if (window_overview_) |
| 251 window_overview_->OnWindowsChanged(); |
| 209 if (mode_ == CYCLE && selected_window_ >= deleted_index) { | 252 if (mode_ == CYCLE && selected_window_ >= deleted_index) { |
| 210 if (selected_window_ > deleted_index) | 253 if (selected_window_ > deleted_index) |
| 211 selected_window_--; | 254 selected_window_--; |
| 212 selected_window_ = selected_window_ % windows_.size(); | 255 selected_window_ = selected_window_ % windows_.size(); |
| 213 if (window_overview_) | 256 if (window_overview_) |
| 214 window_overview_->SetSelection(selected_window_); | 257 window_overview_->SetSelection(selected_window_); |
| 215 } | 258 } |
| 216 } | 259 } |
| 217 | 260 |
| 218 void WindowSelector::OnWindowActivated(aura::Window* gained_active, | 261 void WindowSelector::OnWindowActivated(aura::Window* gained_active, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 241 window_overview_->SetSelection(selected_window_); | 284 window_overview_->SetSelection(selected_window_); |
| 242 } | 285 } |
| 243 | 286 |
| 244 void WindowSelector::RemoveFocusAndSetRestoreWindow() { | 287 void WindowSelector::RemoveFocusAndSetRestoreWindow() { |
| 245 aura::client::FocusClient* focus_client = aura::client::GetFocusClient( | 288 aura::client::FocusClient* focus_client = aura::client::GetFocusClient( |
| 246 Shell::GetActiveRootWindow()); | 289 Shell::GetActiveRootWindow()); |
| 247 DCHECK(!restore_focus_window_); | 290 DCHECK(!restore_focus_window_); |
| 248 restore_focus_window_ = focus_client->GetFocusedWindow(); | 291 restore_focus_window_ = focus_client->GetFocusedWindow(); |
| 249 if (restore_focus_window_) { | 292 if (restore_focus_window_) { |
| 250 focus_client->FocusWindow(NULL); | 293 focus_client->FocusWindow(NULL); |
| 251 restore_focus_window_->AddObserver(this); | 294 if (observed_windows_.find(restore_focus_window_) == |
| 295 observed_windows_.end()) { |
| 296 restore_focus_window_->AddObserver(this); |
| 297 } |
| 252 } | 298 } |
| 253 } | 299 } |
| 254 | 300 |
| 255 void WindowSelector::ResetFocusRestoreWindow(bool focus) { | 301 void WindowSelector::ResetFocusRestoreWindow(bool focus) { |
| 256 if (!restore_focus_window_) | 302 if (!restore_focus_window_) |
| 257 return; | 303 return; |
| 258 if (focus) { | 304 if (focus) { |
| 259 base::AutoReset<bool> restoring_focus(&restoring_focus_, true); | 305 base::AutoReset<bool> restoring_focus(&restoring_focus_, true); |
| 260 restore_focus_window_->Focus(); | 306 restore_focus_window_->Focus(); |
| 261 } | 307 } |
| 262 // If the window is in the windows_ list it needs to continue to be observed. | 308 // If the window is in the observed_windows_ list it needs to continue to be |
| 263 if (std::find_if(windows_.begin(), windows_.end(), | 309 // observed. |
| 264 WindowSelectorWindowComparator(restore_focus_window_)) == | 310 if (observed_windows_.find(restore_focus_window_) == |
| 265 windows_.end()) { | 311 observed_windows_.end()) { |
| 266 restore_focus_window_->RemoveObserver(this); | 312 restore_focus_window_->RemoveObserver(this); |
| 267 } | 313 } |
| 268 restore_focus_window_ = NULL; | 314 restore_focus_window_ = NULL; |
| 269 } | 315 } |
| 270 | 316 |
| 271 } // namespace ash | 317 } // namespace ash |
| OLD | NEW |