| OLD | NEW |
| 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 #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/accessibility_delegate.h" | 13 #include "ash/accessibility_delegate.h" |
| 14 #include "ash/ash_switches.h" | 14 #include "ash/ash_switches.h" |
| 15 #include "ash/common/shell_window_ids.h" | 15 #include "ash/common/shell_window_ids.h" |
| 16 #include "ash/common/wm/panels/panel_layout_manager.h" | 16 #include "ash/common/wm/panels/panel_layout_manager.h" |
| 17 #include "ash/common/wm/shelf/wm_shelf.h" | 17 #include "ash/common/wm/shelf/wm_shelf.h" |
| 18 #include "ash/common/wm/switchable_windows.h" | 18 #include "ash/common/wm/switchable_windows.h" |
| 19 #include "ash/common/wm/window_state.h" | 19 #include "ash/common/wm/window_state.h" |
| 20 #include "ash/common/wm/wm_globals.h" | |
| 21 #include "ash/common/wm/wm_lookup.h" | |
| 22 #include "ash/common/wm/wm_root_window_controller.h" | |
| 23 #include "ash/common/wm/wm_user_metrics_action.h" | 20 #include "ash/common/wm/wm_user_metrics_action.h" |
| 24 #include "ash/common/wm/wm_window.h" | 21 #include "ash/common/wm_lookup.h" |
| 22 #include "ash/common/wm_root_window_controller.h" |
| 23 #include "ash/common/wm_shell.h" |
| 24 #include "ash/common/wm_window.h" |
| 25 #include "ash/shell.h" | 25 #include "ash/shell.h" |
| 26 #include "ash/wm/overview/window_grid.h" | 26 #include "ash/wm/overview/window_grid.h" |
| 27 #include "ash/wm/overview/window_selector_delegate.h" | 27 #include "ash/wm/overview/window_selector_delegate.h" |
| 28 #include "ash/wm/overview/window_selector_item.h" | 28 #include "ash/wm/overview/window_selector_item.h" |
| 29 #include "base/auto_reset.h" | 29 #include "base/auto_reset.h" |
| 30 #include "base/command_line.h" | 30 #include "base/command_line.h" |
| 31 #include "base/metrics/histogram.h" | 31 #include "base/metrics/histogram.h" |
| 32 #include "third_party/skia/include/core/SkPaint.h" | 32 #include "third_party/skia/include/core/SkPaint.h" |
| 33 #include "third_party/skia/include/core/SkPath.h" | 33 #include "third_party/skia/include/core/SkPath.h" |
| 34 #include "ui/base/resource/resource_bundle.h" | 34 #include "ui/base/resource/resource_bundle.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 63 ::ui::ResourceBundle::FontStyle::MediumFont; | 63 ::ui::ResourceBundle::FontStyle::MediumFont; |
| 64 | 64 |
| 65 // The alpha value for the background of the text filtering textbox. | 65 // The alpha value for the background of the text filtering textbox. |
| 66 const unsigned char kTextFilterOpacity = 180; | 66 const unsigned char kTextFilterOpacity = 180; |
| 67 | 67 |
| 68 // The radius used for the rounded corners on the text filtering textbox. | 68 // The radius used for the rounded corners on the text filtering textbox. |
| 69 const int kTextFilterCornerRadius = 1; | 69 const int kTextFilterCornerRadius = 1; |
| 70 | 70 |
| 71 // A comparator for locating a grid with a given root window. | 71 // A comparator for locating a grid with a given root window. |
| 72 struct RootWindowGridComparator { | 72 struct RootWindowGridComparator { |
| 73 explicit RootWindowGridComparator(const wm::WmWindow* root_window) | 73 explicit RootWindowGridComparator(const WmWindow* root_window) |
| 74 : root_window_(root_window) {} | 74 : root_window_(root_window) {} |
| 75 | 75 |
| 76 bool operator()(const std::unique_ptr<WindowGrid>& grid) const { | 76 bool operator()(const std::unique_ptr<WindowGrid>& grid) const { |
| 77 return grid->root_window() == root_window_; | 77 return grid->root_window() == root_window_; |
| 78 } | 78 } |
| 79 | 79 |
| 80 const wm::WmWindow* root_window_; | 80 const WmWindow* root_window_; |
| 81 }; | 81 }; |
| 82 | 82 |
| 83 // A comparator for locating a selectable window given a targeted window. | 83 // A comparator for locating a selectable window given a targeted window. |
| 84 struct WindowSelectorItemTargetComparator { | 84 struct WindowSelectorItemTargetComparator { |
| 85 explicit WindowSelectorItemTargetComparator(const wm::WmWindow* target_window) | 85 explicit WindowSelectorItemTargetComparator(const WmWindow* target_window) |
| 86 : target(target_window) {} | 86 : target(target_window) {} |
| 87 | 87 |
| 88 bool operator()(WindowSelectorItem* window) const { | 88 bool operator()(WindowSelectorItem* window) const { |
| 89 return window->GetWindow() == target; | 89 return window->GetWindow() == target; |
| 90 } | 90 } |
| 91 | 91 |
| 92 const wm::WmWindow* target; | 92 const WmWindow* target; |
| 93 }; | 93 }; |
| 94 | 94 |
| 95 // A comparator for locating a selector item for a given root. | 95 // A comparator for locating a selector item for a given root. |
| 96 struct WindowSelectorItemForRoot { | 96 struct WindowSelectorItemForRoot { |
| 97 explicit WindowSelectorItemForRoot(const wm::WmWindow* root) | 97 explicit WindowSelectorItemForRoot(const WmWindow* root) |
| 98 : root_window(root) {} | 98 : root_window(root) {} |
| 99 | 99 |
| 100 bool operator()(WindowSelectorItem* item) const { | 100 bool operator()(WindowSelectorItem* item) const { |
| 101 return item->root_window() == root_window; | 101 return item->root_window() == root_window; |
| 102 } | 102 } |
| 103 | 103 |
| 104 const wm::WmWindow* root_window; | 104 const WmWindow* root_window; |
| 105 }; | 105 }; |
| 106 | 106 |
| 107 // A View having rounded corners and a specified background color which is | 107 // A View having rounded corners and a specified background color which is |
| 108 // only painted within the bounds defined by the rounded corners. | 108 // only painted within the bounds defined by the rounded corners. |
| 109 // TODO(tdanderson): This duplicates code from RoundedImageView. Refactor these | 109 // TODO(tdanderson): This duplicates code from RoundedImageView. Refactor these |
| 110 // classes and move into ui/views. | 110 // classes and move into ui/views. |
| 111 class RoundedContainerView : public views::View { | 111 class RoundedContainerView : public views::View { |
| 112 public: | 112 public: |
| 113 RoundedContainerView(int corner_radius, SkColor background) | 113 RoundedContainerView(int corner_radius, SkColor background) |
| 114 : corner_radius_(corner_radius), | 114 : corner_radius_(corner_radius), |
| (...skipping 20 matching lines...) Expand all Loading... |
| 135 | 135 |
| 136 private: | 136 private: |
| 137 int corner_radius_; | 137 int corner_radius_; |
| 138 SkColor background_; | 138 SkColor background_; |
| 139 | 139 |
| 140 DISALLOW_COPY_AND_ASSIGN(RoundedContainerView); | 140 DISALLOW_COPY_AND_ASSIGN(RoundedContainerView); |
| 141 }; | 141 }; |
| 142 | 142 |
| 143 // Triggers a shelf visibility update on all root window controllers. | 143 // Triggers a shelf visibility update on all root window controllers. |
| 144 void UpdateShelfVisibility() { | 144 void UpdateShelfVisibility() { |
| 145 for (wm::WmWindow* root : wm::WmGlobals::Get()->GetAllRootWindows()) | 145 for (WmWindow* root : WmShell::Get()->GetAllRootWindows()) |
| 146 root->GetRootWindowController()->GetShelf()->UpdateVisibilityState(); | 146 root->GetRootWindowController()->GetShelf()->UpdateVisibilityState(); |
| 147 } | 147 } |
| 148 | 148 |
| 149 // Initializes the text filter on the top of the main root window and requests | 149 // Initializes the text filter on the top of the main root window and requests |
| 150 // focus on its textfield. | 150 // focus on its textfield. |
| 151 views::Widget* CreateTextFilter(views::TextfieldController* controller, | 151 views::Widget* CreateTextFilter(views::TextfieldController* controller, |
| 152 wm::WmWindow* root_window) { | 152 WmWindow* root_window) { |
| 153 views::Widget* widget = new views::Widget; | 153 views::Widget* widget = new views::Widget; |
| 154 views::Widget::InitParams params; | 154 views::Widget::InitParams params; |
| 155 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; | 155 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; |
| 156 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 156 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 157 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 157 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 158 params.accept_events = true; | 158 params.accept_events = true; |
| 159 params.bounds = gfx::Rect( | 159 params.bounds = gfx::Rect( |
| 160 root_window->GetBounds().width() / 2 * (1 - kTextFilterScreenProportion), | 160 root_window->GetBounds().width() / 2 * (1 - kTextFilterScreenProportion), |
| 161 kTextFilterDistanceFromTop, | 161 kTextFilterDistanceFromTop, |
| 162 root_window->GetBounds().width() * kTextFilterScreenProportion, | 162 root_window->GetBounds().width() * kTextFilterScreenProportion, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 185 textfield->SetTextColor(SK_ColorWHITE); | 185 textfield->SetTextColor(SK_ColorWHITE); |
| 186 textfield->SetFontList(bundle.GetFontList(kTextFilterFontStyle)); | 186 textfield->SetFontList(bundle.GetFontList(kTextFilterFontStyle)); |
| 187 | 187 |
| 188 container->AddChildView(textfield); | 188 container->AddChildView(textfield); |
| 189 widget->SetContentsView(container); | 189 widget->SetContentsView(container); |
| 190 | 190 |
| 191 // The textfield initially contains no text, so shift its position to be | 191 // The textfield initially contains no text, so shift its position to be |
| 192 // outside the visible bounds of the screen. | 192 // outside the visible bounds of the screen. |
| 193 gfx::Transform transform; | 193 gfx::Transform transform; |
| 194 transform.Translate(0, -WindowSelector::kTextFilterBottomEdge); | 194 transform.Translate(0, -WindowSelector::kTextFilterBottomEdge); |
| 195 wm::WmLookup::Get()->GetWindowForWidget(widget)->SetTransform(transform); | 195 WmLookup::Get()->GetWindowForWidget(widget)->SetTransform(transform); |
| 196 widget->Show(); | 196 widget->Show(); |
| 197 textfield->RequestFocus(); | 197 textfield->RequestFocus(); |
| 198 | 198 |
| 199 return widget; | 199 return widget; |
| 200 } | 200 } |
| 201 | 201 |
| 202 } // namespace | 202 } // namespace |
| 203 | 203 |
| 204 const int WindowSelector::kTextFilterBottomEdge = | 204 const int WindowSelector::kTextFilterBottomEdge = |
| 205 kTextFilterDistanceFromTop + kTextFilterHeight; | 205 kTextFilterDistanceFromTop + kTextFilterHeight; |
| 206 | 206 |
| 207 // static | 207 // static |
| 208 bool WindowSelector::IsSelectable(wm::WmWindow* window) { | 208 bool WindowSelector::IsSelectable(WmWindow* window) { |
| 209 wm::WindowState* state = window->GetWindowState(); | 209 wm::WindowState* state = window->GetWindowState(); |
| 210 if (state->GetStateType() == wm::WINDOW_STATE_TYPE_DOCKED || | 210 if (state->GetStateType() == wm::WINDOW_STATE_TYPE_DOCKED || |
| 211 state->GetStateType() == wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED) { | 211 state->GetStateType() == wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED) { |
| 212 return false; | 212 return false; |
| 213 } | 213 } |
| 214 return state->IsUserPositionable(); | 214 return state->IsUserPositionable(); |
| 215 } | 215 } |
| 216 | 216 |
| 217 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate) | 217 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate) |
| 218 : delegate_(delegate), | 218 : delegate_(delegate), |
| 219 restore_focus_window_(wm::WmGlobals::Get()->GetFocusedWindow()), | 219 restore_focus_window_(WmShell::Get()->GetFocusedWindow()), |
| 220 ignore_activations_(false), | 220 ignore_activations_(false), |
| 221 selected_grid_index_(0), | 221 selected_grid_index_(0), |
| 222 overview_start_time_(base::Time::Now()), | 222 overview_start_time_(base::Time::Now()), |
| 223 num_key_presses_(0), | 223 num_key_presses_(0), |
| 224 num_items_(0), | 224 num_items_(0), |
| 225 showing_selection_widget_(false), | 225 showing_selection_widget_(false), |
| 226 text_filter_string_length_(0), | 226 text_filter_string_length_(0), |
| 227 num_times_textfield_cleared_(0), | 227 num_times_textfield_cleared_(0), |
| 228 restoring_minimized_windows_(false) { | 228 restoring_minimized_windows_(false) { |
| 229 DCHECK(delegate_); | 229 DCHECK(delegate_); |
| 230 } | 230 } |
| 231 | 231 |
| 232 WindowSelector::~WindowSelector() { | 232 WindowSelector::~WindowSelector() { |
| 233 RemoveAllObservers(); | 233 RemoveAllObservers(); |
| 234 } | 234 } |
| 235 | 235 |
| 236 // NOTE: The work done in Init() is not done in the constructor because it may | 236 // NOTE: The work done in Init() is not done in the constructor because it may |
| 237 // cause other, unrelated classes, (ie PanelLayoutManager) to make indirect | 237 // cause other, unrelated classes, (ie PanelLayoutManager) to make indirect |
| 238 // calls to restoring_minimized_windows() on a partially constructed object. | 238 // calls to restoring_minimized_windows() on a partially constructed object. |
| 239 void WindowSelector::Init(const WindowList& windows) { | 239 void WindowSelector::Init(const WindowList& windows) { |
| 240 if (restore_focus_window_) | 240 if (restore_focus_window_) |
| 241 restore_focus_window_->AddObserver(this); | 241 restore_focus_window_->AddObserver(this); |
| 242 | 242 |
| 243 wm::WmGlobals* globals = wm::WmGlobals::Get(); | 243 WmShell* shell = WmShell::Get(); |
| 244 | 244 |
| 245 std::vector<wm::WmWindow*> root_windows = globals->GetAllRootWindows(); | 245 std::vector<WmWindow*> root_windows = shell->GetAllRootWindows(); |
| 246 std::sort(root_windows.begin(), root_windows.end(), | 246 std::sort(root_windows.begin(), root_windows.end(), |
| 247 [](const wm::WmWindow* a, const wm::WmWindow* b) { | 247 [](const WmWindow* a, const WmWindow* b) { |
| 248 // Since we don't know if windows are vertically or horizontally | 248 // Since we don't know if windows are vertically or horizontally |
| 249 // oriented we use both x and y position. This may be confusing | 249 // oriented we use both x and y position. This may be confusing |
| 250 // if you have 3 or more monitors which are not strictly | 250 // if you have 3 or more monitors which are not strictly |
| 251 // horizontal or vertical but that case is not yet supported. | 251 // horizontal or vertical but that case is not yet supported. |
| 252 return (a->GetBoundsInScreen().x() + a->GetBoundsInScreen().y()) < | 252 return (a->GetBoundsInScreen().x() + a->GetBoundsInScreen().y()) < |
| 253 (b->GetBoundsInScreen().x() + b->GetBoundsInScreen().y()); | 253 (b->GetBoundsInScreen().x() + b->GetBoundsInScreen().y()); |
| 254 }); | 254 }); |
| 255 | 255 |
| 256 for (wm::WmWindow* root : root_windows) { | 256 for (WmWindow* root : root_windows) { |
| 257 // Observed switchable containers for newly created windows on all root | 257 // Observed switchable containers for newly created windows on all root |
| 258 // windows. | 258 // windows. |
| 259 for (size_t i = 0; i < wm::kSwitchableWindowContainerIdsLength; ++i) { | 259 for (size_t i = 0; i < wm::kSwitchableWindowContainerIdsLength; ++i) { |
| 260 wm::WmWindow* container = | 260 WmWindow* container = |
| 261 root->GetChildByShellWindowId(wm::kSwitchableWindowContainerIds[i]); | 261 root->GetChildByShellWindowId(wm::kSwitchableWindowContainerIds[i]); |
| 262 container->AddObserver(this); | 262 container->AddObserver(this); |
| 263 observed_windows_.insert(container); | 263 observed_windows_.insert(container); |
| 264 } | 264 } |
| 265 | 265 |
| 266 // Hide the callout widgets for panels. It is safe to call this for | 266 // Hide the callout widgets for panels. It is safe to call this for |
| 267 // root windows that don't contain any panel windows. | 267 // root windows that don't contain any panel windows. |
| 268 PanelLayoutManager::Get(root)->SetShowCalloutWidgets(false); | 268 PanelLayoutManager::Get(root)->SetShowCalloutWidgets(false); |
| 269 | 269 |
| 270 std::unique_ptr<WindowGrid> grid(new WindowGrid(root, windows, this)); | 270 std::unique_ptr<WindowGrid> grid(new WindowGrid(root, windows, this)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 287 | 287 |
| 288 // Do not call PrepareForOverview until all items are added to window_list_ | 288 // Do not call PrepareForOverview until all items are added to window_list_ |
| 289 // as we don't want to cause any window updates until all windows in | 289 // as we don't want to cause any window updates until all windows in |
| 290 // overview are observed. See http://crbug.com/384495. | 290 // overview are observed. See http://crbug.com/384495. |
| 291 for (std::unique_ptr<WindowGrid>& window_grid : grid_list_) { | 291 for (std::unique_ptr<WindowGrid>& window_grid : grid_list_) { |
| 292 window_grid->PrepareForOverview(); | 292 window_grid->PrepareForOverview(); |
| 293 window_grid->PositionWindows(true); | 293 window_grid->PositionWindows(true); |
| 294 } | 294 } |
| 295 | 295 |
| 296 text_filter_widget_.reset( | 296 text_filter_widget_.reset( |
| 297 CreateTextFilter(this, globals->GetPrimaryRootWindow())); | 297 CreateTextFilter(this, shell->GetPrimaryRootWindow())); |
| 298 } | 298 } |
| 299 | 299 |
| 300 DCHECK(!grid_list_.empty()); | 300 DCHECK(!grid_list_.empty()); |
| 301 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); | 301 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); |
| 302 | 302 |
| 303 globals->AddActivationObserver(this); | 303 shell->AddActivationObserver(this); |
| 304 | 304 |
| 305 display::Screen::GetScreen()->AddObserver(this); | 305 display::Screen::GetScreen()->AddObserver(this); |
| 306 globals->RecordUserMetricsAction(wm::WmUserMetricsAction::WINDOW_OVERVIEW); | 306 shell->RecordUserMetricsAction(wm::WmUserMetricsAction::WINDOW_OVERVIEW); |
| 307 // Send an a11y alert. | 307 // Send an a11y alert. |
| 308 Shell::GetInstance()->accessibility_delegate()->TriggerAccessibilityAlert( | 308 Shell::GetInstance()->accessibility_delegate()->TriggerAccessibilityAlert( |
| 309 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); | 309 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); |
| 310 | 310 |
| 311 UpdateShelfVisibility(); | 311 UpdateShelfVisibility(); |
| 312 } | 312 } |
| 313 | 313 |
| 314 // NOTE: The work done in Shutdown() is not done in the destructor because it | 314 // NOTE: The work done in Shutdown() is not done in the destructor because it |
| 315 // may cause other, unrelated classes, (ie PanelLayoutManager) to make indirect | 315 // may cause other, unrelated classes, (ie PanelLayoutManager) to make indirect |
| 316 // calls to restoring_minimized_windows() on a partially destructed object. | 316 // calls to restoring_minimized_windows() on a partially destructed object. |
| 317 void WindowSelector::Shutdown() { | 317 void WindowSelector::Shutdown() { |
| 318 ResetFocusRestoreWindow(true); | 318 ResetFocusRestoreWindow(true); |
| 319 RemoveAllObservers(); | 319 RemoveAllObservers(); |
| 320 | 320 |
| 321 std::vector<wm::WmWindow*> root_windows = | 321 std::vector<WmWindow*> root_windows = WmShell::Get()->GetAllRootWindows(); |
| 322 wm::WmGlobals::Get()->GetAllRootWindows(); | 322 for (WmWindow* window : root_windows) { |
| 323 for (wm::WmWindow* window : root_windows) { | |
| 324 // Un-hide the callout widgets for panels. It is safe to call this for | 323 // Un-hide the callout widgets for panels. It is safe to call this for |
| 325 // root_windows that don't contain any panel windows. | 324 // root_windows that don't contain any panel windows. |
| 326 PanelLayoutManager::Get(window)->SetShowCalloutWidgets(true); | 325 PanelLayoutManager::Get(window)->SetShowCalloutWidgets(true); |
| 327 } | 326 } |
| 328 | 327 |
| 329 size_t remaining_items = 0; | 328 size_t remaining_items = 0; |
| 330 for (std::unique_ptr<WindowGrid>& window_grid : grid_list_) { | 329 for (std::unique_ptr<WindowGrid>& window_grid : grid_list_) { |
| 331 for (WindowSelectorItem* window_selector_item : window_grid->window_list()) | 330 for (WindowSelectorItem* window_selector_item : window_grid->window_list()) |
| 332 window_selector_item->RestoreWindow(); | 331 window_selector_item->RestoreWindow(); |
| 333 remaining_items += window_grid->size(); | 332 remaining_items += window_grid->size(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 352 "Ash.WindowSelector.ItemsWhenTextFilteringUsed", | 351 "Ash.WindowSelector.ItemsWhenTextFilteringUsed", |
| 353 remaining_items); | 352 remaining_items); |
| 354 } | 353 } |
| 355 | 354 |
| 356 // Clearing the window list resets the ignored_by_shelf flag on the windows. | 355 // Clearing the window list resets the ignored_by_shelf flag on the windows. |
| 357 grid_list_.clear(); | 356 grid_list_.clear(); |
| 358 UpdateShelfVisibility(); | 357 UpdateShelfVisibility(); |
| 359 } | 358 } |
| 360 | 359 |
| 361 void WindowSelector::RemoveAllObservers() { | 360 void WindowSelector::RemoveAllObservers() { |
| 362 for (wm::WmWindow* window : observed_windows_) | 361 for (WmWindow* window : observed_windows_) |
| 363 window->RemoveObserver(this); | 362 window->RemoveObserver(this); |
| 364 | 363 |
| 365 wm::WmGlobals::Get()->RemoveActivationObserver(this); | 364 WmShell::Get()->RemoveActivationObserver(this); |
| 366 display::Screen::GetScreen()->RemoveObserver(this); | 365 display::Screen::GetScreen()->RemoveObserver(this); |
| 367 if (restore_focus_window_) | 366 if (restore_focus_window_) |
| 368 restore_focus_window_->RemoveObserver(this); | 367 restore_focus_window_->RemoveObserver(this); |
| 369 } | 368 } |
| 370 | 369 |
| 371 void WindowSelector::CancelSelection() { | 370 void WindowSelector::CancelSelection() { |
| 372 delegate_->OnSelectionEnded(); | 371 delegate_->OnSelectionEnded(); |
| 373 } | 372 } |
| 374 | 373 |
| 375 void WindowSelector::OnGridEmpty(WindowGrid* grid) { | 374 void WindowSelector::OnGridEmpty(WindowGrid* grid) { |
| 376 size_t index = 0; | 375 size_t index = 0; |
| 377 for (auto iter = grid_list_.begin(); iter != grid_list_.end(); ++iter) { | 376 for (auto iter = grid_list_.begin(); iter != grid_list_.end(); ++iter) { |
| 378 if (grid == (*iter).get()) { | 377 if (grid == (*iter).get()) { |
| 379 index = iter - grid_list_.begin(); | 378 index = iter - grid_list_.begin(); |
| 380 grid_list_.erase(iter); | 379 grid_list_.erase(iter); |
| 381 break; | 380 break; |
| 382 } | 381 } |
| 383 } | 382 } |
| 384 if (index > 0 && selected_grid_index_ >= index) { | 383 if (index > 0 && selected_grid_index_ >= index) { |
| 385 selected_grid_index_--; | 384 selected_grid_index_--; |
| 386 // If the grid which became empty was the one with the selected window, we | 385 // If the grid which became empty was the one with the selected window, we |
| 387 // need to select a window on the newly selected grid. | 386 // need to select a window on the newly selected grid. |
| 388 if (selected_grid_index_ == index - 1) | 387 if (selected_grid_index_ == index - 1) |
| 389 Move(LEFT, true); | 388 Move(LEFT, true); |
| 390 } | 389 } |
| 391 if (grid_list_.empty()) | 390 if (grid_list_.empty()) |
| 392 CancelSelection(); | 391 CancelSelection(); |
| 393 } | 392 } |
| 394 | 393 |
| 395 void WindowSelector::SelectWindow(wm::WmWindow* window) { | 394 void WindowSelector::SelectWindow(WmWindow* window) { |
| 396 // Record UMA_WINDOW_OVERVIEW_ACTIVE_WINDOW_CHANGED if the user is selecting | 395 // Record UMA_WINDOW_OVERVIEW_ACTIVE_WINDOW_CHANGED if the user is selecting |
| 397 // a window other than the window that was active prior to entering overview | 396 // a window other than the window that was active prior to entering overview |
| 398 // mode (i.e., the window at the front of the MRU list). | 397 // mode (i.e., the window at the front of the MRU list). |
| 399 std::vector<wm::WmWindow*> window_list = | 398 std::vector<WmWindow*> window_list = WmShell::Get()->GetMruWindowList(); |
| 400 wm::WmGlobals::Get()->GetMruWindowList(); | |
| 401 if (!window_list.empty() && window_list[0] != window) { | 399 if (!window_list.empty() && window_list[0] != window) { |
| 402 wm::WmGlobals::Get()->RecordUserMetricsAction( | 400 WmShell::Get()->RecordUserMetricsAction( |
| 403 wm::WmUserMetricsAction::WINDOW_OVERVIEW_ACTIVE_WINDOW_CHANGED); | 401 wm::WmUserMetricsAction::WINDOW_OVERVIEW_ACTIVE_WINDOW_CHANGED); |
| 404 } | 402 } |
| 405 | 403 |
| 406 window->GetWindowState()->Activate(); | 404 window->GetWindowState()->Activate(); |
| 407 } | 405 } |
| 408 | 406 |
| 409 bool WindowSelector::HandleKeyEvent(views::Textfield* sender, | 407 bool WindowSelector::HandleKeyEvent(views::Textfield* sender, |
| 410 const ui::KeyEvent& key_event) { | 408 const ui::KeyEvent& key_event) { |
| 411 if (key_event.type() != ui::ET_KEY_PRESSED) | 409 if (key_event.type() != ui::ET_KEY_PRESSED) |
| 412 return false; | 410 return false; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 434 break; | 432 break; |
| 435 case ui::VKEY_RETURN: | 433 case ui::VKEY_RETURN: |
| 436 // Ignore if no item is selected. | 434 // Ignore if no item is selected. |
| 437 if (!grid_list_[selected_grid_index_]->is_selecting()) | 435 if (!grid_list_[selected_grid_index_]->is_selecting()) |
| 438 return false; | 436 return false; |
| 439 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.ArrowKeyPresses", | 437 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.ArrowKeyPresses", |
| 440 num_key_presses_); | 438 num_key_presses_); |
| 441 UMA_HISTOGRAM_CUSTOM_COUNTS( | 439 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 442 "Ash.WindowSelector.KeyPressesOverItemsRatio", | 440 "Ash.WindowSelector.KeyPressesOverItemsRatio", |
| 443 (num_key_presses_ * 100) / num_items_, 1, 300, 30); | 441 (num_key_presses_ * 100) / num_items_, 1, 300, 30); |
| 444 wm::WmGlobals::Get()->RecordUserMetricsAction( | 442 WmShell::Get()->RecordUserMetricsAction( |
| 445 wm::WmUserMetricsAction::WINDOW_OVERVIEW_ENTER_KEY); | 443 wm::WmUserMetricsAction::WINDOW_OVERVIEW_ENTER_KEY); |
| 446 SelectWindow( | 444 SelectWindow( |
| 447 grid_list_[selected_grid_index_]->SelectedWindow()->GetWindow()); | 445 grid_list_[selected_grid_index_]->SelectedWindow()->GetWindow()); |
| 448 break; | 446 break; |
| 449 default: | 447 default: |
| 450 // Not a key we are interested in, allow the textfield to handle it. | 448 // Not a key we are interested in, allow the textfield to handle it. |
| 451 return false; | 449 return false; |
| 452 } | 450 } |
| 453 return true; | 451 return true; |
| 454 } | 452 } |
| 455 | 453 |
| 456 void WindowSelector::OnDisplayAdded(const display::Display& display) {} | 454 void WindowSelector::OnDisplayAdded(const display::Display& display) {} |
| 457 | 455 |
| 458 void WindowSelector::OnDisplayRemoved(const display::Display& display) { | 456 void WindowSelector::OnDisplayRemoved(const display::Display& display) { |
| 459 // TODO(flackr): Keep window selection active on remaining displays. | 457 // TODO(flackr): Keep window selection active on remaining displays. |
| 460 CancelSelection(); | 458 CancelSelection(); |
| 461 } | 459 } |
| 462 | 460 |
| 463 void WindowSelector::OnDisplayMetricsChanged(const display::Display& display, | 461 void WindowSelector::OnDisplayMetricsChanged(const display::Display& display, |
| 464 uint32_t metrics) { | 462 uint32_t metrics) { |
| 465 PositionWindows(/* animate */ false); | 463 PositionWindows(/* animate */ false); |
| 466 RepositionTextFilterOnDisplayMetricsChange(); | 464 RepositionTextFilterOnDisplayMetricsChange(); |
| 467 } | 465 } |
| 468 | 466 |
| 469 void WindowSelector::OnWindowTreeChanged(wm::WmWindow* window, | 467 void WindowSelector::OnWindowTreeChanged(WmWindow* window, |
| 470 const TreeChangeParams& params) { | 468 const TreeChangeParams& params) { |
| 471 // Only care about newly added children of |observed_windows_|. | 469 // Only care about newly added children of |observed_windows_|. |
| 472 if (!observed_windows_.count(window) || | 470 if (!observed_windows_.count(window) || |
| 473 !observed_windows_.count(params.new_parent)) { | 471 !observed_windows_.count(params.new_parent)) { |
| 474 return; | 472 return; |
| 475 } | 473 } |
| 476 | 474 |
| 477 wm::WmWindow* new_window = params.target; | 475 WmWindow* new_window = params.target; |
| 478 if (!IsSelectable(new_window)) | 476 if (!IsSelectable(new_window)) |
| 479 return; | 477 return; |
| 480 | 478 |
| 481 for (size_t i = 0; i < wm::kSwitchableWindowContainerIdsLength; ++i) { | 479 for (size_t i = 0; i < wm::kSwitchableWindowContainerIdsLength; ++i) { |
| 482 if (new_window->GetParent()->GetShellWindowId() == | 480 if (new_window->GetParent()->GetShellWindowId() == |
| 483 wm::kSwitchableWindowContainerIds[i] && | 481 wm::kSwitchableWindowContainerIds[i] && |
| 484 !new_window->GetTransientParent()) { | 482 !new_window->GetTransientParent()) { |
| 485 // The new window is in one of the switchable containers, abort overview. | 483 // The new window is in one of the switchable containers, abort overview. |
| 486 CancelSelection(); | 484 CancelSelection(); |
| 487 return; | 485 return; |
| 488 } | 486 } |
| 489 } | 487 } |
| 490 } | 488 } |
| 491 | 489 |
| 492 void WindowSelector::OnWindowDestroying(wm::WmWindow* window) { | 490 void WindowSelector::OnWindowDestroying(WmWindow* window) { |
| 493 window->RemoveObserver(this); | 491 window->RemoveObserver(this); |
| 494 observed_windows_.erase(window); | 492 observed_windows_.erase(window); |
| 495 if (window == restore_focus_window_) | 493 if (window == restore_focus_window_) |
| 496 restore_focus_window_ = nullptr; | 494 restore_focus_window_ = nullptr; |
| 497 } | 495 } |
| 498 | 496 |
| 499 void WindowSelector::OnWindowActivated(wm::WmWindow* gained_active, | 497 void WindowSelector::OnWindowActivated(WmWindow* gained_active, |
| 500 wm::WmWindow* lost_active) { | 498 WmWindow* lost_active) { |
| 501 if (ignore_activations_ || !gained_active || | 499 if (ignore_activations_ || !gained_active || |
| 502 gained_active == GetTextFilterWidgetWindow()) { | 500 gained_active == GetTextFilterWidgetWindow()) { |
| 503 return; | 501 return; |
| 504 } | 502 } |
| 505 | 503 |
| 506 auto grid = | 504 auto grid = |
| 507 std::find_if(grid_list_.begin(), grid_list_.end(), | 505 std::find_if(grid_list_.begin(), grid_list_.end(), |
| 508 RootWindowGridComparator(gained_active->GetRootWindow())); | 506 RootWindowGridComparator(gained_active->GetRootWindow())); |
| 509 if (grid == grid_list_.end()) | 507 if (grid == grid_list_.end()) |
| 510 return; | 508 return; |
| 511 const std::vector<WindowSelectorItem*> windows = (*grid)->window_list(); | 509 const std::vector<WindowSelectorItem*> windows = (*grid)->window_list(); |
| 512 | 510 |
| 513 auto iter = std::find_if(windows.begin(), windows.end(), | 511 auto iter = std::find_if(windows.begin(), windows.end(), |
| 514 WindowSelectorItemTargetComparator(gained_active)); | 512 WindowSelectorItemTargetComparator(gained_active)); |
| 515 | 513 |
| 516 if (iter != windows.end()) | 514 if (iter != windows.end()) |
| 517 (*iter)->ShowWindowOnExit(); | 515 (*iter)->ShowWindowOnExit(); |
| 518 | 516 |
| 519 // Don't restore focus on exit if a window was just activated. | 517 // Don't restore focus on exit if a window was just activated. |
| 520 ResetFocusRestoreWindow(false); | 518 ResetFocusRestoreWindow(false); |
| 521 CancelSelection(); | 519 CancelSelection(); |
| 522 } | 520 } |
| 523 | 521 |
| 524 void WindowSelector::OnAttemptToReactivateWindow(wm::WmWindow* request_active, | 522 void WindowSelector::OnAttemptToReactivateWindow(WmWindow* request_active, |
| 525 wm::WmWindow* actual_active) { | 523 WmWindow* actual_active) { |
| 526 OnWindowActivated(request_active, actual_active); | 524 OnWindowActivated(request_active, actual_active); |
| 527 } | 525 } |
| 528 | 526 |
| 529 void WindowSelector::ContentsChanged(views::Textfield* sender, | 527 void WindowSelector::ContentsChanged(views::Textfield* sender, |
| 530 const base::string16& new_contents) { | 528 const base::string16& new_contents) { |
| 531 text_filter_string_length_ = new_contents.length(); | 529 text_filter_string_length_ = new_contents.length(); |
| 532 if (!text_filter_string_length_) | 530 if (!text_filter_string_length_) |
| 533 num_times_textfield_cleared_++; | 531 num_times_textfield_cleared_++; |
| 534 | 532 |
| 535 bool should_show_selection_widget = !new_contents.empty(); | 533 bool should_show_selection_widget = !new_contents.empty(); |
| 536 if (showing_selection_widget_ != should_show_selection_widget) { | 534 if (showing_selection_widget_ != should_show_selection_widget) { |
| 537 wm::WmWindow* text_filter_widget_window = GetTextFilterWidgetWindow(); | 535 WmWindow* text_filter_widget_window = GetTextFilterWidgetWindow(); |
| 538 ui::ScopedLayerAnimationSettings animation_settings( | 536 ui::ScopedLayerAnimationSettings animation_settings( |
| 539 text_filter_widget_window->GetLayer()->GetAnimator()); | 537 text_filter_widget_window->GetLayer()->GetAnimator()); |
| 540 animation_settings.SetPreemptionStrategy( | 538 animation_settings.SetPreemptionStrategy( |
| 541 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 539 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 542 animation_settings.SetTweenType(showing_selection_widget_ ? | 540 animation_settings.SetTweenType(showing_selection_widget_ ? |
| 543 gfx::Tween::FAST_OUT_LINEAR_IN : gfx::Tween::LINEAR_OUT_SLOW_IN); | 541 gfx::Tween::FAST_OUT_LINEAR_IN : gfx::Tween::LINEAR_OUT_SLOW_IN); |
| 544 | 542 |
| 545 gfx::Transform transform; | 543 gfx::Transform transform; |
| 546 if (should_show_selection_widget) { | 544 if (should_show_selection_widget) { |
| 547 transform.Translate(0, 0); | 545 transform.Translate(0, 0); |
| 548 text_filter_widget_window->SetOpacity(1); | 546 text_filter_widget_window->SetOpacity(1); |
| 549 } else { | 547 } else { |
| 550 transform.Translate(0, -kTextFilterBottomEdge); | 548 transform.Translate(0, -kTextFilterBottomEdge); |
| 551 text_filter_widget_window->SetOpacity(0); | 549 text_filter_widget_window->SetOpacity(0); |
| 552 } | 550 } |
| 553 | 551 |
| 554 text_filter_widget_window->SetTransform(transform); | 552 text_filter_widget_window->SetTransform(transform); |
| 555 showing_selection_widget_ = should_show_selection_widget; | 553 showing_selection_widget_ = should_show_selection_widget; |
| 556 } | 554 } |
| 557 for (auto iter = grid_list_.begin(); iter != grid_list_.end(); iter++) | 555 for (auto iter = grid_list_.begin(); iter != grid_list_.end(); iter++) |
| 558 (*iter)->FilterItems(new_contents); | 556 (*iter)->FilterItems(new_contents); |
| 559 | 557 |
| 560 // If the selection widget is not active, execute a Move() command so that it | 558 // If the selection widget is not active, execute a Move() command so that it |
| 561 // shows up on the first undimmed item. | 559 // shows up on the first undimmed item. |
| 562 if (grid_list_[selected_grid_index_]->is_selecting()) | 560 if (grid_list_[selected_grid_index_]->is_selecting()) |
| 563 return; | 561 return; |
| 564 Move(WindowSelector::RIGHT, false); | 562 Move(WindowSelector::RIGHT, false); |
| 565 } | 563 } |
| 566 | 564 |
| 567 wm::WmWindow* WindowSelector::GetTextFilterWidgetWindow() { | 565 WmWindow* WindowSelector::GetTextFilterWidgetWindow() { |
| 568 return wm::WmLookup::Get()->GetWindowForWidget(text_filter_widget_.get()); | 566 return WmLookup::Get()->GetWindowForWidget(text_filter_widget_.get()); |
| 569 } | 567 } |
| 570 | 568 |
| 571 void WindowSelector::PositionWindows(bool animate) { | 569 void WindowSelector::PositionWindows(bool animate) { |
| 572 for (std::unique_ptr<WindowGrid>& grid : grid_list_) | 570 for (std::unique_ptr<WindowGrid>& grid : grid_list_) |
| 573 grid->PositionWindows(animate); | 571 grid->PositionWindows(animate); |
| 574 } | 572 } |
| 575 | 573 |
| 576 void WindowSelector::RepositionTextFilterOnDisplayMetricsChange() { | 574 void WindowSelector::RepositionTextFilterOnDisplayMetricsChange() { |
| 577 wm::WmWindow* root_window = wm::WmGlobals::Get()->GetPrimaryRootWindow(); | 575 WmWindow* root_window = WmShell::Get()->GetPrimaryRootWindow(); |
| 578 gfx::Rect rect( | 576 gfx::Rect rect( |
| 579 root_window->GetBounds().width() / 2 * (1 - kTextFilterScreenProportion), | 577 root_window->GetBounds().width() / 2 * (1 - kTextFilterScreenProportion), |
| 580 kTextFilterDistanceFromTop, | 578 kTextFilterDistanceFromTop, |
| 581 root_window->GetBounds().width() * kTextFilterScreenProportion, | 579 root_window->GetBounds().width() * kTextFilterScreenProportion, |
| 582 kTextFilterHeight); | 580 kTextFilterHeight); |
| 583 | 581 |
| 584 text_filter_widget_->SetBounds(rect); | 582 text_filter_widget_->SetBounds(rect); |
| 585 | 583 |
| 586 gfx::Transform transform; | 584 gfx::Transform transform; |
| 587 transform.Translate(0, text_filter_string_length_ == 0 | 585 transform.Translate(0, text_filter_string_length_ == 0 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 for (size_t i = 0; | 620 for (size_t i = 0; |
| 623 i <= grid_list_.size() && | 621 i <= grid_list_.size() && |
| 624 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { | 622 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { |
| 625 selected_grid_index_ = | 623 selected_grid_index_ = |
| 626 (selected_grid_index_ + display_direction + grid_list_.size()) % | 624 (selected_grid_index_ + display_direction + grid_list_.size()) % |
| 627 grid_list_.size(); | 625 grid_list_.size(); |
| 628 } | 626 } |
| 629 } | 627 } |
| 630 | 628 |
| 631 } // namespace ash | 629 } // namespace ash |
| OLD | NEW |