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

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

Issue 358553004: Added text filtering to Overview Mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Thanks chrome team for helping me fix the previous patch Created 6 years, 5 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/shell.h" 13 #include "ash/shell.h"
14 #include "ash/shell_window_ids.h" 14 #include "ash/shell_window_ids.h"
15 #include "ash/switchable_windows.h" 15 #include "ash/switchable_windows.h"
16 #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" 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/window_state.h" 20 #include "ash/wm/window_state.h"
21 #include "base/auto_reset.h" 21 #include "base/auto_reset.h"
22 #include "base/command_line.h"
22 #include "base/metrics/histogram.h" 23 #include "base/metrics/histogram.h"
23 #include "ui/aura/client/focus_client.h" 24 #include "ui/aura/client/focus_client.h"
24 #include "ui/aura/window.h" 25 #include "ui/aura/window.h"
25 #include "ui/aura/window_event_dispatcher.h" 26 #include "ui/aura/window_event_dispatcher.h"
26 #include "ui/aura/window_observer.h" 27 #include "ui/aura/window_observer.h"
27 #include "ui/compositor/scoped_layer_animation_settings.h" 28 #include "ui/compositor/scoped_layer_animation_settings.h"
28 #include "ui/events/event.h" 29 #include "ui/events/event.h"
29 #include "ui/gfx/screen.h" 30 #include "ui/gfx/screen.h"
31 #include "ui/views/border.h"
32 #include "ui/views/controls/textfield/textfield.h"
30 #include "ui/wm/core/window_util.h" 33 #include "ui/wm/core/window_util.h"
31 #include "ui/wm/public/activation_client.h" 34 #include "ui/wm/public/activation_client.h"
32 35
33 namespace ash { 36 namespace ash {
34 37
35 namespace { 38 namespace {
36 39
40 // The proportion of screen width that the text filter takes.
41 const float kTextFilterScreenProportion = 0.5;
42
43 // The height of the text filter.
44 const int kTextFilterHeight = 50;
45
46 // Solid shadow length from the text filter.
47 const int kVerticalShadowOffset = 1;
48
49 // Amount of blur applied to the text filter shadow.
50 const int kShadowBlur = 10;
51
52 // Text filter shadow color.
53 const SkColor kTextFilterShadow = 0xB0000000;
54
37 // A comparator for locating a grid with a given root window. 55 // A comparator for locating a grid with a given root window.
38 struct RootWindowGridComparator 56 struct RootWindowGridComparator
39 : public std::unary_function<WindowGrid*, bool> { 57 : public std::unary_function<WindowGrid*, bool> {
40 explicit RootWindowGridComparator(const aura::Window* root_window) 58 explicit RootWindowGridComparator(const aura::Window* root_window)
41 : root_window_(root_window) { 59 : root_window_(root_window) {
42 } 60 }
43 61
44 bool operator()(WindowGrid* grid) const { 62 bool operator()(WindowGrid* grid) const {
45 return (grid->root_window() == root_window_); 63 return (grid->root_window() == root_window_);
46 } 64 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 void UpdateShelfVisibility() { 98 void UpdateShelfVisibility() {
81 Shell::RootWindowControllerList root_window_controllers = 99 Shell::RootWindowControllerList root_window_controllers =
82 Shell::GetInstance()->GetAllRootWindowControllers(); 100 Shell::GetInstance()->GetAllRootWindowControllers();
83 for (Shell::RootWindowControllerList::iterator iter = 101 for (Shell::RootWindowControllerList::iterator iter =
84 root_window_controllers.begin(); 102 root_window_controllers.begin();
85 iter != root_window_controllers.end(); ++iter) { 103 iter != root_window_controllers.end(); ++iter) {
86 (*iter)->UpdateShelfVisibility(); 104 (*iter)->UpdateShelfVisibility();
87 } 105 }
88 } 106 }
89 107
108 // Initializes the text filter on the top of the main root window and requests
109 // focus on its textfield.
110 views::Widget* CreateTextFilter(views::TextfieldController* controller,
111 aura::Window* root_window) {
112 views::Widget* widget = new views::Widget;
113 views::Widget::InitParams params;
114 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
115 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
116 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
117 params.parent =
118 Shell::GetContainer(root_window, ash::kShellWindowId_OverlayContainer);
119 params.accept_events = true;
120 params.bounds = gfx::Rect(
121 root_window->bounds().width() / 2 * (1 - kTextFilterScreenProportion),
122 -kTextFilterHeight,
flackr 2014/06/27 20:00:06 Should this be created at 0 and transformed to -kT
Nina 2014/06/27 22:42:02 Done.
123 root_window->bounds().width() * kTextFilterScreenProportion,
124 kTextFilterHeight);
125 widget->Init(params);
126 views::Textfield* textfield = new views::Textfield;
127 textfield->set_controller(controller);
128 textfield->SetBackgroundColor(SK_ColorTRANSPARENT);
129 textfield->SetBorder(views::Border::NullBorder());
130 textfield->SetTextColor(SK_ColorWHITE);
131 textfield->set_shadows(gfx::ShadowValues(1, gfx::ShadowValue(
132 gfx::Point(0, kVerticalShadowOffset), kShadowBlur, kTextFilterShadow)));
133 widget->SetContentsView(textfield);
134 widget->Show();
135 textfield->RequestFocus();
136
137 return widget;
138 }
139
90 } // namespace 140 } // namespace
91 141
92 WindowSelector::WindowSelector(const WindowList& windows, 142 WindowSelector::WindowSelector(const WindowList& windows,
93 WindowSelectorDelegate* delegate) 143 WindowSelectorDelegate* delegate)
94 : delegate_(delegate), 144 : delegate_(delegate),
95 restore_focus_window_(aura::client::GetFocusClient( 145 restore_focus_window_(aura::client::GetFocusClient(
96 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), 146 Shell::GetPrimaryRootWindow())->GetFocusedWindow()),
97 ignore_activations_(false), 147 ignore_activations_(false),
98 selected_grid_index_(0), 148 selected_grid_index_(0),
99 overview_start_time_(base::Time::Now()), 149 overview_start_time_(base::Time::Now()),
100 num_key_presses_(0), 150 num_key_presses_(0),
101 num_items_(0) { 151 num_items_(0),
152 showing_selection_widget_(false) {
102 DCHECK(delegate_); 153 DCHECK(delegate_);
103 Shell* shell = Shell::GetInstance(); 154 Shell* shell = Shell::GetInstance();
104 shell->OnOverviewModeStarting(); 155 shell->OnOverviewModeStarting();
105 156
106 if (restore_focus_window_) 157 if (restore_focus_window_)
107 restore_focus_window_->AddObserver(this); 158 restore_focus_window_->AddObserver(this);
108 159
109 const aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 160 const aura::Window::Windows root_windows = Shell::GetAllRootWindows();
110 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); 161 for (aura::Window::Windows::const_iterator iter = root_windows.begin();
111 iter != root_windows.end(); iter++) { 162 iter != root_windows.end(); iter++) {
112 // Observed switchable containers for newly created windows on all root 163 // Observed switchable containers for newly created windows on all root
113 // windows. 164 // windows.
114 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { 165 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) {
115 aura::Window* container = Shell::GetContainer(*iter, 166 aura::Window* container = Shell::GetContainer(*iter,
116 kSwitchableWindowContainerIds[i]); 167 kSwitchableWindowContainerIds[i]);
117 container->AddObserver(this); 168 container->AddObserver(this);
118 observed_windows_.insert(container); 169 observed_windows_.insert(container);
119 } 170 }
120 scoped_ptr<WindowGrid> grid(new WindowGrid(*iter, windows, this)); 171 scoped_ptr<WindowGrid> grid(new WindowGrid(*iter, windows, this));
121 if (grid->empty()) 172 if (grid->empty())
122 continue; 173 continue;
123 num_items_ += grid->size(); 174 num_items_ += grid->size();
124 grid_list_.push_back(grid.release()); 175 grid_list_.push_back(grid.release());
125 } 176 }
126 177
127 DCHECK(!grid_list_.empty()); 178 DCHECK(!grid_list_.empty());
128 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); 179 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_);
129 180
181 text_filter_widget_.reset(
182 CreateTextFilter(this, Shell::GetPrimaryRootWindow()));
flackr 2014/06/27 20:00:07 Do we have to worry about the text input element l
Nina 2014/06/27 22:42:02 I really don't think it can happen, as we are obse
183
130 shell->activation_client()->AddObserver(this); 184 shell->activation_client()->AddObserver(this);
131 185
132 // Remove focus from active window before entering overview.
133 aura::client::GetFocusClient(
134 Shell::GetPrimaryRootWindow())->FocusWindow(NULL);
135
136 shell->PrependPreTargetHandler(this);
137 shell->GetScreen()->AddObserver(this); 186 shell->GetScreen()->AddObserver(this);
138 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); 187 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW);
139 HideAndTrackNonOverviewWindows(); 188 HideAndTrackNonOverviewWindows();
140 // Send an a11y alert. 189 // Send an a11y alert.
141 shell->accessibility_delegate()->TriggerAccessibilityAlert( 190 shell->accessibility_delegate()->TriggerAccessibilityAlert(
142 A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); 191 A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED);
143 192
144 UpdateShelfVisibility(); 193 UpdateShelfVisibility();
145 } 194 }
146 195
(...skipping 14 matching lines...) Expand all
161 ui::ScopedLayerAnimationSettings settings( 210 ui::ScopedLayerAnimationSettings settings(
162 (*iter)->layer()->GetAnimator()); 211 (*iter)->layer()->GetAnimator());
163 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( 212 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
164 ScopedTransformOverviewWindow::kTransitionMilliseconds)); 213 ScopedTransformOverviewWindow::kTransitionMilliseconds));
165 settings.SetPreemptionStrategy( 214 settings.SetPreemptionStrategy(
166 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 215 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
167 (*iter)->layer()->SetOpacity(1); 216 (*iter)->layer()->SetOpacity(1);
168 (*iter)->Show(); 217 (*iter)->Show();
169 } 218 }
170 219
171 shell->RemovePreTargetHandler(this);
172 shell->GetScreen()->RemoveObserver(this); 220 shell->GetScreen()->RemoveObserver(this);
173 221
174 size_t remaining_items = 0; 222 size_t remaining_items = 0;
175 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); 223 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin();
176 iter != grid_list_.end(); iter++) { 224 iter != grid_list_.end(); iter++) {
177 remaining_items += (*iter)->size(); 225 remaining_items += (*iter)->size();
178 } 226 }
179 227
180 DCHECK(num_items_ >= remaining_items); 228 DCHECK(num_items_ >= remaining_items);
181 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems", 229 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems",
(...skipping 18 matching lines...) Expand all
200 ScopedVector<WindowGrid>::iterator iter = 248 ScopedVector<WindowGrid>::iterator iter =
201 std::find(grid_list_.begin(), grid_list_.end(), grid); 249 std::find(grid_list_.begin(), grid_list_.end(), grid);
202 DCHECK(iter != grid_list_.end()); 250 DCHECK(iter != grid_list_.end());
203 grid_list_.erase(iter); 251 grid_list_.erase(iter);
204 // TODO(nsatragno): Use the previous index for more than two displays. 252 // TODO(nsatragno): Use the previous index for more than two displays.
205 selected_grid_index_ = 0; 253 selected_grid_index_ = 0;
206 if (grid_list_.empty()) 254 if (grid_list_.empty())
207 CancelSelection(); 255 CancelSelection();
208 } 256 }
209 257
210 void WindowSelector::OnKeyEvent(ui::KeyEvent* event) { 258 bool WindowSelector::HandleKeyEvent(views::Textfield* sender,
211 if (event->type() != ui::ET_KEY_PRESSED) 259 const ui::KeyEvent& key_event) {
212 return; 260 if (key_event.type() != ui::ET_KEY_PRESSED)
261 return false;
213 262
214 switch (event->key_code()) { 263 switch (key_event.key_code()) {
215 case ui::VKEY_ESCAPE: 264 case ui::VKEY_ESCAPE:
216 CancelSelection(); 265 CancelSelection();
217 break; 266 break;
218 case ui::VKEY_UP: 267 case ui::VKEY_UP:
219 num_key_presses_++; 268 num_key_presses_++;
220 Move(WindowSelector::UP); 269 Move(WindowSelector::UP, true);
221 break; 270 break;
222 case ui::VKEY_DOWN: 271 case ui::VKEY_DOWN:
223 num_key_presses_++; 272 num_key_presses_++;
224 Move(WindowSelector::DOWN); 273 Move(WindowSelector::DOWN, true);
225 break; 274 break;
226 case ui::VKEY_RIGHT: 275 case ui::VKEY_RIGHT:
227 num_key_presses_++; 276 num_key_presses_++;
228 Move(WindowSelector::RIGHT); 277 Move(WindowSelector::RIGHT, true);
229 break; 278 break;
230 case ui::VKEY_LEFT: 279 case ui::VKEY_LEFT:
231 num_key_presses_++; 280 num_key_presses_++;
232 Move(WindowSelector::LEFT); 281 Move(WindowSelector::LEFT, true);
233 break; 282 break;
234 case ui::VKEY_RETURN: 283 case ui::VKEY_RETURN:
235 // Ignore if no item is selected. 284 // Ignore if no item is selected.
236 if (!grid_list_[selected_grid_index_]->is_selecting()) 285 if (!grid_list_[selected_grid_index_]->is_selecting())
237 return; 286 return true;
flackr 2014/06/27 20:00:06 Isn't this technically not handled? Should we retu
Nina 2014/06/27 22:42:01 Well, apparently both options have the same effect
238 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.ArrowKeyPresses", 287 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.ArrowKeyPresses",
239 num_key_presses_); 288 num_key_presses_);
240 UMA_HISTOGRAM_CUSTOM_COUNTS( 289 UMA_HISTOGRAM_CUSTOM_COUNTS(
241 "Ash.WindowSelector.KeyPressesOverItemsRatio", 290 "Ash.WindowSelector.KeyPressesOverItemsRatio",
242 (num_key_presses_ * 100) / num_items_, 1, 300, 30); 291 (num_key_presses_ * 100) / num_items_, 1, 300, 30);
243 Shell::GetInstance()->metrics()->RecordUserMetricsAction( 292 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
244 UMA_WINDOW_OVERVIEW_ENTER_KEY); 293 UMA_WINDOW_OVERVIEW_ENTER_KEY);
245 wm::GetWindowState(grid_list_[selected_grid_index_]-> 294 wm::GetWindowState(grid_list_[selected_grid_index_]->
246 SelectedWindow()->SelectionWindow())->Activate(); 295 SelectedWindow()->SelectionWindow())->Activate();
247 break; 296 break;
248 default: 297 default:
249 // Not a key we are interested in. 298 // Not a key we are interested in, allow the textfield to handle it.
250 return; 299 return false;
251 } 300 }
252 event->StopPropagation(); 301 return true;
253 } 302 }
254 303
255 void WindowSelector::OnDisplayAdded(const gfx::Display& display) { 304 void WindowSelector::OnDisplayAdded(const gfx::Display& display) {
256 } 305 }
257 306
258 void WindowSelector::OnDisplayRemoved(const gfx::Display& display) { 307 void WindowSelector::OnDisplayRemoved(const gfx::Display& display) {
259 // TODO(nsatragno): Keep window selection active on remaining displays. 308 // TODO(nsatragno): Keep window selection active on remaining displays.
260 CancelSelection(); 309 CancelSelection();
261 } 310 }
262 311
(...skipping 20 matching lines...) Expand all
283 332
284 void WindowSelector::OnWindowDestroying(aura::Window* window) { 333 void WindowSelector::OnWindowDestroying(aura::Window* window) {
285 window->RemoveObserver(this); 334 window->RemoveObserver(this);
286 observed_windows_.erase(window); 335 observed_windows_.erase(window);
287 if (window == restore_focus_window_) 336 if (window == restore_focus_window_)
288 restore_focus_window_ = NULL; 337 restore_focus_window_ = NULL;
289 } 338 }
290 339
291 void WindowSelector::OnWindowActivated(aura::Window* gained_active, 340 void WindowSelector::OnWindowActivated(aura::Window* gained_active,
292 aura::Window* lost_active) { 341 aura::Window* lost_active) {
293 if (ignore_activations_ || !gained_active) 342 if (ignore_activations_ ||
343 !gained_active ||
344 gained_active == text_filter_widget_->GetNativeWindow()) {
294 return; 345 return;
346 }
295 347
296 ScopedVector<WindowGrid>::iterator grid = 348 ScopedVector<WindowGrid>::iterator grid =
297 std::find_if(grid_list_.begin(), grid_list_.end(), 349 std::find_if(grid_list_.begin(), grid_list_.end(),
298 RootWindowGridComparator(gained_active->GetRootWindow())); 350 RootWindowGridComparator(gained_active->GetRootWindow()));
299 if (grid == grid_list_.end()) 351 if (grid == grid_list_.end())
300 return; 352 return;
301 const std::vector<WindowSelectorItem*> windows = (*grid)->window_list(); 353 const std::vector<WindowSelectorItem*> windows = (*grid)->window_list();
302 354
303 ScopedVector<WindowSelectorItem>::const_iterator iter = std::find_if( 355 ScopedVector<WindowSelectorItem>::const_iterator iter = std::find_if(
304 windows.begin(), windows.end(), 356 windows.begin(), windows.end(),
305 WindowSelectorItemTargetComparator(gained_active)); 357 WindowSelectorItemTargetComparator(gained_active));
306 358
307 if (iter != windows.end()) 359 if (iter != windows.end())
308 (*iter)->RestoreWindowOnExit(gained_active); 360 (*iter)->RestoreWindowOnExit(gained_active);
309 361
310 // Don't restore focus on exit if a window was just activated. 362 // Don't restore focus on exit if a window was just activated.
311 ResetFocusRestoreWindow(false); 363 ResetFocusRestoreWindow(false);
312 CancelSelection(); 364 CancelSelection();
313 } 365 }
314 366
315 void WindowSelector::OnAttemptToReactivateWindow(aura::Window* request_active, 367 void WindowSelector::OnAttemptToReactivateWindow(aura::Window* request_active,
316 aura::Window* actual_active) { 368 aura::Window* actual_active) {
317 OnWindowActivated(request_active, actual_active); 369 OnWindowActivated(request_active, actual_active);
318 } 370 }
319 371
372 void WindowSelector::ContentsChanged(views::Textfield* sender,
373 const base::string16& new_contents) {
374 if (CommandLine::ForCurrentProcess()->HasSwitch(
375 switches::kAshDisableTextFilteringInOverviewMode)) {
flackr 2014/06/27 20:00:06 nit: Indend 4 from '(', I guess a total of 10 spac
Nina 2014/06/27 22:42:02 Damn Eclipse!
376 return;
377 }
flackr 2014/06/27 20:00:06 nit: blank line to separate this early return from
Nina 2014/06/27 22:42:02 Done.
378 if (!showing_selection_widget_ || new_contents.empty()) {
flackr 2014/06/27 20:00:06 nit: To make sure this always does the right thing
Nina 2014/06/27 22:42:01 I'll take you meant should_show_*. Done.
379 ui::ScopedLayerAnimationSettings animation_settings(
380 text_filter_widget_->GetNativeWindow()->layer()->GetAnimator());
381 animation_settings.SetPreemptionStrategy(
382 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
383 animation_settings.SetTweenType(showing_selection_widget_ ?
384 gfx::Tween::FAST_OUT_LINEAR_IN : gfx::Tween::LINEAR_OUT_SLOW_IN);
385
386 gfx::Transform transform;
387 if (showing_selection_widget_)
flackr 2014/06/27 20:00:06 This is confusing because you're doing the opposit
Nina 2014/06/27 22:42:02 Done.
388 transform.Translate(0, -kTextFilterHeight);
389 else
390 transform.Translate(0, kTextFilterHeight);
flackr 2014/06/27 20:00:06 This should just be transformed to (0, 0), we shou
Nina 2014/06/27 22:42:01 Done.
391
392 text_filter_widget_->GetNativeWindow()->SetTransform(transform);
393 showing_selection_widget_ = !showing_selection_widget_;
394 }
395 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin();
396 iter != grid_list_.end(); iter++) {
397 (*iter)->FilterItems(new_contents);
398 }
399
400 // If the selection widget is not active, execute a Move() command so that it
401 // shows up on the first undimmed item.
402 if (grid_list_[selected_grid_index_]->is_selecting())
403 return;
404 Move(WindowSelector::RIGHT, false);
405 }
406
320 void WindowSelector::PositionWindows(bool animate) { 407 void WindowSelector::PositionWindows(bool animate) {
321 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); 408 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin();
322 iter != grid_list_.end(); iter++) { 409 iter != grid_list_.end(); iter++) {
323 (*iter)->PositionWindows(animate); 410 (*iter)->PositionWindows(animate);
324 } 411 }
325 } 412 }
326 413
327 void WindowSelector::HideAndTrackNonOverviewWindows() { 414 void WindowSelector::HideAndTrackNonOverviewWindows() {
328 // Add the windows to hidden_windows first so that if any are destroyed 415 // Add the windows to hidden_windows first so that if any are destroyed
329 // while hiding them they are tracked. 416 // while hiding them they are tracked.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 } 459 }
373 // If the window is in the observed_windows_ list it needs to continue to be 460 // If the window is in the observed_windows_ list it needs to continue to be
374 // observed. 461 // observed.
375 if (observed_windows_.find(restore_focus_window_) == 462 if (observed_windows_.find(restore_focus_window_) ==
376 observed_windows_.end()) { 463 observed_windows_.end()) {
377 restore_focus_window_->RemoveObserver(this); 464 restore_focus_window_->RemoveObserver(this);
378 } 465 }
379 restore_focus_window_ = NULL; 466 restore_focus_window_ = NULL;
380 } 467 }
381 468
382 void WindowSelector::Move(Direction direction) { 469 void WindowSelector::Move(Direction direction, bool animate) {
383 bool overflowed = grid_list_[selected_grid_index_]->Move(direction); 470 // Keep calling Move() on the grids until one of them reports no overflow or
384 if (overflowed) { 471 // we made a full cycle on all the grids.
385 // The grid reported that the movement command corresponds to the next 472 for (size_t i = 0;
386 // root window, identify it and call Move() on it to initialize the 473 i <= grid_list_.size() &&
387 // selection widget. 474 grid_list_[selected_grid_index_]->Move(direction, animate); i++) {
388 // TODO(nsatragno): If there are more than two monitors, move between grids 475 // TODO(nsatragno): If there are more than two monitors, move between grids
389 // in the requested direction. 476 // in the requested direction.
390 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size(); 477 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size();
391 grid_list_[selected_grid_index_]->Move(direction);
392 } 478 }
393 } 479 }
394 480
395 } // namespace ash 481 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698