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 <functional> | 8 #include <functional> |
9 #include <set> | 9 #include <set> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "ash/accessibility_delegate.h" | 12 #include "ash/accessibility_delegate.h" |
13 #include "ash/ash_switches.h" | 13 #include "ash/ash_switches.h" |
14 #include "ash/metrics/user_metrics_recorder.h" | 14 #include "ash/metrics/user_metrics_recorder.h" |
15 #include "ash/root_window_controller.h" | 15 #include "ash/root_window_controller.h" |
16 #include "ash/shell.h" | 16 #include "ash/shell.h" |
17 #include "ash/shell_window_ids.h" | 17 #include "ash/shell_window_ids.h" |
18 #include "ash/switchable_windows.h" | 18 #include "ash/switchable_windows.h" |
19 #include "ash/wm/overview/scoped_overview_animation_settings.h" | |
20 #include "ash/wm/overview/scoped_transform_overview_window.h" | |
21 #include "ash/wm/overview/window_grid.h" | 19 #include "ash/wm/overview/window_grid.h" |
22 #include "ash/wm/overview/window_selector_delegate.h" | 20 #include "ash/wm/overview/window_selector_delegate.h" |
23 #include "ash/wm/overview/window_selector_item.h" | 21 #include "ash/wm/overview/window_selector_item.h" |
24 #include "ash/wm/panels/panel_layout_manager.h" | 22 #include "ash/wm/panels/panel_layout_manager.h" |
25 #include "ash/wm/window_state.h" | 23 #include "ash/wm/window_state.h" |
26 #include "base/auto_reset.h" | 24 #include "base/auto_reset.h" |
27 #include "base/command_line.h" | 25 #include "base/command_line.h" |
28 #include "base/metrics/histogram.h" | 26 #include "base/metrics/histogram.h" |
29 #include "third_party/skia/include/core/SkPaint.h" | 27 #include "third_party/skia/include/core/SkPaint.h" |
30 #include "third_party/skia/include/core/SkPath.h" | 28 #include "third_party/skia/include/core/SkPath.h" |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 textfield->RequestFocus(); | 209 textfield->RequestFocus(); |
212 | 210 |
213 return widget; | 211 return widget; |
214 } | 212 } |
215 | 213 |
216 } // namespace | 214 } // namespace |
217 | 215 |
218 const int WindowSelector::kTextFilterBottomEdge = | 216 const int WindowSelector::kTextFilterBottomEdge = |
219 kTextFilterDistanceFromTop + kTextFilterHeight; | 217 kTextFilterDistanceFromTop + kTextFilterHeight; |
220 | 218 |
| 219 // static |
| 220 bool WindowSelector::IsSelectable(aura::Window* window) { |
| 221 wm::WindowState* state = wm::GetWindowState(window); |
| 222 if (state->GetStateType() == wm::WINDOW_STATE_TYPE_DOCKED || |
| 223 state->GetStateType() == wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED) { |
| 224 return false; |
| 225 } |
| 226 return window->type() == ui::wm::WINDOW_TYPE_NORMAL || |
| 227 window->type() == ui::wm::WINDOW_TYPE_PANEL; |
| 228 } |
| 229 |
221 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate) | 230 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate) |
222 : delegate_(delegate), | 231 : delegate_(delegate), |
223 restore_focus_window_(aura::client::GetFocusClient( | 232 restore_focus_window_(aura::client::GetFocusClient( |
224 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), | 233 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), |
225 ignore_activations_(false), | 234 ignore_activations_(false), |
226 selected_grid_index_(0), | 235 selected_grid_index_(0), |
227 overview_start_time_(base::Time::Now()), | 236 overview_start_time_(base::Time::Now()), |
228 num_key_presses_(0), | 237 num_key_presses_(0), |
229 num_items_(0), | 238 num_items_(0), |
230 showing_selection_widget_(false), | 239 showing_selection_widget_(false), |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 | 304 |
296 DCHECK(!grid_list_.empty()); | 305 DCHECK(!grid_list_.empty()); |
297 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); | 306 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); |
298 | 307 |
299 Shell* shell = Shell::GetInstance(); | 308 Shell* shell = Shell::GetInstance(); |
300 | 309 |
301 shell->activation_client()->AddObserver(this); | 310 shell->activation_client()->AddObserver(this); |
302 | 311 |
303 shell->GetScreen()->AddObserver(this); | 312 shell->GetScreen()->AddObserver(this); |
304 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); | 313 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); |
305 HideAndTrackNonOverviewWindows(); | |
306 // Send an a11y alert. | 314 // Send an a11y alert. |
307 shell->accessibility_delegate()->TriggerAccessibilityAlert( | 315 shell->accessibility_delegate()->TriggerAccessibilityAlert( |
308 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); | 316 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); |
309 | 317 |
310 UpdateShelfVisibility(); | 318 UpdateShelfVisibility(); |
311 } | 319 } |
312 | 320 |
313 // NOTE: The work done in Shutdown() is not done in the destructor because it | 321 // NOTE: The work done in Shutdown() is not done in the destructor because it |
314 // may cause other, unrelated classes, (ie PanelLayoutManager) to make indirect | 322 // may cause other, unrelated classes, (ie PanelLayoutManager) to make indirect |
315 // calls to restoring_minimized_windows() on a partially destructed object. | 323 // calls to restoring_minimized_windows() on a partially destructed object. |
316 void WindowSelector::Shutdown() { | 324 void WindowSelector::Shutdown() { |
317 ResetFocusRestoreWindow(true); | 325 ResetFocusRestoreWindow(true); |
318 RemoveAllObservers(); | 326 RemoveAllObservers(); |
319 | 327 |
320 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | 328 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
321 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); | 329 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); |
322 iter != root_windows.end(); iter++) { | 330 iter != root_windows.end(); iter++) { |
323 // Un-hide the callout widgets for panels. It is safe to call this for | 331 // Un-hide the callout widgets for panels. It is safe to call this for |
324 // root_windows that don't contain any panel windows. | 332 // root_windows that don't contain any panel windows. |
325 static_cast<PanelLayoutManager*>( | 333 static_cast<PanelLayoutManager*>( |
326 Shell::GetContainer(*iter, kShellWindowId_PanelContainer) | 334 Shell::GetContainer(*iter, kShellWindowId_PanelContainer) |
327 ->layout_manager())->SetShowCalloutWidgets(true); | 335 ->layout_manager())->SetShowCalloutWidgets(true); |
328 } | 336 } |
329 | 337 |
330 const aura::WindowTracker::Windows hidden_windows(hidden_windows_.windows()); | |
331 for (aura::WindowTracker::Windows::const_iterator iter = | |
332 hidden_windows.begin(); iter != hidden_windows.end(); ++iter) { | |
333 ScopedOverviewAnimationSettings animation_settings( | |
334 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, | |
335 *iter); | |
336 (*iter)->layer()->SetOpacity(1); | |
337 (*iter)->Show(); | |
338 } | |
339 | |
340 size_t remaining_items = 0; | 338 size_t remaining_items = 0; |
341 for (WindowGrid* window_grid : grid_list_) { | 339 for (WindowGrid* window_grid : grid_list_) { |
342 for (WindowSelectorItem* window_selector_item : window_grid->window_list()) | 340 for (WindowSelectorItem* window_selector_item : window_grid->window_list()) |
343 window_selector_item->RestoreWindow(); | 341 window_selector_item->RestoreWindow(); |
344 remaining_items += window_grid->size(); | 342 remaining_items += window_grid->size(); |
345 } | 343 } |
346 | 344 |
347 DCHECK(num_items_ >= remaining_items); | 345 DCHECK(num_items_ >= remaining_items); |
348 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems", | 346 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems", |
349 num_items_ - remaining_items); | 347 num_items_ - remaining_items); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 // TODO(flackr): Keep window selection active on remaining displays. | 447 // TODO(flackr): Keep window selection active on remaining displays. |
450 CancelSelection(); | 448 CancelSelection(); |
451 } | 449 } |
452 | 450 |
453 void WindowSelector::OnDisplayMetricsChanged(const gfx::Display& display, | 451 void WindowSelector::OnDisplayMetricsChanged(const gfx::Display& display, |
454 uint32_t metrics) { | 452 uint32_t metrics) { |
455 PositionWindows(/* animate */ false); | 453 PositionWindows(/* animate */ false); |
456 } | 454 } |
457 | 455 |
458 void WindowSelector::OnWindowAdded(aura::Window* new_window) { | 456 void WindowSelector::OnWindowAdded(aura::Window* new_window) { |
459 if (new_window->type() != ui::wm::WINDOW_TYPE_NORMAL && | 457 if (!IsSelectable(new_window)) |
460 new_window->type() != ui::wm::WINDOW_TYPE_PANEL) { | |
461 return; | 458 return; |
462 } | |
463 | 459 |
464 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { | 460 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { |
465 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && | 461 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && |
466 !::wm::GetTransientParent(new_window)) { | 462 !::wm::GetTransientParent(new_window)) { |
467 // The new window is in one of the switchable containers, abort overview. | 463 // The new window is in one of the switchable containers, abort overview. |
468 CancelSelection(); | 464 CancelSelection(); |
469 return; | 465 return; |
470 } | 466 } |
471 } | 467 } |
472 } | 468 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 Move(WindowSelector::RIGHT, false); | 545 Move(WindowSelector::RIGHT, false); |
550 } | 546 } |
551 | 547 |
552 void WindowSelector::PositionWindows(bool animate) { | 548 void WindowSelector::PositionWindows(bool animate) { |
553 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); | 549 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); |
554 iter != grid_list_.end(); iter++) { | 550 iter != grid_list_.end(); iter++) { |
555 (*iter)->PositionWindows(animate); | 551 (*iter)->PositionWindows(animate); |
556 } | 552 } |
557 } | 553 } |
558 | 554 |
559 void WindowSelector::HideAndTrackNonOverviewWindows() { | |
560 // Add the windows to hidden_windows first so that if any are destroyed | |
561 // while hiding them they are tracked. | |
562 for (ScopedVector<WindowGrid>::iterator grid_iter = grid_list_.begin(); | |
563 grid_iter != grid_list_.end(); ++grid_iter) { | |
564 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { | |
565 const aura::Window* container = | |
566 Shell::GetContainer((*grid_iter)->root_window(), | |
567 kSwitchableWindowContainerIds[i]); | |
568 for (aura::Window::Windows::const_iterator iter = | |
569 container->children().begin(); iter != container->children().end(); | |
570 ++iter) { | |
571 if (!(*iter)->IsVisible() || (*grid_iter)->Contains(*iter)) | |
572 continue; | |
573 hidden_windows_.Add(*iter); | |
574 } | |
575 } | |
576 } | |
577 | |
578 // Copy the window list as it can change during iteration. | |
579 const aura::WindowTracker::Windows hidden_windows(hidden_windows_.windows()); | |
580 for (aura::WindowTracker::Windows::const_iterator iter = | |
581 hidden_windows.begin(); iter != hidden_windows.end(); ++iter) { | |
582 if (!hidden_windows_.Contains(*iter)) | |
583 continue; | |
584 ScopedOverviewAnimationSettings animation_settings( | |
585 OverviewAnimationType::OVERVIEW_ANIMATION_HIDE_WINDOW, | |
586 *iter); | |
587 (*iter)->Hide(); | |
588 // Hiding the window can result in it being destroyed. | |
589 if (!hidden_windows_.Contains(*iter)) | |
590 continue; | |
591 (*iter)->layer()->SetOpacity(0); | |
592 } | |
593 } | |
594 | |
595 void WindowSelector::ResetFocusRestoreWindow(bool focus) { | 555 void WindowSelector::ResetFocusRestoreWindow(bool focus) { |
596 if (!restore_focus_window_) | 556 if (!restore_focus_window_) |
597 return; | 557 return; |
598 if (focus) { | 558 if (focus) { |
599 base::AutoReset<bool> restoring_focus(&ignore_activations_, true); | 559 base::AutoReset<bool> restoring_focus(&ignore_activations_, true); |
600 restore_focus_window_->Focus(); | 560 restore_focus_window_->Focus(); |
601 } | 561 } |
602 // If the window is in the observed_windows_ list it needs to continue to be | 562 // If the window is in the observed_windows_ list it needs to continue to be |
603 // observed. | 563 // observed. |
604 if (observed_windows_.find(restore_focus_window_) == | 564 if (observed_windows_.find(restore_focus_window_) == |
605 observed_windows_.end()) { | 565 observed_windows_.end()) { |
606 restore_focus_window_->RemoveObserver(this); | 566 restore_focus_window_->RemoveObserver(this); |
607 } | 567 } |
608 restore_focus_window_ = nullptr; | 568 restore_focus_window_ = nullptr; |
609 } | 569 } |
610 | 570 |
611 void WindowSelector::Move(Direction direction, bool animate) { | 571 void WindowSelector::Move(Direction direction, bool animate) { |
612 // Keep calling Move() on the grids until one of them reports no overflow or | 572 // Keep calling Move() on the grids until one of them reports no overflow or |
613 // we made a full cycle on all the grids. | 573 // we made a full cycle on all the grids. |
614 for (size_t i = 0; | 574 for (size_t i = 0; |
615 i <= grid_list_.size() && | 575 i <= grid_list_.size() && |
616 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { | 576 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { |
617 // TODO(flackr): If there are more than two monitors, move between grids | 577 // TODO(flackr): If there are more than two monitors, move between grids |
618 // in the requested direction. | 578 // in the requested direction. |
619 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size(); | 579 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size(); |
620 } | 580 } |
621 } | 581 } |
622 | 582 |
623 } // namespace ash | 583 } // namespace ash |
OLD | NEW |