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

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

Issue 280423008: Merge WindowOverview into WindowSelector (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed nits Created 6 years, 7 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') | no next file » | 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 8
9 #include "ash/accessibility_delegate.h"
9 #include "ash/ash_switches.h" 10 #include "ash/ash_switches.h"
11 #include "ash/metrics/user_metrics_recorder.h"
10 #include "ash/root_window_controller.h" 12 #include "ash/root_window_controller.h"
13 #include "ash/screen_util.h"
11 #include "ash/shell.h" 14 #include "ash/shell.h"
15 #include "ash/shell_window_ids.h"
12 #include "ash/switchable_windows.h" 16 #include "ash/switchable_windows.h"
13 #include "ash/wm/overview/window_overview.h" 17 #include "ash/wm/overview/scoped_transform_overview_window.h"
14 #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"
15 #include "ash/wm/overview/window_selector_panels.h" 20 #include "ash/wm/overview/window_selector_panels.h"
16 #include "ash/wm/overview/window_selector_window.h" 21 #include "ash/wm/overview/window_selector_window.h"
17 #include "ash/wm/window_state.h" 22 #include "ash/wm/window_state.h"
18 #include "base/auto_reset.h" 23 #include "base/auto_reset.h"
19 #include "base/command_line.h" 24 #include "base/command_line.h"
20 #include "base/metrics/histogram.h" 25 #include "base/metrics/histogram.h"
21 #include "base/strings/string_number_conversions.h" 26 #include "base/strings/string_number_conversions.h"
27 #include "third_party/skia/include/core/SkColor.h"
28 #include "ui/aura/client/cursor_client.h"
22 #include "ui/aura/client/focus_client.h" 29 #include "ui/aura/client/focus_client.h"
23 #include "ui/aura/window.h" 30 #include "ui/aura/window.h"
31 #include "ui/aura/window_event_dispatcher.h"
24 #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"
35 #include "ui/events/event.h"
36 #include "ui/gfx/screen.h"
37 #include "ui/views/background.h"
38 #include "ui/views/widget/widget.h"
25 #include "ui/wm/core/window_util.h" 39 #include "ui/wm/core/window_util.h"
26 #include "ui/wm/public/activation_client.h" 40 #include "ui/wm/public/activation_client.h"
27 41
28 namespace ash { 42 namespace ash {
29 43
30 namespace { 44 namespace {
31 45
32 // A comparator for locating a given selectable window. 46 // Conceptually the window overview is a table or grid of cells having this
47 // fixed aspect ratio. The number of columns is determined by maximizing the
48 // area of them based on the number of windows.
49 const float kCardAspectRatio = 4.0f / 3.0f;
50
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.
33 struct WindowSelectorItemComparator 61 struct WindowSelectorItemComparator
34 : public std::unary_function<WindowSelectorItem*, bool> { 62 : public std::unary_function<WindowSelectorItem*, bool> {
35 explicit WindowSelectorItemComparator(const aura::Window* window) 63 explicit WindowSelectorItemComparator(const aura::Window* target_window)
36 : window_(window) { 64 : target(target_window) {
37 } 65 }
38 66
39 bool operator()(WindowSelectorItem* window) const { 67 bool operator()(WindowSelectorItem* window) const {
40 return window->HasSelectableWindow(window_); 68 return window->HasSelectableWindow(target);
41 } 69 }
42 70
43 const aura::Window* window_; 71 const aura::Window* target;
44 }; 72 };
45 73
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
46 // A comparator for locating a selectable window given a targeted window. 121 // A comparator for locating a selectable window given a targeted window.
47 struct WindowSelectorItemTargetComparator 122 struct WindowSelectorItemTargetComparator
48 : public std::unary_function<WindowSelectorItem*, bool> { 123 : public std::unary_function<WindowSelectorItem*, bool> {
49 explicit WindowSelectorItemTargetComparator(const aura::Window* target_window) 124 explicit WindowSelectorItemTargetComparator(const aura::Window* target_window)
50 : target(target_window) { 125 : target(target_window) {
51 } 126 }
52 127
53 bool operator()(WindowSelectorItem* window) const { 128 bool operator()(WindowSelectorItem* window) const {
54 return window->TargetedWindow(target) != NULL; 129 return window->TargetedWindow(target) != NULL;
55 } 130 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 kSwitchableWindowContainerIds[i]); 214 kSwitchableWindowContainerIds[i]);
140 container->AddObserver(this); 215 container->AddObserver(this);
141 observed_windows_.insert(container); 216 observed_windows_.insert(container);
142 } 217 }
143 } 218 }
144 219
145 StartOverview(); 220 StartOverview();
146 } 221 }
147 222
148 WindowSelector::~WindowSelector() { 223 WindowSelector::~WindowSelector() {
224 ash::Shell* shell = ash::Shell::GetInstance();
225
149 ResetFocusRestoreWindow(true); 226 ResetFocusRestoreWindow(true);
150 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin(); 227 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin();
151 iter != observed_windows_.end(); ++iter) { 228 iter != observed_windows_.end(); ++iter) {
152 (*iter)->RemoveObserver(this); 229 (*iter)->RemoveObserver(this);
153 } 230 }
154 Shell::GetInstance()->activation_client()->RemoveObserver(this); 231 shell->activation_client()->RemoveObserver(this);
155 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 232 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
156 window_overview_.reset(); 233
234 const aura::WindowTracker::Windows hidden_windows(hidden_windows_.windows());
235 for (aura::WindowTracker::Windows::const_iterator iter =
236 hidden_windows.begin(); iter != hidden_windows.end(); ++iter) {
237 ui::ScopedLayerAnimationSettings settings(
238 (*iter)->layer()->GetAnimator());
239 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
240 ScopedTransformOverviewWindow::kTransitionMilliseconds));
241 settings.SetPreemptionStrategy(
242 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
243 (*iter)->layer()->SetOpacity(1);
244 (*iter)->Show();
245 }
246
247 if (cursor_client_)
248 cursor_client_->UnlockCursor();
249 shell->RemovePreTargetHandler(this);
250 shell->GetScreen()->RemoveObserver(this);
251 UMA_HISTOGRAM_MEDIUM_TIMES(
252 "Ash.WindowSelector.TimeInOverview",
253 base::Time::Now() - overview_start_time_);
254
255 // TODO(nsatragno): Change this to OnOverviewModeEnded and move it to when
256 // everything is done.
257 shell->OnOverviewModeEnding();
258
157 // Clearing the window list resets the ignored_by_shelf flag on the windows. 259 // Clearing the window list resets the ignored_by_shelf flag on the windows.
158 windows_.clear(); 260 windows_.clear();
159 UpdateShelfVisibility(); 261 UpdateShelfVisibility();
160 } 262 }
161 263
162 void WindowSelector::SelectWindow(aura::Window* window) { 264 void WindowSelector::SelectWindow(aura::Window* window) {
163 ResetFocusRestoreWindow(false); 265 ResetFocusRestoreWindow(false);
164 ScopedVector<WindowSelectorItem>::iterator iter = 266 ScopedVector<WindowSelectorItem>::iterator iter =
165 std::find_if(windows_.begin(), windows_.end(), 267 std::find_if(windows_.begin(), windows_.end(),
166 WindowSelectorItemTargetComparator(window)); 268 WindowSelectorItemTargetComparator(window));
167 DCHECK(iter != windows_.end()); 269 DCHECK(iter != windows_.end());
168 // The selected window should not be minimized when window selection is 270 // The selected window should not be minimized when window selection is
169 // ended. 271 // ended.
170 (*iter)->RestoreWindowOnExit(window); 272 (*iter)->RestoreWindowOnExit(window);
171 delegate_->OnWindowSelected(window); 273 delegate_->OnWindowSelected(window);
172 } 274 }
173 275
174 void WindowSelector::CancelSelection() { 276 void WindowSelector::CancelSelection() {
175 delegate_->OnSelectionCanceled(); 277 delegate_->OnSelectionCanceled();
176 } 278 }
177 279
280 void WindowSelector::OnKeyEvent(ui::KeyEvent* event) {
281 if (GetTargetedWindow(static_cast<aura::Window*>(event->target())))
282 event->StopPropagation();
283 if (event->type() != ui::ET_KEY_PRESSED)
284 return;
285
286 if (event->key_code() == ui::VKEY_ESCAPE)
287 CancelSelection();
288 }
289
290 void WindowSelector::OnMouseEvent(ui::MouseEvent* event) {
291 aura::Window* target = GetEventTarget(event);
292 if (!target)
293 return;
294
295 event->SetHandled();
296 if (event->type() != ui::ET_MOUSE_RELEASED)
297 return;
298
299 SelectWindow(target);
300 }
301
302 void WindowSelector::OnScrollEvent(ui::ScrollEvent* event) {
303 // Set the handled flag to prevent delivering scroll events to the window but
304 // still allowing other pretarget handlers to process the scroll event.
305 if (GetTargetedWindow(static_cast<aura::Window*>(event->target())))
306 event->SetHandled();
307 }
308
309 void WindowSelector::OnTouchEvent(ui::TouchEvent* event) {
310 // Existing touches should be allowed to continue. This prevents getting
311 // stuck in a gesture or with pressed fingers being tracked elsewhere.
312 if (event->type() != ui::ET_TOUCH_PRESSED)
313 return;
314
315 aura::Window* target = GetEventTarget(event);
316 if (!target)
317 return;
318
319 // TODO(flackr): StopPropogation prevents generation of gesture events.
320 // We should find a better way to prevent events from being delivered to
321 // the window, perhaps a transparent window in front of the target window
322 // or using EventClientImpl::CanProcessEventsWithinSubtree and then a tap
323 // gesture could be used to activate the window.
324 event->SetHandled();
325 SelectWindow(target);
326 }
327
328 void WindowSelector::OnDisplayBoundsChanged(const gfx::Display& display) {
329 PositionWindows(/* animate */ false);
330 }
331
332 void WindowSelector::OnDisplayAdded(const gfx::Display& display) {
333 }
334
335 void WindowSelector::OnDisplayRemoved(const gfx::Display& display) {
336 }
337
178 void WindowSelector::OnWindowAdded(aura::Window* new_window) { 338 void WindowSelector::OnWindowAdded(aura::Window* new_window) {
179 if (new_window->type() != ui::wm::WINDOW_TYPE_NORMAL && 339 if (new_window->type() != ui::wm::WINDOW_TYPE_NORMAL &&
180 new_window->type() != ui::wm::WINDOW_TYPE_PANEL) { 340 new_window->type() != ui::wm::WINDOW_TYPE_PANEL) {
181 return; 341 return;
182 } 342 }
183 343
184 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { 344 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) {
185 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && 345 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] &&
186 !::wm::GetTransientParent(new_window)) { 346 !::wm::GetTransientParent(new_window)) {
187 // The new window is in one of the switchable containers, abort overview. 347 // The new window is in one of the switchable containers, abort overview.
(...skipping 20 matching lines...) Expand all
208 // If there are still windows in this selector entry then the overview is 368 // If there are still windows in this selector entry then the overview is
209 // still active and the active selection remains the same. 369 // still active and the active selection remains the same.
210 if (!(*iter)->empty()) 370 if (!(*iter)->empty())
211 return; 371 return;
212 372
213 windows_.erase(iter); 373 windows_.erase(iter);
214 if (windows_.empty()) { 374 if (windows_.empty()) {
215 CancelSelection(); 375 CancelSelection();
216 return; 376 return;
217 } 377 }
218 if (window_overview_) 378 PositionWindows(true);
219 window_overview_->OnWindowsChanged();
220 } 379 }
221 380
222 void WindowSelector::OnWindowBoundsChanged(aura::Window* window, 381 void WindowSelector::OnWindowBoundsChanged(aura::Window* window,
223 const gfx::Rect& old_bounds, 382 const gfx::Rect& old_bounds,
224 const gfx::Rect& new_bounds) { 383 const gfx::Rect& new_bounds) {
225 if (!window_overview_)
226 return;
227
228 ScopedVector<WindowSelectorItem>::iterator iter = 384 ScopedVector<WindowSelectorItem>::iterator iter =
229 std::find_if(windows_.begin(), windows_.end(), 385 std::find_if(windows_.begin(), windows_.end(),
230 WindowSelectorItemTargetComparator(window)); 386 WindowSelectorItemTargetComparator(window));
231 if (iter == windows_.end()) 387 if (iter == windows_.end())
232 return; 388 return;
233 389
234 // Immediately finish any active bounds animation. 390 // Immediately finish any active bounds animation.
235 window->layer()->GetAnimator()->StopAnimatingProperty( 391 window->layer()->GetAnimator()->StopAnimatingProperty(
236 ui::LayerAnimationElement::BOUNDS); 392 ui::LayerAnimationElement::BOUNDS);
237 393
(...skipping 13 matching lines...) Expand all
251 void WindowSelector::OnAttemptToReactivateWindow(aura::Window* request_active, 407 void WindowSelector::OnAttemptToReactivateWindow(aura::Window* request_active,
252 aura::Window* actual_active) { 408 aura::Window* actual_active) {
253 if (ignore_activations_) 409 if (ignore_activations_)
254 return; 410 return;
255 // Don't restore focus on exit if a window was just activated. 411 // Don't restore focus on exit if a window was just activated.
256 ResetFocusRestoreWindow(false); 412 ResetFocusRestoreWindow(false);
257 CancelSelection(); 413 CancelSelection();
258 } 414 }
259 415
260 void WindowSelector::StartOverview() { 416 void WindowSelector::StartOverview() {
261 DCHECK(!window_overview_);
262 // Remove focus from active window before entering overview. 417 // Remove focus from active window before entering overview.
263 aura::client::GetFocusClient( 418 aura::client::GetFocusClient(
264 Shell::GetPrimaryRootWindow())->FocusWindow(NULL); 419 Shell::GetPrimaryRootWindow())->FocusWindow(NULL);
265 420
266 window_overview_.reset(new WindowOverview(this, &windows_)); 421 Shell* shell = Shell::GetInstance();
422 shell->OnOverviewModeStarting();
423
424 for (WindowSelectorItemList::iterator iter = windows_.begin();
425 iter != windows_.end(); ++iter) {
426 (*iter)->PrepareForOverview();
427 }
428 PositionWindows(/* animate */ true);
429 DCHECK(!windows_.empty());
430 cursor_client_ = aura::client::GetCursorClient(
431 windows_.front()->GetRootWindow());
432 if (cursor_client_) {
433 cursor_client_->SetCursor(ui::kCursorPointer);
434 cursor_client_->ShowCursor();
435 // TODO(flackr): Only prevent cursor changes for windows in the overview.
436 // This will be easier to do without exposing the overview mode code if the
437 // cursor changes are moved to ToplevelWindowEventHandler::HandleMouseMoved
438 // as suggested there.
439 cursor_client_->LockCursor();
440 }
441 shell->PrependPreTargetHandler(this);
442 shell->GetScreen()->AddObserver(this);
443 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW);
444 HideAndTrackNonOverviewWindows();
445 // Send an a11y alert.
446 shell->accessibility_delegate()->TriggerAccessibilityAlert(
447 A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED);
448
267 UpdateShelfVisibility(); 449 UpdateShelfVisibility();
268 } 450 }
269 451
452 void WindowSelector::PositionWindows(bool animate) {
453 aura::Window::Windows root_window_list = Shell::GetAllRootWindows();
454 for (size_t i = 0; i < root_window_list.size(); ++i)
455 PositionWindowsFromRoot(root_window_list[i], animate);
456 }
457
458 void WindowSelector::PositionWindowsFromRoot(aura::Window* root_window,
459 bool animate) {
460 std::vector<WindowSelectorItem*> windows;
461 for (WindowSelectorItemList::iterator iter = windows_.begin();
462 iter != windows_.end(); ++iter) {
463 if ((*iter)->GetRootWindow() == root_window)
464 windows.push_back(*iter);
465 }
466
467 if (windows.empty())
468 return;
469
470 gfx::Size window_size;
471 gfx::Rect total_bounds = ScreenUtil::ConvertRectToScreen(
472 root_window,
473 ScreenUtil::GetDisplayWorkAreaBoundsInParent(
474 Shell::GetContainer(root_window, kShellWindowId_DefaultContainer)));
475
476 // Find the minimum number of windows per row that will fit all of the
477 // windows on screen.
478 size_t columns = std::max(
479 total_bounds.width() > total_bounds.height() ? kMinCardsMajor : 1,
480 static_cast<int>(ceil(sqrt(total_bounds.width() * windows.size() /
481 (kCardAspectRatio * total_bounds.height())))));
482 size_t rows = ((windows.size() + columns - 1) / columns);
483 window_size.set_width(std::min(
484 static_cast<int>(total_bounds.width() / columns),
485 static_cast<int>(total_bounds.height() * kCardAspectRatio / rows)));
486 window_size.set_height(window_size.width() / kCardAspectRatio);
487
488 // Calculate the X and Y offsets necessary to center the grid.
489 int x_offset = total_bounds.x() + ((windows.size() >= columns ? 0 :
490 (columns - windows.size()) * window_size.width()) +
491 (total_bounds.width() - columns * window_size.width())) / 2;
492 int y_offset = total_bounds.y() + (total_bounds.height() -
493 rows * window_size.height()) / 2;
494 for (size_t i = 0; i < windows.size(); ++i) {
495 gfx::Transform transform;
496 int column = i % columns;
497 int row = i / columns;
498 gfx::Rect target_bounds(window_size.width() * column + x_offset,
499 window_size.height() * row + y_offset,
500 window_size.width(),
501 window_size.height());
502 target_bounds.Inset(kWindowMargin, kWindowMargin);
503 windows[i]->SetBounds(root_window, target_bounds, animate);
504 }
505 }
506
507 void WindowSelector::HideAndTrackNonOverviewWindows() {
508 // Add the windows to hidden_windows first so that if any are destroyed
509 // while hiding them they are tracked.
510 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
511 for (aura::Window::Windows::const_iterator root_iter = root_windows.begin();
512 root_iter != root_windows.end(); ++root_iter) {
513 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) {
514 aura::Window* container = Shell::GetContainer(*root_iter,
515 kSwitchableWindowContainerIds[i]);
516 for (aura::Window::Windows::const_iterator iter =
517 container->children().begin(); iter != container->children().end();
518 ++iter) {
519 if (GetTargetedWindow(*iter) || !(*iter)->IsVisible())
520 continue;
521 hidden_windows_.Add(*iter);
522 }
523 }
524 }
525
526 // Copy the window list as it can change during iteration.
527 const aura::WindowTracker::Windows hidden_windows(hidden_windows_.windows());
528 for (aura::WindowTracker::Windows::const_iterator iter =
529 hidden_windows.begin(); iter != hidden_windows.end(); ++iter) {
530 if (!hidden_windows_.Contains(*iter))
531 continue;
532 ui::ScopedLayerAnimationSettings settings(
533 (*iter)->layer()->GetAnimator());
534 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
535 ScopedTransformOverviewWindow::kTransitionMilliseconds));
536 settings.SetPreemptionStrategy(
537 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
538 (*iter)->Hide();
539 // Hiding the window can result in it being destroyed.
540 if (!hidden_windows_.Contains(*iter))
541 continue;
542 (*iter)->layer()->SetOpacity(0);
543 }
544 }
545
270 void WindowSelector::ResetFocusRestoreWindow(bool focus) { 546 void WindowSelector::ResetFocusRestoreWindow(bool focus) {
271 if (!restore_focus_window_) 547 if (!restore_focus_window_)
272 return; 548 return;
273 if (focus) { 549 if (focus) {
274 base::AutoReset<bool> restoring_focus(&ignore_activations_, true); 550 base::AutoReset<bool> restoring_focus(&ignore_activations_, true);
275 restore_focus_window_->Focus(); 551 restore_focus_window_->Focus();
276 } 552 }
277 // If the window is in the observed_windows_ list it needs to continue to be 553 // If the window is in the observed_windows_ list it needs to continue to be
278 // observed. 554 // observed.
279 if (observed_windows_.find(restore_focus_window_) == 555 if (observed_windows_.find(restore_focus_window_) ==
280 observed_windows_.end()) { 556 observed_windows_.end()) {
281 restore_focus_window_->RemoveObserver(this); 557 restore_focus_window_->RemoveObserver(this);
282 } 558 }
283 restore_focus_window_ = NULL; 559 restore_focus_window_ = NULL;
284 } 560 }
285 561
562 aura::Window* WindowSelector::GetEventTarget(ui::LocatedEvent* event) {
563 aura::Window* target = static_cast<aura::Window*>(event->target());
564 // If the target window doesn't actually contain the event location (i.e.
565 // mouse down over the window and mouse up elsewhere) then do not select the
566 // window.
567 if (!target->ContainsPoint(event->location()))
568 return NULL;
569
570 return GetTargetedWindow(target);
571 }
572
573 aura::Window* WindowSelector::GetTargetedWindow(aura::Window* window) {
574 for (WindowSelectorItemList::iterator iter = windows_.begin();
575 iter != windows_.end(); ++iter) {
576 aura::Window* selected = (*iter)->TargetedWindow(window);
577 if (selected)
578 return selected;
579 }
580 return NULL;
581 }
582
286 } // namespace ash 583 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/overview/window_selector.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698