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

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

Issue 251103005: Added arrow key navigation to Overview Mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added reposition animation, shortened movement time, fixed what Terry commented. Created 6 years, 6 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
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 8
9 #include "ash/accessibility_delegate.h" 9 #include "ash/accessibility_delegate.h"
10 #include "ash/ash_switches.h" 10 #include "ash/ash_switches.h"
11 #include "ash/metrics/user_metrics_recorder.h" 11 #include "ash/metrics/user_metrics_recorder.h"
12 #include "ash/root_window_controller.h" 12 #include "ash/root_window_controller.h"
13 #include "ash/screen_util.h"
14 #include "ash/shell.h" 13 #include "ash/shell.h"
15 #include "ash/shell_window_ids.h" 14 #include "ash/shell_window_ids.h"
16 #include "ash/switchable_windows.h" 15 #include "ash/switchable_windows.h"
17 #include "ash/wm/overview/scoped_transform_overview_window.h" 16 #include "ash/wm/overview/scoped_transform_overview_window.h"
17 #include "ash/wm/overview/window_grid.h"
18 #include "ash/wm/overview/window_selector_delegate.h" 18 #include "ash/wm/overview/window_selector_delegate.h"
19 #include "ash/wm/overview/window_selector_item.h" 19 #include "ash/wm/overview/window_selector_item.h"
20 #include "ash/wm/overview/window_selector_panels.h" 20 #include "ash/wm/overview/window_selector_panels.h"
21 #include "ash/wm/overview/window_selector_window.h" 21 #include "ash/wm/overview/window_selector_window.h"
22 #include "ash/wm/window_state.h" 22 #include "ash/wm/window_state.h"
23 #include "base/auto_reset.h" 23 #include "base/auto_reset.h"
24 #include "base/command_line.h" 24 #include "base/command_line.h"
25 #include "base/metrics/histogram.h" 25 #include "base/metrics/histogram.h"
26 #include "base/strings/string_number_conversions.h" 26 #include "base/strings/string_number_conversions.h"
27 #include "third_party/skia/include/core/SkColor.h" 27 #include "third_party/skia/include/core/SkColor.h"
28 #include "ui/aura/client/cursor_client.h" 28 #include "ui/aura/client/cursor_client.h"
29 #include "ui/aura/client/focus_client.h" 29 #include "ui/aura/client/focus_client.h"
30 #include "ui/aura/window.h" 30 #include "ui/aura/window.h"
31 #include "ui/aura/window_event_dispatcher.h" 31 #include "ui/aura/window_event_dispatcher.h"
32 #include "ui/aura/window_observer.h" 32 #include "ui/aura/window_observer.h"
33 #include "ui/compositor/layer_animation_observer.h"
34 #include "ui/compositor/scoped_layer_animation_settings.h" 33 #include "ui/compositor/scoped_layer_animation_settings.h"
35 #include "ui/events/event.h" 34 #include "ui/events/event.h"
36 #include "ui/gfx/screen.h" 35 #include "ui/gfx/screen.h"
37 #include "ui/views/background.h" 36 #include "ui/views/background.h"
38 #include "ui/views/widget/widget.h" 37 #include "ui/views/widget/widget.h"
39 #include "ui/wm/core/window_util.h" 38 #include "ui/wm/core/window_util.h"
40 #include "ui/wm/public/activation_client.h" 39 #include "ui/wm/public/activation_client.h"
41 40
42 namespace ash { 41 namespace ash {
43 42
44 namespace { 43 namespace {
45 44
46 // Conceptually the window overview is a table or grid of cells having this 45 // A comparator for locating a grid with a given root window.
47 // fixed aspect ratio. The number of columns is determined by maximizing the 46 struct RootWindowGridComparator
48 // area of them based on the number of windows. 47 : public std::unary_function<WindowGrid*, bool> {
49 const float kCardAspectRatio = 4.0f / 3.0f; 48 explicit RootWindowGridComparator(const aura::Window* root_window)
50 49 : root_window_(root_window) {
51 // In the conceptual overview table, the window margin is the space reserved
52 // around the window within the cell. This margin does not overlap so the
53 // closest distance between adjacent windows will be twice this amount.
54 const int kWindowMargin = 30;
55
56 // The minimum number of cards along the major axis (i.e. horizontally on a
57 // landscape orientation).
58 const int kMinCardsMajor = 3;
59
60 // A comparator for locating a given target window.
61 struct WindowSelectorItemComparator
62 : public std::unary_function<WindowSelectorItem*, bool> {
63 explicit WindowSelectorItemComparator(const aura::Window* target_window)
64 : target(target_window) {
65 } 50 }
66 51
67 bool operator()(WindowSelectorItem* window) const { 52 bool operator()(WindowGrid* grid) const {
68 return window->HasSelectableWindow(target); 53 return (grid->root_window() == root_window_);
69 } 54 }
70 55
71 const aura::Window* target; 56 const aura::Window* root_window_;
72 }; 57 };
73 58
74 // An observer which holds onto the passed widget until the animation is
75 // complete.
76 class CleanupWidgetAfterAnimationObserver : public ui::LayerAnimationObserver {
77 public:
78 explicit CleanupWidgetAfterAnimationObserver(
79 scoped_ptr<views::Widget> widget);
80
81 // ui::LayerAnimationObserver:
82 virtual void OnLayerAnimationEnded(
83 ui::LayerAnimationSequence* sequence) OVERRIDE;
84 virtual void OnLayerAnimationAborted(
85 ui::LayerAnimationSequence* sequence) OVERRIDE;
86 virtual void OnLayerAnimationScheduled(
87 ui::LayerAnimationSequence* sequence) OVERRIDE;
88
89 private:
90 virtual ~CleanupWidgetAfterAnimationObserver();
91
92 scoped_ptr<views::Widget> widget_;
93
94 DISALLOW_COPY_AND_ASSIGN(CleanupWidgetAfterAnimationObserver);
95 };
96
97 CleanupWidgetAfterAnimationObserver::CleanupWidgetAfterAnimationObserver(
98 scoped_ptr<views::Widget> widget)
99 : widget_(widget.Pass()) {
100 widget_->GetNativeWindow()->layer()->GetAnimator()->AddObserver(this);
101 }
102
103 CleanupWidgetAfterAnimationObserver::~CleanupWidgetAfterAnimationObserver() {
104 widget_->GetNativeWindow()->layer()->GetAnimator()->RemoveObserver(this);
105 }
106
107 void CleanupWidgetAfterAnimationObserver::OnLayerAnimationEnded(
108 ui::LayerAnimationSequence* sequence) {
109 delete this;
110 }
111
112 void CleanupWidgetAfterAnimationObserver::OnLayerAnimationAborted(
113 ui::LayerAnimationSequence* sequence) {
114 delete this;
115 }
116
117 void CleanupWidgetAfterAnimationObserver::OnLayerAnimationScheduled(
118 ui::LayerAnimationSequence* sequence) {
119 }
120
121 // A comparator for locating a selectable window given a targeted window. 59 // A comparator for locating a selectable window given a targeted window.
122 struct WindowSelectorItemTargetComparator 60 struct WindowSelectorItemTargetComparator
123 : public std::unary_function<WindowSelectorItem*, bool> { 61 : public std::unary_function<WindowSelectorItem*, bool> {
124 explicit WindowSelectorItemTargetComparator(const aura::Window* target_window) 62 explicit WindowSelectorItemTargetComparator(const aura::Window* target_window)
125 : target(target_window) { 63 : target(target_window) {
126 } 64 }
127 65
128 bool operator()(WindowSelectorItem* window) const { 66 bool operator()(WindowSelectorItem* window) const {
129 return window->TargetedWindow(target) != NULL; 67 return window->TargetedWindow(target) != NULL;
130 } 68 }
(...skipping 26 matching lines...) Expand all
157 } 95 }
158 } 96 }
159 97
160 } // namespace 98 } // namespace
161 99
162 WindowSelector::WindowSelector(const WindowList& windows, 100 WindowSelector::WindowSelector(const WindowList& windows,
163 WindowSelectorDelegate* delegate) 101 WindowSelectorDelegate* delegate)
164 : delegate_(delegate), 102 : delegate_(delegate),
165 restore_focus_window_(aura::client::GetFocusClient( 103 restore_focus_window_(aura::client::GetFocusClient(
166 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), 104 Shell::GetPrimaryRootWindow())->GetFocusedWindow()),
167 ignore_activations_(false) { 105 ignore_activations_(false),
106 root_index_(0) {
168 DCHECK(delegate_); 107 DCHECK(delegate_);
169 108
170 if (restore_focus_window_) 109 if (restore_focus_window_)
171 restore_focus_window_->AddObserver(this); 110 restore_focus_window_->AddObserver(this);
172 111
173 std::vector<WindowSelectorPanels*> panels_items; 112 std::vector<WindowSelectorPanels*> panels_items;
174 for (size_t i = 0; i < windows.size(); ++i) { 113 for (size_t i = 0; i < windows.size(); ++i) {
175 WindowSelectorItem* item = NULL; 114 WindowSelectorItem* item = NULL;
176 if (windows[i] != restore_focus_window_) 115 if (windows[i] != restore_focus_window_)
177 windows[i]->AddObserver(this); 116 windows[i]->AddObserver(this);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 void WindowSelector::CancelSelection() { 215 void WindowSelector::CancelSelection() {
277 delegate_->OnSelectionCanceled(); 216 delegate_->OnSelectionCanceled();
278 } 217 }
279 218
280 void WindowSelector::OnKeyEvent(ui::KeyEvent* event) { 219 void WindowSelector::OnKeyEvent(ui::KeyEvent* event) {
281 if (GetTargetedWindow(static_cast<aura::Window*>(event->target()))) 220 if (GetTargetedWindow(static_cast<aura::Window*>(event->target())))
282 event->StopPropagation(); 221 event->StopPropagation();
283 if (event->type() != ui::ET_KEY_PRESSED) 222 if (event->type() != ui::ET_KEY_PRESSED)
284 return; 223 return;
285 224
286 if (event->key_code() == ui::VKEY_ESCAPE) 225 switch (event->key_code()) {
287 CancelSelection(); 226 case ui::VKEY_ESCAPE:
227 CancelSelection();
228 break;
229 case ui::VKEY_UP:
230 Move(WindowSelector::UP);
flackr 2014/05/29 20:04:25 I think any of these handled events should set han
Nina 2014/06/02 22:04:38 Done.
231 break;
232 case ui::VKEY_DOWN:
233 Move(WindowSelector::DOWN);
234 break;
235 case ui::VKEY_RIGHT:
236 Move(WindowSelector::RIGHT);
237 break;
238 case ui::VKEY_LEFT:
239 Move(WindowSelector::LEFT);
240 break;
241 case ui::VKEY_RETURN:
242 SelectWindow(
243 grid_list_[root_index_]->SelectedWindow()->SelectionWindow());
244 break;
245 default:
246 // Not a key we are interested in.
247 break;
248 }
288 } 249 }
289 250
290 void WindowSelector::OnMouseEvent(ui::MouseEvent* event) { 251 void WindowSelector::OnMouseEvent(ui::MouseEvent* event) {
291 aura::Window* target = GetEventTarget(event); 252 aura::Window* target = GetEventTarget(event);
292 if (!target) 253 if (!target)
293 return; 254 return;
294 255
295 event->SetHandled(); 256 event->SetHandled();
296 if (event->type() != ui::ET_MOUSE_RELEASED) 257 if (event->type() != ui::ET_MOUSE_RELEASED)
297 return; 258 return;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && 307 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] &&
347 !::wm::GetTransientParent(new_window)) { 308 !::wm::GetTransientParent(new_window)) {
348 // The new window is in one of the switchable containers, abort overview. 309 // The new window is in one of the switchable containers, abort overview.
349 CancelSelection(); 310 CancelSelection();
350 return; 311 return;
351 } 312 }
352 } 313 }
353 } 314 }
354 315
355 void WindowSelector::OnWindowDestroying(aura::Window* window) { 316 void WindowSelector::OnWindowDestroying(aura::Window* window) {
356 // window is one of a container, the restore_focus_window and/or 317 WindowSelectorItem* removed_item = NULL;
357 // one of the selectable windows in overview. 318
358 ScopedVector<WindowSelectorItem>::iterator iter = 319 // Find the grid corresponding to the window's root window.
359 std::find_if(windows_.begin(), windows_.end(), 320 ScopedVector<WindowGrid>::iterator grid_iter =
360 WindowSelectorItemComparator(window)); 321 std::find_if(grid_list_.begin(), grid_list_.end(),
322 RootWindowGridComparator(window->GetRootWindow()));
323
324 DCHECK(grid_iter != grid_list_.end());
325 removed_item = (*grid_iter)->RemoveWindow(window);
326
361 window->RemoveObserver(this); 327 window->RemoveObserver(this);
362 observed_windows_.erase(window); 328 observed_windows_.erase(window);
363 if (window == restore_focus_window_) 329 if (window == restore_focus_window_)
364 restore_focus_window_ = NULL; 330 restore_focus_window_ = NULL;
365 if (iter == windows_.end()) 331
332 // If removing the window doesn't cause the removal of an item, we are done.
333 if (!removed_item)
366 return; 334 return;
367 335
368 (*iter)->RemoveWindow(window); 336 windows_.erase(std::find(windows_.begin(), windows_.end(), removed_item));
flackr 2014/05/29 20:04:25 So we have two vectors of WindowSelectorItem point
Nina 2014/06/02 22:04:38 I refactored the code so that the WindowGrid owns
369 // If there are still windows in this selector entry then the overview is
370 // still active and the active selection remains the same.
371 if (!(*iter)->empty())
372 return;
373 337
374 windows_.erase(iter); 338 if (grid_iter != grid_list_.end() && (*grid_iter)->empty()) {
flackr 2014/05/29 20:04:25 if we have a removed item, it must have come from
Nina 2014/06/02 22:04:38 Done.
375 if (windows_.empty()) { 339 grid_list_.erase(grid_iter);
376 CancelSelection(); 340 root_index_ = 0;
377 return; 341 if (grid_list_.size() == 0)
342 CancelSelection();
378 } 343 }
379 PositionWindows(true);
380 } 344 }
381 345
382 void WindowSelector::OnWindowBoundsChanged(aura::Window* window, 346 void WindowSelector::OnWindowBoundsChanged(aura::Window* window,
383 const gfx::Rect& old_bounds, 347 const gfx::Rect& old_bounds,
384 const gfx::Rect& new_bounds) { 348 const gfx::Rect& new_bounds) {
385 ScopedVector<WindowSelectorItem>::iterator iter = 349 ScopedVector<WindowSelectorItem>::iterator iter =
386 std::find_if(windows_.begin(), windows_.end(), 350 std::find_if(windows_.begin(), windows_.end(),
387 WindowSelectorItemTargetComparator(window)); 351 WindowSelectorItemTargetComparator(window));
388 if (iter == windows_.end()) 352 if (iter == windows_.end())
389 return; 353 return;
(...skipping 29 matching lines...) Expand all
419 aura::client::GetFocusClient( 383 aura::client::GetFocusClient(
420 Shell::GetPrimaryRootWindow())->FocusWindow(NULL); 384 Shell::GetPrimaryRootWindow())->FocusWindow(NULL);
421 385
422 Shell* shell = Shell::GetInstance(); 386 Shell* shell = Shell::GetInstance();
423 shell->OnOverviewModeStarting(); 387 shell->OnOverviewModeStarting();
424 388
425 for (WindowSelectorItemList::iterator iter = windows_.begin(); 389 for (WindowSelectorItemList::iterator iter = windows_.begin();
426 iter != windows_.end(); ++iter) { 390 iter != windows_.end(); ++iter) {
427 (*iter)->PrepareForOverview(); 391 (*iter)->PrepareForOverview();
428 } 392 }
429 PositionWindows(/* animate */ true); 393 PositionWindows(true);
flackr 2014/05/29 20:04:25 Why remove the animate comment?
Nina 2014/06/02 22:04:38 Hmmm that slipped. Restored.
430 DCHECK(!windows_.empty()); 394 DCHECK(!windows_.empty());
431 cursor_client_ = aura::client::GetCursorClient( 395 cursor_client_ = aura::client::GetCursorClient(
432 windows_.front()->GetRootWindow()); 396 windows_.front()->GetRootWindow());
433 if (cursor_client_) { 397 if (cursor_client_) {
434 cursor_client_->SetCursor(ui::kCursorPointer); 398 cursor_client_->SetCursor(ui::kCursorPointer);
435 cursor_client_->ShowCursor(); 399 cursor_client_->ShowCursor();
436 // TODO(flackr): Only prevent cursor changes for windows in the overview. 400 // TODO(flackr): Only prevent cursor changes for windows in the overview.
437 // This will be easier to do without exposing the overview mode code if the 401 // This will be easier to do without exposing the overview mode code if the
438 // cursor changes are moved to ToplevelWindowEventHandler::HandleMouseMoved 402 // cursor changes are moved to ToplevelWindowEventHandler::HandleMouseMoved
439 // as suggested there. 403 // as suggested there.
440 cursor_client_->LockCursor(); 404 cursor_client_->LockCursor();
441 } 405 }
442 shell->PrependPreTargetHandler(this); 406 shell->PrependPreTargetHandler(this);
443 shell->GetScreen()->AddObserver(this); 407 shell->GetScreen()->AddObserver(this);
444 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); 408 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW);
445 HideAndTrackNonOverviewWindows(); 409 HideAndTrackNonOverviewWindows();
446 // Send an a11y alert. 410 // Send an a11y alert.
447 shell->accessibility_delegate()->TriggerAccessibilityAlert( 411 shell->accessibility_delegate()->TriggerAccessibilityAlert(
448 A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); 412 A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED);
449 413
450 UpdateShelfVisibility(); 414 UpdateShelfVisibility();
451 } 415 }
452 416
453 void WindowSelector::PositionWindows(bool animate) { 417 void WindowSelector::PositionWindows(bool animate) {
418 grid_list_.clear();
flackr 2014/05/29 20:04:25 Instead of rebuilding grid_list_, can we construct
Nina 2014/06/02 22:04:38 I believe it is still better to handle window acti
454 aura::Window::Windows root_window_list = Shell::GetAllRootWindows(); 419 aura::Window::Windows root_window_list = Shell::GetAllRootWindows();
455 for (size_t i = 0; i < root_window_list.size(); ++i) 420 for (size_t i = 0; i < root_window_list.size(); ++i) {
456 PositionWindowsFromRoot(root_window_list[i], animate); 421 std::vector<WindowSelectorItem*> windows;
457 } 422 for (WindowSelectorItemList::iterator iter = windows_.begin();
458 423 iter != windows_.end(); ++iter) {
459 void WindowSelector::PositionWindowsFromRoot(aura::Window* root_window, 424 if ((*iter)->GetRootWindow() == root_window_list[i])
460 bool animate) { 425 windows.push_back(*iter);
461 std::vector<WindowSelectorItem*> windows; 426 }
462 for (WindowSelectorItemList::iterator iter = windows_.begin(); 427 if (!windows.empty())
463 iter != windows_.end(); ++iter) { 428 grid_list_.push_back(new WindowGrid(root_window_list[i], windows));
464 if ((*iter)->GetRootWindow() == root_window)
465 windows.push_back(*iter);
466 }
467
468 if (windows.empty())
469 return;
470
471 gfx::Size window_size;
472 gfx::Rect total_bounds = ScreenUtil::ConvertRectToScreen(
473 root_window,
474 ScreenUtil::GetDisplayWorkAreaBoundsInParent(
475 Shell::GetContainer(root_window, kShellWindowId_DefaultContainer)));
476
477 // Find the minimum number of windows per row that will fit all of the
478 // windows on screen.
479 size_t columns = std::max(
480 total_bounds.width() > total_bounds.height() ? kMinCardsMajor : 1,
481 static_cast<int>(ceil(sqrt(total_bounds.width() * windows.size() /
482 (kCardAspectRatio * total_bounds.height())))));
483 size_t rows = ((windows.size() + columns - 1) / columns);
484 window_size.set_width(std::min(
485 static_cast<int>(total_bounds.width() / columns),
486 static_cast<int>(total_bounds.height() * kCardAspectRatio / rows)));
487 window_size.set_height(window_size.width() / kCardAspectRatio);
488
489 // Calculate the X and Y offsets necessary to center the grid.
490 int x_offset = total_bounds.x() + ((windows.size() >= columns ? 0 :
491 (columns - windows.size()) * window_size.width()) +
492 (total_bounds.width() - columns * window_size.width())) / 2;
493 int y_offset = total_bounds.y() + (total_bounds.height() -
494 rows * window_size.height()) / 2;
495 for (size_t i = 0; i < windows.size(); ++i) {
496 gfx::Transform transform;
497 int column = i % columns;
498 int row = i / columns;
499 gfx::Rect target_bounds(window_size.width() * column + x_offset,
500 window_size.height() * row + y_offset,
501 window_size.width(),
502 window_size.height());
503 target_bounds.Inset(kWindowMargin, kWindowMargin);
504 windows[i]->SetBounds(root_window, target_bounds, animate);
505 } 429 }
506 } 430 }
507 431
508 void WindowSelector::HideAndTrackNonOverviewWindows() { 432 void WindowSelector::HideAndTrackNonOverviewWindows() {
509 // Add the windows to hidden_windows first so that if any are destroyed 433 // Add the windows to hidden_windows first so that if any are destroyed
510 // while hiding them they are tracked. 434 // while hiding them they are tracked.
511 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 435 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
512 for (aura::Window::Windows::const_iterator root_iter = root_windows.begin(); 436 for (aura::Window::Windows::const_iterator root_iter = root_windows.begin();
513 root_iter != root_windows.end(); ++root_iter) { 437 root_iter != root_windows.end(); ++root_iter) {
514 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { 438 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 aura::Window* WindowSelector::GetTargetedWindow(aura::Window* window) { 498 aura::Window* WindowSelector::GetTargetedWindow(aura::Window* window) {
575 for (WindowSelectorItemList::iterator iter = windows_.begin(); 499 for (WindowSelectorItemList::iterator iter = windows_.begin();
576 iter != windows_.end(); ++iter) { 500 iter != windows_.end(); ++iter) {
577 aura::Window* selected = (*iter)->TargetedWindow(window); 501 aura::Window* selected = (*iter)->TargetedWindow(window);
578 if (selected) 502 if (selected)
579 return selected; 503 return selected;
580 } 504 }
581 return NULL; 505 return NULL;
582 } 506 }
583 507
508 void WindowSelector::Move(Direction direction) {
509 if (!grid_list_[root_index_]->is_selecting()) {
510 grid_list_[root_index_]->CreateSelectionWidget(direction);
flackr 2014/05/29 20:04:25 This seems like something calling GridList::Move c
Nina 2014/06/02 22:04:38 Done.
511 return;
512 }
513 if (grid_list_[root_index_]->Move(direction)) {
514 // The grid reported that the movement command corresponds to the next
515 // root window, identify it and call Move() on it to initialize the
516 // selection widget.
517 if (root_index_ >= grid_list_.size() - 1)
518 root_index_ = 0;
519 else
520 root_index_++;
flackr 2014/05/29 20:04:25 root_index_ = (root_index + 1) % grid_list_.size()
Nina 2014/06/02 22:04:38 Done.
521 grid_list_[root_index_]->CreateSelectionWidget(direction);
522 }
523 }
524
584 } // namespace ash 525 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698