Chromium Code Reviews| 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 <utility> | 10 #include <utility> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "ash/ash_switches.h" | 13 #include "ash/ash_switches.h" |
| 14 #include "ash/screen_util.h" | |
| 15 #include "ash/shell.h" | |
| 16 #include "ash/shell_window_ids.h" | |
| 17 #include "ash/wm/common/window_state.h" | 14 #include "ash/wm/common/window_state.h" |
| 15 #include "ash/wm/common/wm_lookup.h" | |
| 16 #include "ash/wm/common/wm_root_window_controller.h" | |
| 17 #include "ash/wm/common/wm_screen_util.h" | |
| 18 #include "ash/wm/common/wm_shell_window_ids.h" | |
| 19 #include "ash/wm/common/wm_window.h" | |
| 18 #include "ash/wm/overview/scoped_transform_overview_window.h" | 20 #include "ash/wm/overview/scoped_transform_overview_window.h" |
| 19 #include "ash/wm/overview/window_selector.h" | 21 #include "ash/wm/overview/window_selector.h" |
| 20 #include "ash/wm/overview/window_selector_item.h" | 22 #include "ash/wm/overview/window_selector_item.h" |
| 21 #include "ash/wm/window_state_aura.h" | |
| 22 #include "base/command_line.h" | 23 #include "base/command_line.h" |
| 23 #include "base/i18n/string_search.h" | 24 #include "base/i18n/string_search.h" |
| 24 #include "base/memory/scoped_vector.h" | 25 #include "base/memory/scoped_vector.h" |
| 25 #include "third_party/skia/include/core/SkColor.h" | 26 #include "third_party/skia/include/core/SkColor.h" |
| 26 #include "ui/aura/window.h" | |
| 27 #include "ui/compositor/layer_animation_observer.h" | 27 #include "ui/compositor/layer_animation_observer.h" |
| 28 #include "ui/compositor/scoped_layer_animation_settings.h" | 28 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 29 #include "ui/display/display.h" | 29 #include "ui/display/display.h" |
| 30 #include "ui/display/screen.h" | |
| 30 #include "ui/gfx/animation/tween.h" | 31 #include "ui/gfx/animation/tween.h" |
| 31 #include "ui/gfx/geometry/vector2d.h" | 32 #include "ui/gfx/geometry/vector2d.h" |
| 32 #include "ui/views/background.h" | 33 #include "ui/views/background.h" |
| 33 #include "ui/views/border.h" | 34 #include "ui/views/border.h" |
| 34 #include "ui/views/view.h" | 35 #include "ui/views/view.h" |
| 35 #include "ui/views/widget/widget.h" | 36 #include "ui/views/widget/widget.h" |
| 36 #include "ui/wm/core/window_animations.h" | 37 #include "ui/wm/core/window_animations.h" |
| 37 | 38 |
| 38 namespace ash { | 39 namespace ash { |
| 39 namespace { | 40 namespace { |
| 40 | 41 |
| 41 typedef std::vector<aura::Window*> Windows; | 42 using Windows = std::vector<wm::WmWindow*>; |
| 42 | 43 |
| 43 // 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 |
| 44 // complete. | 45 // complete. |
| 45 class CleanupWidgetAfterAnimationObserver | 46 class CleanupWidgetAfterAnimationObserver |
| 46 : public ui::ImplicitAnimationObserver { | 47 : public ui::ImplicitAnimationObserver { |
| 47 public: | 48 public: |
| 48 explicit CleanupWidgetAfterAnimationObserver( | 49 explicit CleanupWidgetAfterAnimationObserver( |
| 49 std::unique_ptr<views::Widget> widget); | 50 std::unique_ptr<views::Widget> widget); |
| 50 ~CleanupWidgetAfterAnimationObserver() override; | 51 ~CleanupWidgetAfterAnimationObserver() override; |
| 51 | 52 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 64 | 65 |
| 65 CleanupWidgetAfterAnimationObserver::~CleanupWidgetAfterAnimationObserver() { | 66 CleanupWidgetAfterAnimationObserver::~CleanupWidgetAfterAnimationObserver() { |
| 66 } | 67 } |
| 67 | 68 |
| 68 void CleanupWidgetAfterAnimationObserver::OnImplicitAnimationsCompleted() { | 69 void CleanupWidgetAfterAnimationObserver::OnImplicitAnimationsCompleted() { |
| 69 delete this; | 70 delete this; |
| 70 } | 71 } |
| 71 | 72 |
| 72 // A comparator for locating a given target window. | 73 // A comparator for locating a given target window. |
| 73 struct WindowSelectorItemComparator { | 74 struct WindowSelectorItemComparator { |
| 74 explicit WindowSelectorItemComparator(const aura::Window* target_window) | 75 explicit WindowSelectorItemComparator(const wm::WmWindow* target_window) |
| 75 : target(target_window) { | 76 : target(target_window) {} |
| 76 } | |
| 77 | 77 |
| 78 bool operator()(WindowSelectorItem* window) const { | 78 bool operator()(WindowSelectorItem* window) const { |
| 79 return window->GetWindow() == target; | 79 return window->GetWindow() == target; |
| 80 } | 80 } |
| 81 | 81 |
| 82 const aura::Window* target; | 82 const wm::WmWindow* target; |
| 83 }; | 83 }; |
| 84 | 84 |
| 85 // Conceptually the window overview is a table or grid of cells having this | 85 // Conceptually the window overview is a table or grid of cells having this |
| 86 // fixed aspect ratio. The number of columns is determined by maximizing the | 86 // fixed aspect ratio. The number of columns is determined by maximizing the |
| 87 // area of them based on the number of window_list. | 87 // area of them based on the number of window_list. |
| 88 const float kCardAspectRatio = 4.0f / 3.0f; | 88 const float kCardAspectRatio = 4.0f / 3.0f; |
| 89 | 89 |
| 90 // The minimum number of cards along the major axis (i.e. horizontally on a | 90 // The minimum number of cards along the major axis (i.e. horizontally on a |
| 91 // landscape orientation). | 91 // landscape orientation). |
| 92 const int kMinCardsMajor = 3; | 92 const int kMinCardsMajor = 3; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 120 vector.set_x(-bounds.height()); | 120 vector.set_x(-bounds.height()); |
| 121 break; | 121 break; |
| 122 } | 122 } |
| 123 return vector; | 123 return vector; |
| 124 } | 124 } |
| 125 | 125 |
| 126 // Given |root_window|, calculates the item size necessary to fit |items| | 126 // Given |root_window|, calculates the item size necessary to fit |items| |
| 127 // items in the window selection. |bounding_rect| is set to the centered | 127 // items in the window selection. |bounding_rect| is set to the centered |
| 128 // rectangle containing the grid and |item_size| is set to the size of each | 128 // rectangle containing the grid and |item_size| is set to the size of each |
| 129 // individual item. | 129 // individual item. |
| 130 void CalculateOverviewSizes(aura::Window* root_window, | 130 void CalculateOverviewSizes(wm::WmWindow* root_window, |
| 131 size_t items, | 131 size_t items, |
| 132 gfx::Rect* bounding_rect, | 132 gfx::Rect* bounding_rect, |
| 133 gfx::Size* item_size) { | 133 gfx::Size* item_size) { |
| 134 gfx::Rect total_bounds = ScreenUtil::ConvertRectToScreen( | 134 gfx::Rect total_bounds = root_window->ConvertRectToScreen( |
| 135 root_window, | 135 wm::GetDisplayWorkAreaBoundsInParent(root_window->GetChildByShellWindowId( |
| 136 ScreenUtil::GetDisplayWorkAreaBoundsInParent( | 136 kShellWindowId_DefaultContainer))); |
| 137 Shell::GetContainer(root_window, kShellWindowId_DefaultContainer))); | |
| 138 | 137 |
| 139 // Reserve space at the top for the text filtering textbox to appear. | 138 // Reserve space at the top for the text filtering textbox to appear. |
| 140 total_bounds.Inset( | 139 total_bounds.Inset( |
| 141 0, WindowSelector::kTextFilterBottomEdge + kTextFilterBottomMargin, 0, 0); | 140 0, WindowSelector::kTextFilterBottomEdge + kTextFilterBottomMargin, 0, 0); |
| 142 | 141 |
| 143 // Find the minimum number of windows per row that will fit all of the | 142 // Find the minimum number of windows per row that will fit all of the |
| 144 // windows on screen. | 143 // windows on screen. |
| 145 int num_columns = std::max( | 144 int num_columns = std::max( |
| 146 total_bounds.width() > total_bounds.height() ? kMinCardsMajor : 1, | 145 total_bounds.width() > total_bounds.height() ? kMinCardsMajor : 1, |
| 147 static_cast<int>(ceil(sqrt(total_bounds.width() * items / | 146 static_cast<int>(ceil(sqrt(total_bounds.width() * items / |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 161 bounding_rect->set_x(total_bounds.x() + | 160 bounding_rect->set_x(total_bounds.x() + |
| 162 (total_bounds.width() - bounding_rect->width()) / 2); | 161 (total_bounds.width() - bounding_rect->width()) / 2); |
| 163 bounding_rect->set_y(total_bounds.y() + | 162 bounding_rect->set_y(total_bounds.y() + |
| 164 (total_bounds.height() - bounding_rect->height()) / 2); | 163 (total_bounds.height() - bounding_rect->height()) / 2); |
| 165 } | 164 } |
| 166 | 165 |
| 167 // Reorders the list of windows |items| in |root_window| in an attempt to | 166 // Reorders the list of windows |items| in |root_window| in an attempt to |
| 168 // minimize the distance each window will travel to enter overview. For | 167 // minimize the distance each window will travel to enter overview. For |
| 169 // equidistant windows preserves a stable order between overview sessions | 168 // equidistant windows preserves a stable order between overview sessions |
| 170 // by comparing window pointers. | 169 // by comparing window pointers. |
| 171 void ReorderItemsGreedyLeastMovement(std::vector<aura::Window*>* items, | 170 void ReorderItemsGreedyLeastMovement(std::vector<wm::WmWindow*>* items, |
| 172 aura::Window* root_window) { | 171 wm::WmWindow* root_window) { |
| 173 if (items->empty()) | 172 if (items->empty()) |
| 174 return; | 173 return; |
| 175 gfx::Rect bounding_rect; | 174 gfx::Rect bounding_rect; |
| 176 gfx::Size item_size; | 175 gfx::Size item_size; |
| 177 CalculateOverviewSizes(root_window, items->size(), &bounding_rect, | 176 CalculateOverviewSizes(root_window, items->size(), &bounding_rect, |
| 178 &item_size); | 177 &item_size); |
| 179 int num_columns = std::min(static_cast<int>(items->size()), | 178 int num_columns = std::min(static_cast<int>(items->size()), |
| 180 bounding_rect.width() / item_size.width()); | 179 bounding_rect.width() / item_size.width()); |
| 181 for (size_t i = 0; i < items->size(); ++i) { | 180 for (size_t i = 0; i < items->size(); ++i) { |
| 182 int column = i % num_columns; | 181 int column = i % num_columns; |
| 183 int row = i / num_columns; | 182 int row = i / num_columns; |
| 184 gfx::Point overview_item_center( | 183 gfx::Point overview_item_center( |
| 185 bounding_rect.x() + column * item_size.width() + item_size.width() / 2, | 184 bounding_rect.x() + column * item_size.width() + item_size.width() / 2, |
| 186 bounding_rect.y() + row * item_size.height() + item_size.height() / 2); | 185 bounding_rect.y() + row * item_size.height() + item_size.height() / 2); |
| 187 // Find the nearest window for this position. | 186 // Find the nearest window for this position. |
| 188 size_t swap_index = i; | 187 size_t swap_index = i; |
| 189 int64_t shortest_distance = std::numeric_limits<int64_t>::max(); | 188 int64_t shortest_distance = std::numeric_limits<int64_t>::max(); |
| 190 for (size_t j = i; j < items->size(); ++j) { | 189 for (size_t j = i; j < items->size(); ++j) { |
| 191 aura::Window* window = (*items)[j]; | 190 wm::WmWindow* window = (*items)[j]; |
| 192 int64_t distance = | 191 int64_t distance = (window->ConvertRectToScreen(window->GetTargetBounds()) |
|
James Cook
2016/05/27 00:02:51
optional: I know this is clang-format, and I know
sky
2016/05/27 03:18:04
I split it into two.
| |
| 193 (ScreenUtil::ConvertRectToScreen(window, window->GetTargetBounds()) | 192 .CenterPoint() - |
| 194 .CenterPoint() - | 193 overview_item_center) |
| 195 overview_item_center) | 194 .LengthSquared(); |
| 196 .LengthSquared(); | |
| 197 // We compare raw pointers to create a stable ordering given two windows | 195 // We compare raw pointers to create a stable ordering given two windows |
| 198 // with the same center point. | 196 // with the same center point. |
| 199 if (distance < shortest_distance || | 197 if (distance < shortest_distance || |
| 200 (distance == shortest_distance && window < (*items)[swap_index])) { | 198 (distance == shortest_distance && window < (*items)[swap_index])) { |
| 201 shortest_distance = distance; | 199 shortest_distance = distance; |
| 202 swap_index = j; | 200 swap_index = j; |
| 203 } | 201 } |
| 204 } | 202 } |
| 205 if (swap_index > i) | 203 if (swap_index > i) |
| 206 std::swap((*items)[i], (*items)[swap_index]); | 204 std::swap((*items)[i], (*items)[swap_index]); |
| 207 } | 205 } |
| 208 } | 206 } |
| 209 | 207 |
| 210 } // namespace | 208 } // namespace |
| 211 | 209 |
| 212 WindowGrid::WindowGrid(aura::Window* root_window, | 210 WindowGrid::WindowGrid(wm::WmWindow* root_window, |
| 213 const std::vector<aura::Window*>& windows, | 211 const std::vector<wm::WmWindow*>& windows, |
| 214 WindowSelector* window_selector) | 212 WindowSelector* window_selector) |
| 215 : root_window_(root_window), | 213 : root_window_(root_window), window_selector_(window_selector) { |
| 216 window_selector_(window_selector) { | 214 std::vector<wm::WmWindow*> windows_in_root; |
| 217 std::vector<aura::Window*> windows_in_root; | |
| 218 for (auto window : windows) { | 215 for (auto window : windows) { |
| 219 if (window->GetRootWindow() == root_window) | 216 if (window->GetRootWindow() == root_window) |
| 220 windows_in_root.push_back(window); | 217 windows_in_root.push_back(window); |
| 221 } | 218 } |
| 222 | 219 |
| 223 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 220 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 224 switches::kAshEnableStableOverviewOrder)) { | 221 switches::kAshEnableStableOverviewOrder)) { |
| 225 // Reorder windows to try to minimize movement to target overview positions. | 222 // Reorder windows to try to minimize movement to target overview positions. |
| 226 // This also creates a stable window ordering. | 223 // This also creates a stable window ordering. |
| 227 ReorderItemsGreedyLeastMovement(&windows_in_root, root_window_); | 224 ReorderItemsGreedyLeastMovement(&windows_in_root, root_window_); |
| 228 } | 225 } |
| 229 for (auto window : windows_in_root) { | 226 for (auto window : windows_in_root) { |
| 230 window->AddObserver(this); | 227 window->AddObserver(this); |
| 231 observed_windows_.insert(window); | 228 observed_windows_.insert(window); |
| 232 window_list_.push_back(new WindowSelectorItem(window, window_selector_)); | 229 window_list_.push_back(new WindowSelectorItem(window, window_selector_)); |
| 233 } | 230 } |
| 234 } | 231 } |
| 235 | 232 |
| 236 WindowGrid::~WindowGrid() { | 233 WindowGrid::~WindowGrid() { |
| 237 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin(); | 234 for (wm::WmWindow* window : observed_windows_) |
| 238 iter != observed_windows_.end(); iter++) { | 235 window->RemoveObserver(this); |
| 239 (*iter)->RemoveObserver(this); | |
| 240 } | |
| 241 } | 236 } |
| 242 | 237 |
| 243 void WindowGrid::PrepareForOverview() { | 238 void WindowGrid::PrepareForOverview() { |
| 244 for (ScopedVector<WindowSelectorItem>::iterator iter = window_list_.begin(); | 239 for (auto iter = window_list_.begin(); iter != window_list_.end(); ++iter) |
| 245 iter != window_list_.end(); ++iter) { | |
| 246 (*iter)->PrepareForOverview(); | 240 (*iter)->PrepareForOverview(); |
| 247 } | |
| 248 } | 241 } |
| 249 | 242 |
| 250 void WindowGrid::PositionWindows(bool animate) { | 243 void WindowGrid::PositionWindows(bool animate) { |
| 251 CHECK(!window_list_.empty()); | 244 CHECK(!window_list_.empty()); |
| 252 gfx::Rect bounding_rect; | 245 gfx::Rect bounding_rect; |
| 253 gfx::Size item_size; | 246 gfx::Size item_size; |
| 254 CalculateOverviewSizes(root_window_, window_list_.size(), &bounding_rect, | 247 CalculateOverviewSizes(root_window_, window_list_.size(), &bounding_rect, |
| 255 &item_size); | 248 &item_size); |
| 256 num_columns_ = std::min(static_cast<int>(window_list_.size()), | 249 num_columns_ = std::min(static_cast<int>(window_list_.size()), |
| 257 bounding_rect.width() / item_size.width()); | 250 bounding_rect.width() / item_size.width()); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 return out_of_bounds; | 331 return out_of_bounds; |
| 339 } | 332 } |
| 340 | 333 |
| 341 WindowSelectorItem* WindowGrid::SelectedWindow() const { | 334 WindowSelectorItem* WindowGrid::SelectedWindow() const { |
| 342 if (!selection_widget_) | 335 if (!selection_widget_) |
| 343 return nullptr; | 336 return nullptr; |
| 344 CHECK(selected_index_ < window_list_.size()); | 337 CHECK(selected_index_ < window_list_.size()); |
| 345 return window_list_[selected_index_]; | 338 return window_list_[selected_index_]; |
| 346 } | 339 } |
| 347 | 340 |
| 348 bool WindowGrid::Contains(const aura::Window* window) const { | 341 bool WindowGrid::Contains(const wm::WmWindow* window) const { |
| 349 for (const WindowSelectorItem* window_item : window_list_) { | 342 for (const WindowSelectorItem* window_item : window_list_) { |
| 350 if (window_item->Contains(window)) | 343 if (window_item->Contains(window)) |
| 351 return true; | 344 return true; |
| 352 } | 345 } |
| 353 return false; | 346 return false; |
| 354 } | 347 } |
| 355 | 348 |
| 356 void WindowGrid::FilterItems(const base::string16& pattern) { | 349 void WindowGrid::FilterItems(const base::string16& pattern) { |
| 357 base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents finder(pattern); | 350 base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents finder(pattern); |
| 358 for (ScopedVector<WindowSelectorItem>::iterator iter = window_list_.begin(); | 351 for (auto iter = window_list_.begin(); iter != window_list_.end(); iter++) { |
| 359 iter != window_list_.end(); iter++) { | 352 if (finder.Search((*iter)->GetWindow()->GetTitle(), nullptr, nullptr)) { |
| 360 if (finder.Search((*iter)->GetWindow()->title(), nullptr, nullptr)) { | |
| 361 (*iter)->SetDimmed(false); | 353 (*iter)->SetDimmed(false); |
| 362 } else { | 354 } else { |
| 363 (*iter)->SetDimmed(true); | 355 (*iter)->SetDimmed(true); |
| 364 if (selection_widget_ && SelectedWindow() == *iter) | 356 if (selection_widget_ && SelectedWindow() == *iter) |
| 365 selection_widget_.reset(); | 357 selection_widget_.reset(); |
| 366 } | 358 } |
| 367 } | 359 } |
| 368 } | 360 } |
| 369 | 361 |
| 370 void WindowGrid::OnWindowDestroying(aura::Window* window) { | 362 void WindowGrid::OnWindowDestroying(wm::WmWindow* window) { |
| 371 window->RemoveObserver(this); | 363 window->RemoveObserver(this); |
| 372 observed_windows_.erase(window); | 364 observed_windows_.erase(window); |
| 373 ScopedVector<WindowSelectorItem>::iterator iter = | 365 ScopedVector<WindowSelectorItem>::iterator iter = |
| 374 std::find_if(window_list_.begin(), window_list_.end(), | 366 std::find_if(window_list_.begin(), window_list_.end(), |
| 375 WindowSelectorItemComparator(window)); | 367 WindowSelectorItemComparator(window)); |
| 376 | 368 |
| 377 DCHECK(iter != window_list_.end()); | 369 DCHECK(iter != window_list_.end()); |
| 378 | 370 |
| 379 size_t removed_index = iter - window_list_.begin(); | 371 size_t removed_index = iter - window_list_.begin(); |
| 380 window_list_.erase(iter); | 372 window_list_.erase(iter); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 391 bool send_focus_alert = selected_index_ == removed_index; | 383 bool send_focus_alert = selected_index_ == removed_index; |
| 392 if (selected_index_ >= removed_index && selected_index_ != 0) | 384 if (selected_index_ >= removed_index && selected_index_ != 0) |
| 393 selected_index_--; | 385 selected_index_--; |
| 394 if (send_focus_alert) | 386 if (send_focus_alert) |
| 395 SelectedWindow()->SendAccessibleSelectionEvent(); | 387 SelectedWindow()->SendAccessibleSelectionEvent(); |
| 396 } | 388 } |
| 397 | 389 |
| 398 PositionWindows(true); | 390 PositionWindows(true); |
| 399 } | 391 } |
| 400 | 392 |
| 401 void WindowGrid::OnWindowBoundsChanged(aura::Window* window, | 393 void WindowGrid::OnWindowBoundsChanged(wm::WmWindow* window, |
| 402 const gfx::Rect& old_bounds, | 394 const gfx::Rect& old_bounds, |
| 403 const gfx::Rect& new_bounds) { | 395 const gfx::Rect& new_bounds) { |
| 404 ScopedVector<WindowSelectorItem>::const_iterator iter = | 396 auto iter = std::find_if(window_list_.begin(), window_list_.end(), |
| 405 std::find_if(window_list_.begin(), window_list_.end(), | 397 WindowSelectorItemComparator(window)); |
| 406 WindowSelectorItemComparator(window)); | |
| 407 DCHECK(iter != window_list_.end()); | 398 DCHECK(iter != window_list_.end()); |
| 408 | 399 |
| 409 // Immediately finish any active bounds animation. | 400 // Immediately finish any active bounds animation. |
| 410 window->layer()->GetAnimator()->StopAnimatingProperty( | 401 window->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS); |
| 411 ui::LayerAnimationElement::BOUNDS); | |
| 412 | 402 |
| 413 // Recompute the transform for the window. | 403 // Recompute the transform for the window. |
| 414 (*iter)->RecomputeWindowTransforms(); | 404 (*iter)->RecomputeWindowTransforms(); |
| 415 } | 405 } |
| 416 | 406 |
| 417 void WindowGrid::InitSelectionWidget(WindowSelector::Direction direction) { | 407 void WindowGrid::InitSelectionWidget(WindowSelector::Direction direction) { |
| 418 selection_widget_.reset(new views::Widget); | 408 selection_widget_.reset(new views::Widget); |
| 419 views::Widget::InitParams params; | 409 views::Widget::InitParams params; |
| 420 params.type = views::Widget::InitParams::TYPE_POPUP; | 410 params.type = views::Widget::InitParams::TYPE_POPUP; |
| 421 params.keep_on_top = false; | 411 params.keep_on_top = false; |
| 422 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 412 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 423 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 413 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 424 params.parent = Shell::GetContainer(root_window_, | |
| 425 kShellWindowId_DefaultContainer); | |
| 426 params.accept_events = false; | 414 params.accept_events = false; |
| 427 selection_widget_->set_focus_on_creation(false); | 415 selection_widget_->set_focus_on_creation(false); |
| 416 root_window_->GetRootWindowController() | |
| 417 ->ConfigureWidgetInitParamsForContainer( | |
| 418 selection_widget_.get(), kShellWindowId_DefaultContainer, ¶ms); | |
| 428 selection_widget_->Init(params); | 419 selection_widget_->Init(params); |
| 420 wm::WmWindow* selection_widget_window = | |
| 421 wm::WmLookup::Get()->GetWindowForWidget(selection_widget_.get()); | |
| 429 // Disable the "bounce in" animation when showing the window. | 422 // Disable the "bounce in" animation when showing the window. |
| 430 ::wm::SetWindowVisibilityAnimationTransition( | 423 selection_widget_window->SetVisibilityAnimationTransition(::wm::ANIMATE_NONE); |
| 431 selection_widget_->GetNativeWindow(), ::wm::ANIMATE_NONE); | |
| 432 // The selection widget should not activate the shelf when passing under it. | 424 // The selection widget should not activate the shelf when passing under it. |
| 433 wm::GetWindowState(selection_widget_->GetNativeWindow())-> | 425 selection_widget_window->GetWindowState()->set_ignored_by_shelf(true); |
| 434 set_ignored_by_shelf(true); | |
| 435 | 426 |
| 436 views::View* content_view = new views::View; | 427 views::View* content_view = new views::View; |
| 437 content_view->set_background( | 428 content_view->set_background( |
| 438 views::Background::CreateSolidBackground(kWindowSelectionColor)); | 429 views::Background::CreateSolidBackground(kWindowSelectionColor)); |
| 439 content_view->SetBorder(views::Border::CreateSolidBorder( | 430 content_view->SetBorder(views::Border::CreateSolidBorder( |
| 440 kWindowSelectionBorderThickness, kWindowSelectionBorderColor)); | 431 kWindowSelectionBorderThickness, kWindowSelectionBorderColor)); |
| 441 selection_widget_->SetContentsView(content_view); | 432 selection_widget_->SetContentsView(content_view); |
| 442 selection_widget_->GetNativeWindow()->parent()->StackChildAtBottom( | 433 selection_widget_window->GetParent()->StackChildAtBottom( |
| 443 selection_widget_->GetNativeWindow()); | 434 selection_widget_window); |
| 444 selection_widget_->Show(); | 435 selection_widget_->Show(); |
| 445 // New selection widget starts with 0 opacity and then fades in. | 436 // New selection widget starts with 0 opacity and then fades in. |
| 446 selection_widget_->GetNativeWindow()->layer()->SetOpacity(0); | 437 selection_widget_window->SetOpacity(0); |
| 447 | 438 |
| 448 const gfx::Rect target_bounds = SelectedWindow()->target_bounds(); | 439 const gfx::Rect target_bounds = SelectedWindow()->target_bounds(); |
| 449 gfx::Vector2d fade_out_direction = | 440 gfx::Vector2d fade_out_direction = |
| 450 GetSlideVectorForFadeIn(direction, target_bounds); | 441 GetSlideVectorForFadeIn(direction, target_bounds); |
| 451 display::Display dst_display = | 442 display::Display dst_display = |
| 452 display::Screen::GetScreen()->GetDisplayMatching(target_bounds); | 443 display::Screen::GetScreen()->GetDisplayMatching(target_bounds); |
| 453 selection_widget_->GetNativeWindow()->SetBoundsInScreen( | 444 selection_widget_window->SetBoundsInScreen(target_bounds - fade_out_direction, |
| 454 target_bounds - fade_out_direction, dst_display); | 445 dst_display); |
| 455 } | 446 } |
| 456 | 447 |
| 457 void WindowGrid::MoveSelectionWidget(WindowSelector::Direction direction, | 448 void WindowGrid::MoveSelectionWidget(WindowSelector::Direction direction, |
| 458 bool recreate_selection_widget, | 449 bool recreate_selection_widget, |
| 459 bool out_of_bounds, | 450 bool out_of_bounds, |
| 460 bool animate) { | 451 bool animate) { |
| 461 // If the selection widget is already active, fade it out in the selection | 452 // If the selection widget is already active, fade it out in the selection |
| 462 // direction. | 453 // direction. |
| 463 if (selection_widget_ && (recreate_selection_widget || out_of_bounds)) { | 454 if (selection_widget_ && (recreate_selection_widget || out_of_bounds)) { |
| 464 // Animate the old selection widget and then destroy it. | 455 // Animate the old selection widget and then destroy it. |
| 465 views::Widget* old_selection = selection_widget_.get(); | 456 views::Widget* old_selection = selection_widget_.get(); |
| 457 wm::WmWindow* old_selection_window = | |
| 458 wm::WmLookup::Get()->GetWindowForWidget(old_selection); | |
| 466 gfx::Vector2d fade_out_direction = | 459 gfx::Vector2d fade_out_direction = |
| 467 GetSlideVectorForFadeIn( | 460 GetSlideVectorForFadeIn(direction, old_selection_window->GetBounds()); |
| 468 direction, old_selection->GetNativeWindow()->bounds()); | |
| 469 | 461 |
| 470 ui::ScopedLayerAnimationSettings animation_settings( | 462 ui::ScopedLayerAnimationSettings animation_settings( |
| 471 old_selection->GetNativeWindow()->layer()->GetAnimator()); | 463 old_selection_window->GetLayer()->GetAnimator()); |
| 472 animation_settings.SetTransitionDuration( | 464 animation_settings.SetTransitionDuration( |
| 473 base::TimeDelta::FromMilliseconds( | 465 base::TimeDelta::FromMilliseconds( |
| 474 kOverviewSelectorTransitionMilliseconds)); | 466 kOverviewSelectorTransitionMilliseconds)); |
| 475 animation_settings.SetPreemptionStrategy( | 467 animation_settings.SetPreemptionStrategy( |
| 476 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 468 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 477 animation_settings.SetTweenType(gfx::Tween::FAST_OUT_LINEAR_IN); | 469 animation_settings.SetTweenType(gfx::Tween::FAST_OUT_LINEAR_IN); |
| 478 // CleanupWidgetAfterAnimationObserver will delete itself (and the | 470 // CleanupWidgetAfterAnimationObserver will delete itself (and the |
| 479 // widget) when the movement animation is complete. | 471 // widget) when the movement animation is complete. |
| 480 animation_settings.AddObserver( | 472 animation_settings.AddObserver( |
| 481 new CleanupWidgetAfterAnimationObserver(std::move(selection_widget_))); | 473 new CleanupWidgetAfterAnimationObserver(std::move(selection_widget_))); |
| 482 old_selection->SetOpacity(0); | 474 old_selection->SetOpacity(0); |
| 483 old_selection->GetNativeWindow()->SetBounds( | 475 old_selection_window->SetBounds(old_selection_window->GetBounds() + |
| 484 old_selection->GetNativeWindow()->bounds() + fade_out_direction); | 476 fade_out_direction); |
| 485 old_selection->Hide(); | 477 old_selection->Hide(); |
| 486 } | 478 } |
| 487 if (out_of_bounds) | 479 if (out_of_bounds) |
| 488 return; | 480 return; |
| 489 | 481 |
| 490 if (!selection_widget_) | 482 if (!selection_widget_) |
| 491 InitSelectionWidget(direction); | 483 InitSelectionWidget(direction); |
| 492 // Send an a11y alert so that if ChromeVox is enabled, the item label is | 484 // Send an a11y alert so that if ChromeVox is enabled, the item label is |
| 493 // read. | 485 // read. |
| 494 SelectedWindow()->SendAccessibleSelectionEvent(); | 486 SelectedWindow()->SendAccessibleSelectionEvent(); |
| 495 // The selection widget is moved to the newly selected item in the same | 487 // The selection widget is moved to the newly selected item in the same |
| 496 // grid. | 488 // grid. |
| 497 MoveSelectionWidgetToTarget(animate); | 489 MoveSelectionWidgetToTarget(animate); |
| 498 } | 490 } |
| 499 | 491 |
| 500 void WindowGrid::MoveSelectionWidgetToTarget(bool animate) { | 492 void WindowGrid::MoveSelectionWidgetToTarget(bool animate) { |
| 501 if (animate) { | 493 if (animate) { |
| 494 wm::WmWindow* selection_widget_window = | |
| 495 wm::WmLookup::Get()->GetWindowForWidget(selection_widget_.get()); | |
| 502 ui::ScopedLayerAnimationSettings animation_settings( | 496 ui::ScopedLayerAnimationSettings animation_settings( |
| 503 selection_widget_->GetNativeWindow()->layer()->GetAnimator()); | 497 selection_widget_window->GetLayer()->GetAnimator()); |
| 504 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( | 498 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( |
| 505 kOverviewSelectorTransitionMilliseconds)); | 499 kOverviewSelectorTransitionMilliseconds)); |
| 506 animation_settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); | 500 animation_settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); |
| 507 animation_settings.SetPreemptionStrategy( | 501 animation_settings.SetPreemptionStrategy( |
| 508 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 502 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 509 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); | 503 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); |
| 510 selection_widget_->SetOpacity(255); | 504 selection_widget_->SetOpacity(1.f); |
|
James Cook
2016/05/27 00:02:51
Huh, nice catch.
| |
| 511 return; | 505 return; |
| 512 } | 506 } |
| 513 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); | 507 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); |
| 514 selection_widget_->SetOpacity(255); | 508 selection_widget_->SetOpacity(1.f); |
| 515 } | 509 } |
| 516 | 510 |
| 517 } // namespace ash | 511 } // namespace ash |
| OLD | NEW |