| 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 #include <set> | 8 #include <set> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 }; | 85 }; |
| 86 | 86 |
| 87 // A comparator for locating a selectable window given a targeted window. | 87 // A comparator for locating a selectable window given a targeted window. |
| 88 struct WindowSelectorItemTargetComparator | 88 struct WindowSelectorItemTargetComparator |
| 89 : public std::unary_function<WindowSelectorItem*, bool> { | 89 : public std::unary_function<WindowSelectorItem*, bool> { |
| 90 explicit WindowSelectorItemTargetComparator(const aura::Window* target_window) | 90 explicit WindowSelectorItemTargetComparator(const aura::Window* target_window) |
| 91 : target(target_window) { | 91 : target(target_window) { |
| 92 } | 92 } |
| 93 | 93 |
| 94 bool operator()(WindowSelectorItem* window) const { | 94 bool operator()(WindowSelectorItem* window) const { |
| 95 return window->Contains(target); | 95 return window->GetWindow() == target; |
| 96 } | 96 } |
| 97 | 97 |
| 98 const aura::Window* target; | 98 const aura::Window* target; |
| 99 }; | 99 }; |
| 100 | 100 |
| 101 // A comparator for locating a selector item for a given root. | 101 // A comparator for locating a selector item for a given root. |
| 102 struct WindowSelectorItemForRoot | 102 struct WindowSelectorItemForRoot |
| 103 : public std::unary_function<WindowSelectorItem*, bool> { | 103 : public std::unary_function<WindowSelectorItem*, bool> { |
| 104 explicit WindowSelectorItemForRoot(const aura::Window* root) | 104 explicit WindowSelectorItemForRoot(const aura::Window* root) |
| 105 : root_window(root) { | 105 : root_window(root) { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 textfield->RequestFocus(); | 210 textfield->RequestFocus(); |
| 211 | 211 |
| 212 return widget; | 212 return widget; |
| 213 } | 213 } |
| 214 | 214 |
| 215 } // namespace | 215 } // namespace |
| 216 | 216 |
| 217 const int WindowSelector::kTextFilterBottomEdge = | 217 const int WindowSelector::kTextFilterBottomEdge = |
| 218 kTextFilterDistanceFromTop + kTextFilterHeight; | 218 kTextFilterDistanceFromTop + kTextFilterHeight; |
| 219 | 219 |
| 220 WindowSelector::WindowSelector(const WindowList& windows, | 220 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate) |
| 221 WindowSelectorDelegate* delegate) | |
| 222 : delegate_(delegate), | 221 : delegate_(delegate), |
| 223 restore_focus_window_(aura::client::GetFocusClient( | 222 restore_focus_window_(aura::client::GetFocusClient( |
| 224 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), | 223 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), |
| 225 ignore_activations_(false), | 224 ignore_activations_(false), |
| 226 selected_grid_index_(0), | 225 selected_grid_index_(0), |
| 227 overview_start_time_(base::Time::Now()), | 226 overview_start_time_(base::Time::Now()), |
| 228 num_key_presses_(0), | 227 num_key_presses_(0), |
| 229 num_items_(0), | 228 num_items_(0), |
| 230 showing_selection_widget_(false), | 229 showing_selection_widget_(false), |
| 231 text_filter_string_length_(0), | 230 text_filter_string_length_(0), |
| 232 num_times_textfield_cleared_(0) { | 231 num_times_textfield_cleared_(0), |
| 232 restoring_minimized_windows_(false) { |
| 233 DCHECK(delegate_); | 233 DCHECK(delegate_); |
| 234 } |
| 235 |
| 236 WindowSelector::~WindowSelector() { |
| 237 } |
| 238 |
| 239 void WindowSelector::Init(const WindowList& windows) { |
| 234 Shell* shell = Shell::GetInstance(); | 240 Shell* shell = Shell::GetInstance(); |
| 235 shell->OnOverviewModeStarting(); | 241 shell->OnOverviewModeStarting(); |
| 236 | 242 |
| 237 if (restore_focus_window_) | 243 if (restore_focus_window_) |
| 238 restore_focus_window_->AddObserver(this); | 244 restore_focus_window_->AddObserver(this); |
| 239 | 245 |
| 240 const aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | 246 const aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
| 241 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); | 247 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); |
| 242 iter != root_windows.end(); iter++) { | 248 iter != root_windows.end(); iter++) { |
| 243 // Observed switchable containers for newly created windows on all root | 249 // Observed switchable containers for newly created windows on all root |
| (...skipping 11 matching lines...) Expand all Loading... |
| 255 Shell::GetContainer(*iter, kShellWindowId_PanelContainer) | 261 Shell::GetContainer(*iter, kShellWindowId_PanelContainer) |
| 256 ->layout_manager())->SetShowCalloutWidgets(false); | 262 ->layout_manager())->SetShowCalloutWidgets(false); |
| 257 | 263 |
| 258 scoped_ptr<WindowGrid> grid(new WindowGrid(*iter, windows, this)); | 264 scoped_ptr<WindowGrid> grid(new WindowGrid(*iter, windows, this)); |
| 259 if (grid->empty()) | 265 if (grid->empty()) |
| 260 continue; | 266 continue; |
| 261 num_items_ += grid->size(); | 267 num_items_ += grid->size(); |
| 262 grid_list_.push_back(grid.release()); | 268 grid_list_.push_back(grid.release()); |
| 263 } | 269 } |
| 264 | 270 |
| 265 // Do not call PrepareForOverview until all items are added to window_list_ as | 271 { |
| 266 // we don't want to cause any window updates until all windows in overview | 272 // The calls to WindowGrid::PrepareForOverview() and CreateTextFilter(...) |
| 267 // are observed. See http://crbug.com/384495. | 273 // requires some LayoutManagers (ie PanelLayoutManager) to perform layouts |
| 268 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); | 274 // so that windows are correctly visible and properly animated in overview |
| 269 iter != grid_list_.end(); ++iter) { | 275 // mode. Otherwise these layouts should be suppressed during overview mode |
| 270 (*iter)->PrepareForOverview(); | 276 // so they don't conflict with overview mode animations. The |
| 271 (*iter)->PositionWindows(true); | 277 // |restoring_minimized_windows_| flag enables the PanelLayoutManager to |
| 278 // make this decision. |
| 279 base::AutoReset<bool> auto_restoring_minimized_windows_( |
| 280 &restoring_minimized_windows_, true); |
| 281 |
| 282 // Do not call PrepareForOverview until all items are added to window_list_ |
| 283 // as we don't want to cause any window updates until all windows in |
| 284 // overview are observed. See http://crbug.com/384495. |
| 285 for (auto window_grid : grid_list_) { |
| 286 window_grid->PrepareForOverview(); |
| 287 window_grid->PositionWindows(true); |
| 288 } |
| 289 |
| 290 text_filter_widget_.reset( |
| 291 CreateTextFilter(this, Shell::GetPrimaryRootWindow())); |
| 272 } | 292 } |
| 273 | 293 |
| 274 DCHECK(!grid_list_.empty()); | 294 DCHECK(!grid_list_.empty()); |
| 275 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); | 295 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); |
| 276 | 296 |
| 277 text_filter_widget_.reset( | |
| 278 CreateTextFilter(this, Shell::GetPrimaryRootWindow())); | |
| 279 | |
| 280 shell->activation_client()->AddObserver(this); | 297 shell->activation_client()->AddObserver(this); |
| 281 | 298 |
| 282 shell->GetScreen()->AddObserver(this); | 299 shell->GetScreen()->AddObserver(this); |
| 283 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); | 300 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); |
| 284 HideAndTrackNonOverviewWindows(); | 301 HideAndTrackNonOverviewWindows(); |
| 285 // Send an a11y alert. | 302 // Send an a11y alert. |
| 286 shell->accessibility_delegate()->TriggerAccessibilityAlert( | 303 shell->accessibility_delegate()->TriggerAccessibilityAlert( |
| 287 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); | 304 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); |
| 288 | 305 |
| 289 UpdateShelfVisibility(); | 306 UpdateShelfVisibility(); |
| 290 } | 307 } |
| 291 | 308 |
| 292 WindowSelector::~WindowSelector() { | 309 void WindowSelector::Shutdown() { |
| 293 Shell* shell = Shell::GetInstance(); | 310 Shell* shell = Shell::GetInstance(); |
| 294 | 311 |
| 295 ResetFocusRestoreWindow(true); | 312 ResetFocusRestoreWindow(true); |
| 296 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin(); | 313 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin(); |
| 297 iter != observed_windows_.end(); ++iter) { | 314 iter != observed_windows_.end(); ++iter) { |
| 298 (*iter)->RemoveObserver(this); | 315 (*iter)->RemoveObserver(this); |
| 299 } | 316 } |
| 300 shell->activation_client()->RemoveObserver(this); | 317 shell->activation_client()->RemoveObserver(this); |
| 301 | 318 |
| 302 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | 319 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 315 ScopedOverviewAnimationSettings animation_settings( | 332 ScopedOverviewAnimationSettings animation_settings( |
| 316 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, | 333 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, |
| 317 *iter); | 334 *iter); |
| 318 (*iter)->layer()->SetOpacity(1); | 335 (*iter)->layer()->SetOpacity(1); |
| 319 (*iter)->Show(); | 336 (*iter)->Show(); |
| 320 } | 337 } |
| 321 | 338 |
| 322 shell->GetScreen()->RemoveObserver(this); | 339 shell->GetScreen()->RemoveObserver(this); |
| 323 | 340 |
| 324 size_t remaining_items = 0; | 341 size_t remaining_items = 0; |
| 325 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); | 342 for (auto window_grid : grid_list_) { |
| 326 iter != grid_list_.end(); iter++) { | 343 for (auto window_selector_item : window_grid->window_list()) |
| 327 remaining_items += (*iter)->size(); | 344 window_selector_item->RestoreWindow(); |
| 345 remaining_items += window_grid->size(); |
| 328 } | 346 } |
| 329 | 347 |
| 330 DCHECK(num_items_ >= remaining_items); | 348 DCHECK(num_items_ >= remaining_items); |
| 331 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems", | 349 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems", |
| 332 num_items_ - remaining_items); | 350 num_items_ - remaining_items); |
| 333 UMA_HISTOGRAM_MEDIUM_TIMES("Ash.WindowSelector.TimeInOverview", | 351 UMA_HISTOGRAM_MEDIUM_TIMES("Ash.WindowSelector.TimeInOverview", |
| 334 base::Time::Now() - overview_start_time_); | 352 base::Time::Now() - overview_start_time_); |
| 335 | 353 |
| 336 // Record metrics related to text filtering. | 354 // Record metrics related to text filtering. |
| 337 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.TextFilteringStringLength", | 355 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.TextFilteringStringLength", |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 if (!grid_list_[selected_grid_index_]->is_selecting()) | 420 if (!grid_list_[selected_grid_index_]->is_selecting()) |
| 403 return false; | 421 return false; |
| 404 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.ArrowKeyPresses", | 422 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.ArrowKeyPresses", |
| 405 num_key_presses_); | 423 num_key_presses_); |
| 406 UMA_HISTOGRAM_CUSTOM_COUNTS( | 424 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 407 "Ash.WindowSelector.KeyPressesOverItemsRatio", | 425 "Ash.WindowSelector.KeyPressesOverItemsRatio", |
| 408 (num_key_presses_ * 100) / num_items_, 1, 300, 30); | 426 (num_key_presses_ * 100) / num_items_, 1, 300, 30); |
| 409 Shell::GetInstance()->metrics()->RecordUserMetricsAction( | 427 Shell::GetInstance()->metrics()->RecordUserMetricsAction( |
| 410 UMA_WINDOW_OVERVIEW_ENTER_KEY); | 428 UMA_WINDOW_OVERVIEW_ENTER_KEY); |
| 411 wm::GetWindowState(grid_list_[selected_grid_index_]-> | 429 wm::GetWindowState(grid_list_[selected_grid_index_]-> |
| 412 SelectedWindow()->SelectionWindow())->Activate(); | 430 SelectedWindow()->GetWindow())->Activate(); |
| 413 break; | 431 break; |
| 414 default: | 432 default: |
| 415 // Not a key we are interested in, allow the textfield to handle it. | 433 // Not a key we are interested in, allow the textfield to handle it. |
| 416 return false; | 434 return false; |
| 417 } | 435 } |
| 418 return true; | 436 return true; |
| 419 } | 437 } |
| 420 | 438 |
| 421 void WindowSelector::OnDisplayAdded(const gfx::Display& display) { | 439 void WindowSelector::OnDisplayAdded(const gfx::Display& display) { |
| 422 } | 440 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 RootWindowGridComparator(gained_active->GetRootWindow())); | 485 RootWindowGridComparator(gained_active->GetRootWindow())); |
| 468 if (grid == grid_list_.end()) | 486 if (grid == grid_list_.end()) |
| 469 return; | 487 return; |
| 470 const std::vector<WindowSelectorItem*> windows = (*grid)->window_list(); | 488 const std::vector<WindowSelectorItem*> windows = (*grid)->window_list(); |
| 471 | 489 |
| 472 ScopedVector<WindowSelectorItem>::const_iterator iter = std::find_if( | 490 ScopedVector<WindowSelectorItem>::const_iterator iter = std::find_if( |
| 473 windows.begin(), windows.end(), | 491 windows.begin(), windows.end(), |
| 474 WindowSelectorItemTargetComparator(gained_active)); | 492 WindowSelectorItemTargetComparator(gained_active)); |
| 475 | 493 |
| 476 if (iter != windows.end()) | 494 if (iter != windows.end()) |
| 477 (*iter)->RestoreWindowOnExit(gained_active); | 495 (*iter)->ShowWindowOnExit(); |
| 478 | 496 |
| 479 // Don't restore focus on exit if a window was just activated. | 497 // Don't restore focus on exit if a window was just activated. |
| 480 ResetFocusRestoreWindow(false); | 498 ResetFocusRestoreWindow(false); |
| 481 CancelSelection(); | 499 CancelSelection(); |
| 482 } | 500 } |
| 483 | 501 |
| 484 void WindowSelector::OnAttemptToReactivateWindow(aura::Window* request_active, | 502 void WindowSelector::OnAttemptToReactivateWindow(aura::Window* request_active, |
| 485 aura::Window* actual_active) { | 503 aura::Window* actual_active) { |
| 486 OnWindowActivated(request_active, actual_active); | 504 OnWindowActivated(request_active, actual_active); |
| 487 } | 505 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 for (size_t i = 0; | 613 for (size_t i = 0; |
| 596 i <= grid_list_.size() && | 614 i <= grid_list_.size() && |
| 597 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { | 615 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { |
| 598 // TODO(flackr): If there are more than two monitors, move between grids | 616 // TODO(flackr): If there are more than two monitors, move between grids |
| 599 // in the requested direction. | 617 // in the requested direction. |
| 600 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size(); | 618 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size(); |
| 601 } | 619 } |
| 602 } | 620 } |
| 603 | 621 |
| 604 } // namespace ash | 622 } // namespace ash |
| OLD | NEW |