Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: ash/wm/overview/window_selector.cc

Issue 1059903002: Allow Alt-Tab to move the focus to docked windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/wm/overview/window_selector.h ('k') | ash/wm/overview/window_selector_controller.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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)
varkha 2015/04/07 21:45:45 nit: Multi-line condition needs {
oshima 2015/04/07 22:15:03 Done.
224 return false;
varkha 2015/04/07 21:45:45 Just a question: Are you considering to make docke
flackr 2015/04/07 21:48:28 Yes, we should be - http://crbug.com/351329. It wi
225 return window->type() == ui::wm::WINDOW_TYPE_NORMAL ||
226 window->type() == ui::wm::WINDOW_TYPE_PANEL;
227 }
228
221 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate) 229 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate)
222 : delegate_(delegate), 230 : delegate_(delegate),
223 restore_focus_window_(aura::client::GetFocusClient( 231 restore_focus_window_(aura::client::GetFocusClient(
224 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), 232 Shell::GetPrimaryRootWindow())->GetFocusedWindow()),
225 ignore_activations_(false), 233 ignore_activations_(false),
226 selected_grid_index_(0), 234 selected_grid_index_(0),
227 overview_start_time_(base::Time::Now()), 235 overview_start_time_(base::Time::Now()),
228 num_key_presses_(0), 236 num_key_presses_(0),
229 num_items_(0), 237 num_items_(0),
230 showing_selection_widget_(false), 238 showing_selection_widget_(false),
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 303
296 DCHECK(!grid_list_.empty()); 304 DCHECK(!grid_list_.empty());
297 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); 305 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_);
298 306
299 Shell* shell = Shell::GetInstance(); 307 Shell* shell = Shell::GetInstance();
300 308
301 shell->activation_client()->AddObserver(this); 309 shell->activation_client()->AddObserver(this);
302 310
303 shell->GetScreen()->AddObserver(this); 311 shell->GetScreen()->AddObserver(this);
304 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); 312 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW);
305 HideAndTrackNonOverviewWindows();
306 // Send an a11y alert. 313 // Send an a11y alert.
307 shell->accessibility_delegate()->TriggerAccessibilityAlert( 314 shell->accessibility_delegate()->TriggerAccessibilityAlert(
308 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); 315 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED);
309 316
310 UpdateShelfVisibility(); 317 UpdateShelfVisibility();
311 } 318 }
312 319
313 // NOTE: The work done in Shutdown() is not done in the destructor because it 320 // 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 321 // may cause other, unrelated classes, (ie PanelLayoutManager) to make indirect
315 // calls to restoring_minimized_windows() on a partially destructed object. 322 // calls to restoring_minimized_windows() on a partially destructed object.
316 void WindowSelector::Shutdown() { 323 void WindowSelector::Shutdown() {
317 ResetFocusRestoreWindow(true); 324 ResetFocusRestoreWindow(true);
318 RemoveAllObservers(); 325 RemoveAllObservers();
319 326
320 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 327 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
321 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); 328 for (aura::Window::Windows::const_iterator iter = root_windows.begin();
322 iter != root_windows.end(); iter++) { 329 iter != root_windows.end(); iter++) {
323 // Un-hide the callout widgets for panels. It is safe to call this for 330 // Un-hide the callout widgets for panels. It is safe to call this for
324 // root_windows that don't contain any panel windows. 331 // root_windows that don't contain any panel windows.
325 static_cast<PanelLayoutManager*>( 332 static_cast<PanelLayoutManager*>(
326 Shell::GetContainer(*iter, kShellWindowId_PanelContainer) 333 Shell::GetContainer(*iter, kShellWindowId_PanelContainer)
327 ->layout_manager())->SetShowCalloutWidgets(true); 334 ->layout_manager())->SetShowCalloutWidgets(true);
328 } 335 }
329 336
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; 337 size_t remaining_items = 0;
341 for (WindowGrid* window_grid : grid_list_) { 338 for (WindowGrid* window_grid : grid_list_) {
342 for (WindowSelectorItem* window_selector_item : window_grid->window_list()) 339 for (WindowSelectorItem* window_selector_item : window_grid->window_list())
343 window_selector_item->RestoreWindow(); 340 window_selector_item->RestoreWindow();
344 remaining_items += window_grid->size(); 341 remaining_items += window_grid->size();
345 } 342 }
346 343
347 DCHECK(num_items_ >= remaining_items); 344 DCHECK(num_items_ >= remaining_items);
348 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems", 345 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems",
349 num_items_ - remaining_items); 346 num_items_ - remaining_items);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 // TODO(flackr): Keep window selection active on remaining displays. 446 // TODO(flackr): Keep window selection active on remaining displays.
450 CancelSelection(); 447 CancelSelection();
451 } 448 }
452 449
453 void WindowSelector::OnDisplayMetricsChanged(const gfx::Display& display, 450 void WindowSelector::OnDisplayMetricsChanged(const gfx::Display& display,
454 uint32_t metrics) { 451 uint32_t metrics) {
455 PositionWindows(/* animate */ false); 452 PositionWindows(/* animate */ false);
456 } 453 }
457 454
458 void WindowSelector::OnWindowAdded(aura::Window* new_window) { 455 void WindowSelector::OnWindowAdded(aura::Window* new_window) {
459 if (new_window->type() != ui::wm::WINDOW_TYPE_NORMAL && 456 if (!IsSelectable(new_window))
460 new_window->type() != ui::wm::WINDOW_TYPE_PANEL) {
461 return; 457 return;
462 }
463 458
464 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { 459 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) {
465 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && 460 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] &&
466 !::wm::GetTransientParent(new_window)) { 461 !::wm::GetTransientParent(new_window)) {
467 // The new window is in one of the switchable containers, abort overview. 462 // The new window is in one of the switchable containers, abort overview.
468 CancelSelection(); 463 CancelSelection();
469 return; 464 return;
470 } 465 }
471 } 466 }
472 } 467 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 Move(WindowSelector::RIGHT, false); 544 Move(WindowSelector::RIGHT, false);
550 } 545 }
551 546
552 void WindowSelector::PositionWindows(bool animate) { 547 void WindowSelector::PositionWindows(bool animate) {
553 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); 548 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin();
554 iter != grid_list_.end(); iter++) { 549 iter != grid_list_.end(); iter++) {
555 (*iter)->PositionWindows(animate); 550 (*iter)->PositionWindows(animate);
556 } 551 }
557 } 552 }
558 553
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) { 554 void WindowSelector::ResetFocusRestoreWindow(bool focus) {
596 if (!restore_focus_window_) 555 if (!restore_focus_window_)
597 return; 556 return;
598 if (focus) { 557 if (focus) {
599 base::AutoReset<bool> restoring_focus(&ignore_activations_, true); 558 base::AutoReset<bool> restoring_focus(&ignore_activations_, true);
600 restore_focus_window_->Focus(); 559 restore_focus_window_->Focus();
601 } 560 }
602 // If the window is in the observed_windows_ list it needs to continue to be 561 // If the window is in the observed_windows_ list it needs to continue to be
603 // observed. 562 // observed.
604 if (observed_windows_.find(restore_focus_window_) == 563 if (observed_windows_.find(restore_focus_window_) ==
605 observed_windows_.end()) { 564 observed_windows_.end()) {
606 restore_focus_window_->RemoveObserver(this); 565 restore_focus_window_->RemoveObserver(this);
607 } 566 }
608 restore_focus_window_ = nullptr; 567 restore_focus_window_ = nullptr;
609 } 568 }
610 569
611 void WindowSelector::Move(Direction direction, bool animate) { 570 void WindowSelector::Move(Direction direction, bool animate) {
612 // Keep calling Move() on the grids until one of them reports no overflow or 571 // Keep calling Move() on the grids until one of them reports no overflow or
613 // we made a full cycle on all the grids. 572 // we made a full cycle on all the grids.
614 for (size_t i = 0; 573 for (size_t i = 0;
615 i <= grid_list_.size() && 574 i <= grid_list_.size() &&
616 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { 575 grid_list_[selected_grid_index_]->Move(direction, animate); i++) {
617 // TODO(flackr): If there are more than two monitors, move between grids 576 // TODO(flackr): If there are more than two monitors, move between grids
618 // in the requested direction. 577 // in the requested direction.
619 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size(); 578 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size();
620 } 579 }
621 } 580 }
622 581
623 } // namespace ash 582 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/overview/window_selector.h ('k') | ash/wm/overview/window_selector_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698