| 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]; |
| 191 const gfx::Rect screen_target_bounds = |
| 192 window->ConvertRectToScreen(window->GetTargetBounds()); |
| 192 int64_t distance = | 193 int64_t distance = |
| 193 (ScreenUtil::ConvertRectToScreen(window, window->GetTargetBounds()) | 194 (screen_target_bounds.CenterPoint() - overview_item_center) |
| 194 .CenterPoint() - | |
| 195 overview_item_center) | |
| 196 .LengthSquared(); | 195 .LengthSquared(); |
| 197 // We compare raw pointers to create a stable ordering given two windows | 196 // We compare raw pointers to create a stable ordering given two windows |
| 198 // with the same center point. | 197 // with the same center point. |
| 199 if (distance < shortest_distance || | 198 if (distance < shortest_distance || |
| 200 (distance == shortest_distance && window < (*items)[swap_index])) { | 199 (distance == shortest_distance && window < (*items)[swap_index])) { |
| 201 shortest_distance = distance; | 200 shortest_distance = distance; |
| 202 swap_index = j; | 201 swap_index = j; |
| 203 } | 202 } |
| 204 } | 203 } |
| 205 if (swap_index > i) | 204 if (swap_index > i) |
| 206 std::swap((*items)[i], (*items)[swap_index]); | 205 std::swap((*items)[i], (*items)[swap_index]); |
| 207 } | 206 } |
| 208 } | 207 } |
| 209 | 208 |
| 210 } // namespace | 209 } // namespace |
| 211 | 210 |
| 212 WindowGrid::WindowGrid(aura::Window* root_window, | 211 WindowGrid::WindowGrid(wm::WmWindow* root_window, |
| 213 const std::vector<aura::Window*>& windows, | 212 const std::vector<wm::WmWindow*>& windows, |
| 214 WindowSelector* window_selector) | 213 WindowSelector* window_selector) |
| 215 : root_window_(root_window), | 214 : root_window_(root_window), window_selector_(window_selector) { |
| 216 window_selector_(window_selector) { | 215 std::vector<wm::WmWindow*> windows_in_root; |
| 217 std::vector<aura::Window*> windows_in_root; | |
| 218 for (auto window : windows) { | 216 for (auto window : windows) { |
| 219 if (window->GetRootWindow() == root_window) | 217 if (window->GetRootWindow() == root_window) |
| 220 windows_in_root.push_back(window); | 218 windows_in_root.push_back(window); |
| 221 } | 219 } |
| 222 | 220 |
| 223 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 221 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 224 switches::kAshEnableStableOverviewOrder)) { | 222 switches::kAshEnableStableOverviewOrder)) { |
| 225 // Reorder windows to try to minimize movement to target overview positions. | 223 // Reorder windows to try to minimize movement to target overview positions. |
| 226 // This also creates a stable window ordering. | 224 // This also creates a stable window ordering. |
| 227 ReorderItemsGreedyLeastMovement(&windows_in_root, root_window_); | 225 ReorderItemsGreedyLeastMovement(&windows_in_root, root_window_); |
| 228 } | 226 } |
| 229 for (auto window : windows_in_root) { | 227 for (auto window : windows_in_root) { |
| 230 window->AddObserver(this); | 228 window->AddObserver(this); |
| 231 observed_windows_.insert(window); | 229 observed_windows_.insert(window); |
| 232 window_list_.push_back(new WindowSelectorItem(window, window_selector_)); | 230 window_list_.push_back(new WindowSelectorItem(window, window_selector_)); |
| 233 } | 231 } |
| 234 } | 232 } |
| 235 | 233 |
| 236 WindowGrid::~WindowGrid() { | 234 WindowGrid::~WindowGrid() { |
| 237 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin(); | 235 for (wm::WmWindow* window : observed_windows_) |
| 238 iter != observed_windows_.end(); iter++) { | 236 window->RemoveObserver(this); |
| 239 (*iter)->RemoveObserver(this); | |
| 240 } | |
| 241 } | 237 } |
| 242 | 238 |
| 243 void WindowGrid::PrepareForOverview() { | 239 void WindowGrid::PrepareForOverview() { |
| 244 for (ScopedVector<WindowSelectorItem>::iterator iter = window_list_.begin(); | 240 for (auto iter = window_list_.begin(); iter != window_list_.end(); ++iter) |
| 245 iter != window_list_.end(); ++iter) { | |
| 246 (*iter)->PrepareForOverview(); | 241 (*iter)->PrepareForOverview(); |
| 247 } | |
| 248 } | 242 } |
| 249 | 243 |
| 250 void WindowGrid::PositionWindows(bool animate) { | 244 void WindowGrid::PositionWindows(bool animate) { |
| 251 CHECK(!window_list_.empty()); | 245 CHECK(!window_list_.empty()); |
| 252 gfx::Rect bounding_rect; | 246 gfx::Rect bounding_rect; |
| 253 gfx::Size item_size; | 247 gfx::Size item_size; |
| 254 CalculateOverviewSizes(root_window_, window_list_.size(), &bounding_rect, | 248 CalculateOverviewSizes(root_window_, window_list_.size(), &bounding_rect, |
| 255 &item_size); | 249 &item_size); |
| 256 num_columns_ = std::min(static_cast<int>(window_list_.size()), | 250 num_columns_ = std::min(static_cast<int>(window_list_.size()), |
| 257 bounding_rect.width() / item_size.width()); | 251 bounding_rect.width() / item_size.width()); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 return out_of_bounds; | 332 return out_of_bounds; |
| 339 } | 333 } |
| 340 | 334 |
| 341 WindowSelectorItem* WindowGrid::SelectedWindow() const { | 335 WindowSelectorItem* WindowGrid::SelectedWindow() const { |
| 342 if (!selection_widget_) | 336 if (!selection_widget_) |
| 343 return nullptr; | 337 return nullptr; |
| 344 CHECK(selected_index_ < window_list_.size()); | 338 CHECK(selected_index_ < window_list_.size()); |
| 345 return window_list_[selected_index_]; | 339 return window_list_[selected_index_]; |
| 346 } | 340 } |
| 347 | 341 |
| 348 bool WindowGrid::Contains(const aura::Window* window) const { | 342 bool WindowGrid::Contains(const wm::WmWindow* window) const { |
| 349 for (const WindowSelectorItem* window_item : window_list_) { | 343 for (const WindowSelectorItem* window_item : window_list_) { |
| 350 if (window_item->Contains(window)) | 344 if (window_item->Contains(window)) |
| 351 return true; | 345 return true; |
| 352 } | 346 } |
| 353 return false; | 347 return false; |
| 354 } | 348 } |
| 355 | 349 |
| 356 void WindowGrid::FilterItems(const base::string16& pattern) { | 350 void WindowGrid::FilterItems(const base::string16& pattern) { |
| 357 base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents finder(pattern); | 351 base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents finder(pattern); |
| 358 for (ScopedVector<WindowSelectorItem>::iterator iter = window_list_.begin(); | 352 for (auto iter = window_list_.begin(); iter != window_list_.end(); iter++) { |
| 359 iter != window_list_.end(); iter++) { | 353 if (finder.Search((*iter)->GetWindow()->GetTitle(), nullptr, nullptr)) { |
| 360 if (finder.Search((*iter)->GetWindow()->title(), nullptr, nullptr)) { | |
| 361 (*iter)->SetDimmed(false); | 354 (*iter)->SetDimmed(false); |
| 362 } else { | 355 } else { |
| 363 (*iter)->SetDimmed(true); | 356 (*iter)->SetDimmed(true); |
| 364 if (selection_widget_ && SelectedWindow() == *iter) | 357 if (selection_widget_ && SelectedWindow() == *iter) |
| 365 selection_widget_.reset(); | 358 selection_widget_.reset(); |
| 366 } | 359 } |
| 367 } | 360 } |
| 368 } | 361 } |
| 369 | 362 |
| 370 void WindowGrid::OnWindowDestroying(aura::Window* window) { | 363 void WindowGrid::OnWindowDestroying(wm::WmWindow* window) { |
| 371 window->RemoveObserver(this); | 364 window->RemoveObserver(this); |
| 372 observed_windows_.erase(window); | 365 observed_windows_.erase(window); |
| 373 ScopedVector<WindowSelectorItem>::iterator iter = | 366 ScopedVector<WindowSelectorItem>::iterator iter = |
| 374 std::find_if(window_list_.begin(), window_list_.end(), | 367 std::find_if(window_list_.begin(), window_list_.end(), |
| 375 WindowSelectorItemComparator(window)); | 368 WindowSelectorItemComparator(window)); |
| 376 | 369 |
| 377 DCHECK(iter != window_list_.end()); | 370 DCHECK(iter != window_list_.end()); |
| 378 | 371 |
| 379 size_t removed_index = iter - window_list_.begin(); | 372 size_t removed_index = iter - window_list_.begin(); |
| 380 window_list_.erase(iter); | 373 window_list_.erase(iter); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 391 bool send_focus_alert = selected_index_ == removed_index; | 384 bool send_focus_alert = selected_index_ == removed_index; |
| 392 if (selected_index_ >= removed_index && selected_index_ != 0) | 385 if (selected_index_ >= removed_index && selected_index_ != 0) |
| 393 selected_index_--; | 386 selected_index_--; |
| 394 if (send_focus_alert) | 387 if (send_focus_alert) |
| 395 SelectedWindow()->SendAccessibleSelectionEvent(); | 388 SelectedWindow()->SendAccessibleSelectionEvent(); |
| 396 } | 389 } |
| 397 | 390 |
| 398 PositionWindows(true); | 391 PositionWindows(true); |
| 399 } | 392 } |
| 400 | 393 |
| 401 void WindowGrid::OnWindowBoundsChanged(aura::Window* window, | 394 void WindowGrid::OnWindowBoundsChanged(wm::WmWindow* window, |
| 402 const gfx::Rect& old_bounds, | 395 const gfx::Rect& old_bounds, |
| 403 const gfx::Rect& new_bounds) { | 396 const gfx::Rect& new_bounds) { |
| 404 ScopedVector<WindowSelectorItem>::const_iterator iter = | 397 auto iter = std::find_if(window_list_.begin(), window_list_.end(), |
| 405 std::find_if(window_list_.begin(), window_list_.end(), | 398 WindowSelectorItemComparator(window)); |
| 406 WindowSelectorItemComparator(window)); | |
| 407 DCHECK(iter != window_list_.end()); | 399 DCHECK(iter != window_list_.end()); |
| 408 | 400 |
| 409 // Immediately finish any active bounds animation. | 401 // Immediately finish any active bounds animation. |
| 410 window->layer()->GetAnimator()->StopAnimatingProperty( | 402 window->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS); |
| 411 ui::LayerAnimationElement::BOUNDS); | |
| 412 | 403 |
| 413 // Recompute the transform for the window. | 404 // Recompute the transform for the window. |
| 414 (*iter)->RecomputeWindowTransforms(); | 405 (*iter)->RecomputeWindowTransforms(); |
| 415 } | 406 } |
| 416 | 407 |
| 417 void WindowGrid::InitSelectionWidget(WindowSelector::Direction direction) { | 408 void WindowGrid::InitSelectionWidget(WindowSelector::Direction direction) { |
| 418 selection_widget_.reset(new views::Widget); | 409 selection_widget_.reset(new views::Widget); |
| 419 views::Widget::InitParams params; | 410 views::Widget::InitParams params; |
| 420 params.type = views::Widget::InitParams::TYPE_POPUP; | 411 params.type = views::Widget::InitParams::TYPE_POPUP; |
| 421 params.keep_on_top = false; | 412 params.keep_on_top = false; |
| 422 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 413 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 423 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 414 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 424 params.parent = Shell::GetContainer(root_window_, | |
| 425 kShellWindowId_DefaultContainer); | |
| 426 params.accept_events = false; | 415 params.accept_events = false; |
| 427 selection_widget_->set_focus_on_creation(false); | 416 selection_widget_->set_focus_on_creation(false); |
| 417 root_window_->GetRootWindowController() |
| 418 ->ConfigureWidgetInitParamsForContainer( |
| 419 selection_widget_.get(), kShellWindowId_DefaultContainer, ¶ms); |
| 428 selection_widget_->Init(params); | 420 selection_widget_->Init(params); |
| 421 wm::WmWindow* selection_widget_window = |
| 422 wm::WmLookup::Get()->GetWindowForWidget(selection_widget_.get()); |
| 429 // Disable the "bounce in" animation when showing the window. | 423 // Disable the "bounce in" animation when showing the window. |
| 430 ::wm::SetWindowVisibilityAnimationTransition( | 424 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. | 425 // The selection widget should not activate the shelf when passing under it. |
| 433 wm::GetWindowState(selection_widget_->GetNativeWindow())-> | 426 selection_widget_window->GetWindowState()->set_ignored_by_shelf(true); |
| 434 set_ignored_by_shelf(true); | |
| 435 | 427 |
| 436 views::View* content_view = new views::View; | 428 views::View* content_view = new views::View; |
| 437 content_view->set_background( | 429 content_view->set_background( |
| 438 views::Background::CreateSolidBackground(kWindowSelectionColor)); | 430 views::Background::CreateSolidBackground(kWindowSelectionColor)); |
| 439 content_view->SetBorder(views::Border::CreateSolidBorder( | 431 content_view->SetBorder(views::Border::CreateSolidBorder( |
| 440 kWindowSelectionBorderThickness, kWindowSelectionBorderColor)); | 432 kWindowSelectionBorderThickness, kWindowSelectionBorderColor)); |
| 441 selection_widget_->SetContentsView(content_view); | 433 selection_widget_->SetContentsView(content_view); |
| 442 selection_widget_->GetNativeWindow()->parent()->StackChildAtBottom( | 434 selection_widget_window->GetParent()->StackChildAtBottom( |
| 443 selection_widget_->GetNativeWindow()); | 435 selection_widget_window); |
| 444 selection_widget_->Show(); | 436 selection_widget_->Show(); |
| 445 // New selection widget starts with 0 opacity and then fades in. | 437 // New selection widget starts with 0 opacity and then fades in. |
| 446 selection_widget_->GetNativeWindow()->layer()->SetOpacity(0); | 438 selection_widget_window->SetOpacity(0); |
| 447 | 439 |
| 448 const gfx::Rect target_bounds = SelectedWindow()->target_bounds(); | 440 const gfx::Rect target_bounds = SelectedWindow()->target_bounds(); |
| 449 gfx::Vector2d fade_out_direction = | 441 gfx::Vector2d fade_out_direction = |
| 450 GetSlideVectorForFadeIn(direction, target_bounds); | 442 GetSlideVectorForFadeIn(direction, target_bounds); |
| 451 display::Display dst_display = | 443 display::Display dst_display = |
| 452 display::Screen::GetScreen()->GetDisplayMatching(target_bounds); | 444 display::Screen::GetScreen()->GetDisplayMatching(target_bounds); |
| 453 selection_widget_->GetNativeWindow()->SetBoundsInScreen( | 445 selection_widget_window->SetBoundsInScreen(target_bounds - fade_out_direction, |
| 454 target_bounds - fade_out_direction, dst_display); | 446 dst_display); |
| 455 } | 447 } |
| 456 | 448 |
| 457 void WindowGrid::MoveSelectionWidget(WindowSelector::Direction direction, | 449 void WindowGrid::MoveSelectionWidget(WindowSelector::Direction direction, |
| 458 bool recreate_selection_widget, | 450 bool recreate_selection_widget, |
| 459 bool out_of_bounds, | 451 bool out_of_bounds, |
| 460 bool animate) { | 452 bool animate) { |
| 461 // If the selection widget is already active, fade it out in the selection | 453 // If the selection widget is already active, fade it out in the selection |
| 462 // direction. | 454 // direction. |
| 463 if (selection_widget_ && (recreate_selection_widget || out_of_bounds)) { | 455 if (selection_widget_ && (recreate_selection_widget || out_of_bounds)) { |
| 464 // Animate the old selection widget and then destroy it. | 456 // Animate the old selection widget and then destroy it. |
| 465 views::Widget* old_selection = selection_widget_.get(); | 457 views::Widget* old_selection = selection_widget_.get(); |
| 458 wm::WmWindow* old_selection_window = |
| 459 wm::WmLookup::Get()->GetWindowForWidget(old_selection); |
| 466 gfx::Vector2d fade_out_direction = | 460 gfx::Vector2d fade_out_direction = |
| 467 GetSlideVectorForFadeIn( | 461 GetSlideVectorForFadeIn(direction, old_selection_window->GetBounds()); |
| 468 direction, old_selection->GetNativeWindow()->bounds()); | |
| 469 | 462 |
| 470 ui::ScopedLayerAnimationSettings animation_settings( | 463 ui::ScopedLayerAnimationSettings animation_settings( |
| 471 old_selection->GetNativeWindow()->layer()->GetAnimator()); | 464 old_selection_window->GetLayer()->GetAnimator()); |
| 472 animation_settings.SetTransitionDuration( | 465 animation_settings.SetTransitionDuration( |
| 473 base::TimeDelta::FromMilliseconds( | 466 base::TimeDelta::FromMilliseconds( |
| 474 kOverviewSelectorTransitionMilliseconds)); | 467 kOverviewSelectorTransitionMilliseconds)); |
| 475 animation_settings.SetPreemptionStrategy( | 468 animation_settings.SetPreemptionStrategy( |
| 476 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 469 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 477 animation_settings.SetTweenType(gfx::Tween::FAST_OUT_LINEAR_IN); | 470 animation_settings.SetTweenType(gfx::Tween::FAST_OUT_LINEAR_IN); |
| 478 // CleanupWidgetAfterAnimationObserver will delete itself (and the | 471 // CleanupWidgetAfterAnimationObserver will delete itself (and the |
| 479 // widget) when the movement animation is complete. | 472 // widget) when the movement animation is complete. |
| 480 animation_settings.AddObserver( | 473 animation_settings.AddObserver( |
| 481 new CleanupWidgetAfterAnimationObserver(std::move(selection_widget_))); | 474 new CleanupWidgetAfterAnimationObserver(std::move(selection_widget_))); |
| 482 old_selection->SetOpacity(0); | 475 old_selection->SetOpacity(0); |
| 483 old_selection->GetNativeWindow()->SetBounds( | 476 old_selection_window->SetBounds(old_selection_window->GetBounds() + |
| 484 old_selection->GetNativeWindow()->bounds() + fade_out_direction); | 477 fade_out_direction); |
| 485 old_selection->Hide(); | 478 old_selection->Hide(); |
| 486 } | 479 } |
| 487 if (out_of_bounds) | 480 if (out_of_bounds) |
| 488 return; | 481 return; |
| 489 | 482 |
| 490 if (!selection_widget_) | 483 if (!selection_widget_) |
| 491 InitSelectionWidget(direction); | 484 InitSelectionWidget(direction); |
| 492 // Send an a11y alert so that if ChromeVox is enabled, the item label is | 485 // Send an a11y alert so that if ChromeVox is enabled, the item label is |
| 493 // read. | 486 // read. |
| 494 SelectedWindow()->SendAccessibleSelectionEvent(); | 487 SelectedWindow()->SendAccessibleSelectionEvent(); |
| 495 // The selection widget is moved to the newly selected item in the same | 488 // The selection widget is moved to the newly selected item in the same |
| 496 // grid. | 489 // grid. |
| 497 MoveSelectionWidgetToTarget(animate); | 490 MoveSelectionWidgetToTarget(animate); |
| 498 } | 491 } |
| 499 | 492 |
| 500 void WindowGrid::MoveSelectionWidgetToTarget(bool animate) { | 493 void WindowGrid::MoveSelectionWidgetToTarget(bool animate) { |
| 501 if (animate) { | 494 if (animate) { |
| 495 wm::WmWindow* selection_widget_window = |
| 496 wm::WmLookup::Get()->GetWindowForWidget(selection_widget_.get()); |
| 502 ui::ScopedLayerAnimationSettings animation_settings( | 497 ui::ScopedLayerAnimationSettings animation_settings( |
| 503 selection_widget_->GetNativeWindow()->layer()->GetAnimator()); | 498 selection_widget_window->GetLayer()->GetAnimator()); |
| 504 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( | 499 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( |
| 505 kOverviewSelectorTransitionMilliseconds)); | 500 kOverviewSelectorTransitionMilliseconds)); |
| 506 animation_settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); | 501 animation_settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); |
| 507 animation_settings.SetPreemptionStrategy( | 502 animation_settings.SetPreemptionStrategy( |
| 508 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 503 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 509 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); | 504 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); |
| 510 selection_widget_->SetOpacity(255); | 505 selection_widget_->SetOpacity(1.f); |
| 511 return; | 506 return; |
| 512 } | 507 } |
| 513 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); | 508 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); |
| 514 selection_widget_->SetOpacity(255); | 509 selection_widget_->SetOpacity(1.f); |
| 515 } | 510 } |
| 516 | 511 |
| 517 } // namespace ash | 512 } // namespace ash |
| OLD | NEW |