OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_grid.h" | 5 #include "ash/wm/overview/window_grid.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/ash_switches.h" | 12 #include "ash/ash_switches.h" |
13 #include "ash/screen_util.h" | 13 #include "ash/screen_util.h" |
14 #include "ash/shell.h" | 14 #include "ash/shell.h" |
15 #include "ash/shell_window_ids.h" | 15 #include "ash/shell_window_ids.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_selector.h" | 17 #include "ash/wm/overview/window_selector.h" |
18 #include "ash/wm/overview/window_selector_controller.h" | |
18 #include "ash/wm/overview/window_selector_item.h" | 19 #include "ash/wm/overview/window_selector_item.h" |
19 #include "ash/wm/window_state.h" | 20 #include "ash/wm/window_state.h" |
20 #include "base/command_line.h" | 21 #include "base/command_line.h" |
21 #include "base/i18n/string_search.h" | 22 #include "base/i18n/string_search.h" |
22 #include "base/memory/scoped_vector.h" | 23 #include "base/memory/scoped_vector.h" |
23 #include "third_party/skia/include/core/SkColor.h" | 24 #include "third_party/skia/include/core/SkColor.h" |
25 #include "ui/aura/scoped_window_targeter.h" | |
24 #include "ui/aura/window.h" | 26 #include "ui/aura/window.h" |
27 #include "ui/aura/window_delegate.h" | |
28 #include "ui/aura/window_targeter.h" | |
25 #include "ui/compositor/layer_animation_observer.h" | 29 #include "ui/compositor/layer_animation_observer.h" |
26 #include "ui/compositor/scoped_layer_animation_settings.h" | 30 #include "ui/compositor/scoped_layer_animation_settings.h" |
27 #include "ui/gfx/animation/tween.h" | 31 #include "ui/gfx/animation/tween.h" |
28 #include "ui/gfx/geometry/vector2d.h" | 32 #include "ui/gfx/geometry/vector2d.h" |
29 #include "ui/views/background.h" | 33 #include "ui/views/background.h" |
30 #include "ui/views/view.h" | 34 #include "ui/views/view.h" |
31 #include "ui/views/widget/widget.h" | 35 #include "ui/views/widget/widget.h" |
32 #include "ui/wm/core/window_animations.h" | 36 #include "ui/wm/core/window_animations.h" |
37 #include "ui/wm/core/window_util.h" | |
33 | 38 |
34 namespace ash { | 39 namespace ash { |
35 namespace { | 40 namespace { |
36 | 41 |
37 typedef std::vector<aura::Window*> Windows; | 42 typedef std::vector<aura::Window*> Windows; |
38 | 43 |
39 // An observer which holds onto the passed widget until the animation is | 44 // An observer which holds onto the passed widget until the animation is |
40 // complete. | 45 // complete. |
41 class CleanupWidgetAfterAnimationObserver | 46 class CleanupWidgetAfterAnimationObserver |
42 : public ui::ImplicitAnimationObserver { | 47 : public ui::ImplicitAnimationObserver { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
127 case WindowSelector::UP: | 132 case WindowSelector::UP: |
128 vector.set_y(-bounds.width()); | 133 vector.set_y(-bounds.width()); |
129 break; | 134 break; |
130 case WindowSelector::LEFT: | 135 case WindowSelector::LEFT: |
131 vector.set_x(-bounds.height()); | 136 vector.set_x(-bounds.height()); |
132 break; | 137 break; |
133 } | 138 } |
134 return vector; | 139 return vector; |
135 } | 140 } |
136 | 141 |
142 // Always returns the same target. | |
143 class StaticWindowTargeter : public aura::WindowTargeter { | |
144 public: | |
145 explicit StaticWindowTargeter(aura::Window* target) : target_(target) {} | |
146 ~StaticWindowTargeter() override {} | |
147 | |
148 private: | |
149 // aura::WindowTargeter: | |
150 ui::EventTarget* FindTargetForEvent(ui::EventTarget* root, | |
151 ui::Event* event) override { | |
152 return target_; | |
153 } | |
154 | |
155 ui::EventTarget* FindTargetForLocatedEvent(ui::EventTarget* root, | |
156 ui::LocatedEvent* event) override { | |
157 return target_; | |
158 } | |
159 | |
160 aura::Window* target_; | |
161 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); | |
162 }; | |
163 | |
137 } // namespace | 164 } // namespace |
138 | 165 |
139 WindowGrid::WindowGrid(aura::Window* root_window, | 166 WindowGrid::WindowGrid(aura::Window* root_window, |
140 const std::vector<aura::Window*>& windows, | 167 const std::vector<aura::Window*>& windows, |
141 WindowSelector* window_selector) | 168 WindowSelector* window_selector) |
142 : root_window_(root_window), | 169 : root_window_(root_window), |
143 window_selector_(window_selector) { | 170 window_selector_(window_selector), |
171 static_targeter_container_( | |
172 Shell::GetContainer(root_window_, kShellWindowId_PanelContainer)) { | |
144 WindowSelectorItem* panels_item = nullptr; | 173 WindowSelectorItem* panels_item = nullptr; |
145 | 174 |
146 std::set<aura::Window*> panels_item_windows; | 175 scoped_panel_targeter_.reset( |
147 aura::Window* panels_parent = nullptr; | 176 new aura::ScopedWindowTargeter( |
177 static_targeter_container_, | |
178 scoped_ptr<ui::EventTargeter>( | |
179 new StaticWindowTargeter(static_targeter_container_)))); | |
180 static_targeter_container_->set_target_handler(this); | |
bruthig
2015/01/09 17:04:33
So will all events be consumed by this then? ie E
Nina
2015/01/21 16:24:16
They'll be intercepted, and only handled if they e
| |
148 | 181 |
149 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 182 for (aura::Window::Windows::const_iterator iter = windows.begin(); |
150 iter != windows.end(); ++iter) { | 183 iter != windows.end(); ++iter) { |
151 if ((*iter)->GetRootWindow() != root_window) | 184 if ((*iter)->GetRootWindow() != root_window) |
152 continue; | 185 continue; |
153 (*iter)->AddObserver(this); | 186 (*iter)->AddObserver(this); |
154 observed_windows_.insert(*iter); | 187 observed_windows_.insert(*iter); |
155 | 188 |
156 if ((*iter)->type() == ui::wm::WINDOW_TYPE_PANEL && | 189 if ((*iter)->type() == ui::wm::WINDOW_TYPE_PANEL && |
157 wm::GetWindowState(*iter)->panel_attached()) { | 190 wm::GetWindowState(*iter)->panel_attached()) { |
158 // Attached panel windows are grouped into a single overview item per | 191 // Attached panel windows are grouped into a single overview item per |
159 // grid. | 192 // grid. |
160 if (!panels_item) { | 193 if (!panels_item) { |
161 panels_item = new WindowSelectorItem(root_window_); | 194 panels_item = new WindowSelectorItem(root_window_); |
162 window_list_.push_back(panels_item); | 195 window_list_.push_back(panels_item); |
163 } | 196 } |
164 DCHECK(panels_parent == nullptr || panels_parent == (*iter)->parent()); | 197 panels_item->AddWindow(*iter); |
165 panels_parent = (*iter)->parent(); | |
166 panels_item_windows.insert(*iter); | |
167 } else { | 198 } else { |
168 WindowSelectorItem* selector_item = new WindowSelectorItem(root_window_); | 199 WindowSelectorItem* selector_item = new WindowSelectorItem(root_window_); |
169 window_list_.push_back(selector_item); | 200 window_list_.push_back(selector_item); |
170 selector_item->AddWindow(*iter); | 201 selector_item->AddWindow(*iter); |
171 } | 202 } |
172 } | 203 } |
173 | |
174 if (panels_item) { | |
175 // Sort and add panel windows in reverse z order to the WindowSelectorItem | |
176 // so that the transparent overlays are in the proper order. | |
177 | |
178 CHECK_GT(panels_item_windows.size(), 0u); | |
179 | |
180 const Windows& children = panels_parent->children(); | |
181 for (Windows::const_reverse_iterator iter = children.rbegin(); | |
182 iter != children.rend(); ++iter) { | |
183 if (panels_item_windows.find(*iter) != panels_item_windows.end()) | |
184 panels_item->AddWindow(*iter); | |
185 } | |
186 } | |
187 } | 204 } |
188 | 205 |
189 WindowGrid::~WindowGrid() { | 206 WindowGrid::~WindowGrid() { |
207 static_targeter_container_->set_target_handler( | |
208 static_targeter_container_->delegate()); | |
209 | |
190 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin(); | 210 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin(); |
191 iter != observed_windows_.end(); iter++) { | 211 iter != observed_windows_.end(); iter++) { |
192 (*iter)->RemoveObserver(this); | 212 (*iter)->RemoveObserver(this); |
193 } | 213 } |
194 } | 214 } |
195 | 215 |
196 void WindowGrid::PrepareForOverview() { | 216 void WindowGrid::PrepareForOverview() { |
197 for (ScopedVector<WindowSelectorItem>::iterator iter = window_list_.begin(); | 217 for (ScopedVector<WindowSelectorItem>::iterator iter = window_list_.begin(); |
198 iter != window_list_.end(); ++iter) { | 218 iter != window_list_.end(); ++iter) { |
199 (*iter)->PrepareForOverview(); | 219 (*iter)->PrepareForOverview(); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
399 DCHECK(iter != window_list_.end()); | 419 DCHECK(iter != window_list_.end()); |
400 | 420 |
401 // Immediately finish any active bounds animation. | 421 // Immediately finish any active bounds animation. |
402 window->layer()->GetAnimator()->StopAnimatingProperty( | 422 window->layer()->GetAnimator()->StopAnimatingProperty( |
403 ui::LayerAnimationElement::BOUNDS); | 423 ui::LayerAnimationElement::BOUNDS); |
404 | 424 |
405 // Recompute the transform for the window. | 425 // Recompute the transform for the window. |
406 (*iter)->RecomputeWindowTransforms(); | 426 (*iter)->RecomputeWindowTransforms(); |
407 } | 427 } |
408 | 428 |
429 // ui::EventHandler: | |
430 void WindowGrid::OnMouseEvent(ui::MouseEvent* mouse) { | |
431 if (mouse->type() != ui::ET_MOUSE_PRESSED) | |
432 return; | |
433 HandleTap(mouse); | |
434 } | |
435 | |
436 void WindowGrid::OnGestureEvent(ui::GestureEvent* gesture) { | |
437 if (gesture->type() != ui::ET_GESTURE_TAP) | |
438 return; | |
439 HandleTap(gesture); | |
440 } | |
441 | |
442 void WindowGrid::HandleTap(ui::LocatedEvent* event) const { | |
443 aura::Window* selected_window = GetWindowAt(event, | |
444 Shell::GetContainer(root_window_, kShellWindowId_PanelContainer)); | |
445 | |
446 if (!selected_window) { | |
447 selected_window = GetWindowAt(event, | |
448 Shell::GetContainer(root_window_, kShellWindowId_DefaultContainer)); | |
449 if (!selected_window) { | |
450 ash::Shell::GetInstance()-> | |
451 window_selector_controller()->ToggleOverview(); | |
452 return; | |
453 } | |
454 } | |
455 event->SetHandled(); | |
456 wm::GetWindowState(selected_window)->Activate(); | |
bruthig
2015/01/09 17:04:33
How difficult would it be to move the window activ
Nina
2015/01/21 16:24:16
We would have to search for the WindowSelectorItem
| |
457 } | |
458 | |
409 void WindowGrid::InitSelectionWidget(WindowSelector::Direction direction) { | 459 void WindowGrid::InitSelectionWidget(WindowSelector::Direction direction) { |
410 selection_widget_.reset(new views::Widget); | 460 selection_widget_.reset(new views::Widget); |
411 views::Widget::InitParams params; | 461 views::Widget::InitParams params; |
412 params.type = views::Widget::InitParams::TYPE_POPUP; | 462 params.type = views::Widget::InitParams::TYPE_POPUP; |
413 params.keep_on_top = false; | 463 params.keep_on_top = false; |
414 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 464 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
415 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 465 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
416 params.parent = Shell::GetContainer(root_window_, | 466 params.parent = Shell::GetContainer(root_window_, |
417 kShellWindowId_DefaultContainer); | 467 kShellWindowId_DefaultContainer); |
418 params.accept_events = false; | 468 params.accept_events = false; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
475 old_selection->Hide(); | 525 old_selection->Hide(); |
476 } | 526 } |
477 if (out_of_bounds) | 527 if (out_of_bounds) |
478 return; | 528 return; |
479 | 529 |
480 if (!selection_widget_) | 530 if (!selection_widget_) |
481 InitSelectionWidget(direction); | 531 InitSelectionWidget(direction); |
482 // Send an a11y alert so that if ChromeVox is enabled, the item label is | 532 // Send an a11y alert so that if ChromeVox is enabled, the item label is |
483 // read. | 533 // read. |
484 SelectedWindow()->SendFocusAlert(); | 534 SelectedWindow()->SendFocusAlert(); |
535 | |
485 // The selection widget is moved to the newly selected item in the same | 536 // The selection widget is moved to the newly selected item in the same |
486 // grid. | 537 // grid. |
487 MoveSelectionWidgetToTarget(animate); | 538 MoveSelectionWidgetToTarget(animate); |
488 } | 539 } |
489 | 540 |
490 void WindowGrid::MoveSelectionWidgetToTarget(bool animate) { | 541 void WindowGrid::MoveSelectionWidgetToTarget(bool animate) { |
491 if (animate) { | 542 if (animate) { |
492 ui::ScopedLayerAnimationSettings animation_settings( | 543 ui::ScopedLayerAnimationSettings animation_settings( |
493 selection_widget_->GetNativeWindow()->layer()->GetAnimator()); | 544 selection_widget_->GetNativeWindow()->layer()->GetAnimator()); |
494 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( | 545 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( |
495 kOverviewSelectorTransitionMilliseconds)); | 546 kOverviewSelectorTransitionMilliseconds)); |
496 animation_settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); | 547 animation_settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); |
497 animation_settings.SetPreemptionStrategy( | 548 animation_settings.SetPreemptionStrategy( |
498 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 549 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
499 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); | 550 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); |
500 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); | 551 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); |
501 return; | 552 return; |
502 } | 553 } |
503 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); | 554 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); |
504 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); | 555 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); |
505 } | 556 } |
506 | 557 |
558 aura::Window* WindowGrid::GetWindowAt(ui::LocatedEvent* event, | |
559 aura::Window* container) const { | |
560 // Find the old targeter to find the target of the event. | |
561 ui::EventTargeter* targeter; | |
562 if (container == static_targeter_container_) | |
563 targeter = scoped_panel_targeter_->old_targeter(); | |
564 else | |
565 targeter = container->GetEventTargeter(); | |
566 | |
567 ui::EventTarget* window = container; | |
568 while (!targeter && window->GetParentTarget()) { | |
569 window = window->GetParentTarget(); | |
570 targeter = window->GetEventTargeter(); | |
571 } | |
572 if (!targeter) | |
573 return nullptr; | |
574 | |
575 aura::Window* target = static_cast<aura::Window*>( | |
576 targeter->FindTargetForLocatedEvent(container, event)); | |
577 if (target == container) | |
578 return nullptr; | |
579 | |
580 while (target && target->parent() != container) | |
581 target = target->parent(); | |
582 aura::Window* transient_parent = | |
583 target ? ::wm::GetTransientParent(target) : nullptr; | |
584 | |
585 return transient_parent ? transient_parent : target; | |
586 } | |
587 | |
507 } // namespace ash | 588 } // namespace ash |
OLD | NEW |