| 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> |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "ash/wm/panels/panel_layout_manager.h" | 26 #include "ash/wm/panels/panel_layout_manager.h" |
| 27 #include "ash/wm/switchable_windows.h" | 27 #include "ash/wm/switchable_windows.h" |
| 28 #include "ash/wm/window_state.h" | 28 #include "ash/wm/window_state.h" |
| 29 #include "ash/wm/window_util.h" | 29 #include "ash/wm/window_util.h" |
| 30 #include "ash/wm_window.h" | 30 #include "ash/wm_window.h" |
| 31 #include "base/auto_reset.h" | 31 #include "base/auto_reset.h" |
| 32 #include "base/command_line.h" | 32 #include "base/command_line.h" |
| 33 #include "base/metrics/histogram_macros.h" | 33 #include "base/metrics/histogram_macros.h" |
| 34 #include "third_party/skia/include/core/SkPath.h" | 34 #include "third_party/skia/include/core/SkPath.h" |
| 35 #include "ui/base/resource/resource_bundle.h" | 35 #include "ui/base/resource/resource_bundle.h" |
| 36 #include "ui/compositor/layer.h" |
| 36 #include "ui/compositor/scoped_layer_animation_settings.h" | 37 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 37 #include "ui/display/screen.h" | 38 #include "ui/display/screen.h" |
| 38 #include "ui/events/event.h" | 39 #include "ui/events/event.h" |
| 39 #include "ui/gfx/canvas.h" | 40 #include "ui/gfx/canvas.h" |
| 40 #include "ui/gfx/paint_vector_icon.h" | 41 #include "ui/gfx/paint_vector_icon.h" |
| 41 #include "ui/gfx/skia_util.h" | 42 #include "ui/gfx/skia_util.h" |
| 42 #include "ui/vector_icons/vector_icons.h" | 43 #include "ui/vector_icons/vector_icons.h" |
| 43 #include "ui/views/border.h" | 44 #include "ui/views/border.h" |
| 44 #include "ui/views/controls/image_view.h" | 45 #include "ui/views/controls/image_view.h" |
| 45 #include "ui/views/controls/textfield/textfield.h" | 46 #include "ui/views/controls/textfield/textfield.h" |
| 46 #include "ui/views/layout/box_layout.h" | 47 #include "ui/views/layout/box_layout.h" |
| 48 #include "ui/wm/core/coordinate_conversion.h" |
| 49 #include "ui/wm/core/window_util.h" |
| 47 #include "ui/wm/public/activation_client.h" | 50 #include "ui/wm/public/activation_client.h" |
| 48 | 51 |
| 49 namespace ash { | 52 namespace ash { |
| 50 | 53 |
| 51 namespace { | 54 namespace { |
| 52 | 55 |
| 53 // The amount of padding surrounding the text in the text filtering textbox. | 56 // The amount of padding surrounding the text in the text filtering textbox. |
| 54 const int kTextFilterHorizontalPadding = 10; | 57 const int kTextFilterHorizontalPadding = 10; |
| 55 | 58 |
| 56 // The height of the text filtering textbox. | 59 // The height of the text filtering textbox. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 80 const SkColor kTextFilterIconColor = SkColorSetARGB(138, 0, 0, 0); | 83 const SkColor kTextFilterIconColor = SkColorSetARGB(138, 0, 0, 0); |
| 81 | 84 |
| 82 // The size of search icon. | 85 // The size of search icon. |
| 83 const int kTextFilterIconSize = 20; | 86 const int kTextFilterIconSize = 20; |
| 84 | 87 |
| 85 // The radius used for the rounded corners on the text filtering textbox. | 88 // The radius used for the rounded corners on the text filtering textbox. |
| 86 const int kTextFilterCornerRadius = 2; | 89 const int kTextFilterCornerRadius = 2; |
| 87 | 90 |
| 88 // A comparator for locating a selector item for a given root. | 91 // A comparator for locating a selector item for a given root. |
| 89 struct WindowSelectorItemForRoot { | 92 struct WindowSelectorItemForRoot { |
| 90 explicit WindowSelectorItemForRoot(const WmWindow* root) | 93 explicit WindowSelectorItemForRoot(const aura::Window* root) |
| 91 : root_window(root) {} | 94 : root_window(root) {} |
| 92 | 95 |
| 93 bool operator()(WindowSelectorItem* item) const { | 96 bool operator()(WindowSelectorItem* item) const { |
| 94 return item->root_window() == root_window; | 97 return item->root_window() == root_window; |
| 95 } | 98 } |
| 96 | 99 |
| 97 const WmWindow* root_window; | 100 const aura::Window* root_window; |
| 98 }; | 101 }; |
| 99 | 102 |
| 100 // A View having rounded corners and a specified background color which is | 103 // A View having rounded corners and a specified background color which is |
| 101 // only painted within the bounds defined by the rounded corners. | 104 // only painted within the bounds defined by the rounded corners. |
| 102 // TODO(tdanderson): This duplicates code from RoundedImageView. Refactor these | 105 // TODO(tdanderson): This duplicates code from RoundedImageView. Refactor these |
| 103 // classes and move into ui/views. | 106 // classes and move into ui/views. |
| 104 class RoundedContainerView : public views::View { | 107 class RoundedContainerView : public views::View { |
| 105 public: | 108 public: |
| 106 RoundedContainerView(int corner_radius, SkColor background) | 109 RoundedContainerView(int corner_radius, SkColor background) |
| 107 : corner_radius_(corner_radius), background_(background) {} | 110 : corner_radius_(corner_radius), background_(background) {} |
| (...skipping 20 matching lines...) Expand all Loading... |
| 128 | 131 |
| 129 DISALLOW_COPY_AND_ASSIGN(RoundedContainerView); | 132 DISALLOW_COPY_AND_ASSIGN(RoundedContainerView); |
| 130 }; | 133 }; |
| 131 | 134 |
| 132 // Triggers a shelf visibility update on all root window controllers. | 135 // Triggers a shelf visibility update on all root window controllers. |
| 133 void UpdateShelfVisibility() { | 136 void UpdateShelfVisibility() { |
| 134 for (aura::Window* root : Shell::GetAllRootWindows()) | 137 for (aura::Window* root : Shell::GetAllRootWindows()) |
| 135 WmShelf::ForWindow(root)->UpdateVisibilityState(); | 138 WmShelf::ForWindow(root)->UpdateVisibilityState(); |
| 136 } | 139 } |
| 137 | 140 |
| 138 gfx::Rect GetTextFilterPosition(WmWindow* root_window) { | 141 gfx::Rect GetTextFilterPosition(aura::Window* root_window) { |
| 139 gfx::Rect total_bounds = root_window->ConvertRectToScreen( | 142 gfx::Rect total_bounds = ScreenUtil::GetDisplayWorkAreaBoundsInParent( |
| 140 ScreenUtil::GetDisplayWorkAreaBoundsInParent( | 143 root_window->GetChildById(kShellWindowId_DefaultContainer)); |
| 141 root_window->GetChildByShellWindowId(kShellWindowId_DefaultContainer) | 144 ::wm::ConvertRectToScreen(root_window, &total_bounds); |
| 142 ->aura_window())); | |
| 143 return gfx::Rect( | 145 return gfx::Rect( |
| 144 0.5 * (total_bounds.width() - | 146 0.5 * (total_bounds.width() - |
| 145 std::min(kTextFilterWidth, total_bounds.width())), | 147 std::min(kTextFilterWidth, total_bounds.width())), |
| 146 total_bounds.y() + total_bounds.height() * kTextFilterTopScreenProportion, | 148 total_bounds.y() + total_bounds.height() * kTextFilterTopScreenProportion, |
| 147 std::min(kTextFilterWidth, total_bounds.width()), kTextFilterHeight); | 149 std::min(kTextFilterWidth, total_bounds.width()), kTextFilterHeight); |
| 148 } | 150 } |
| 149 | 151 |
| 150 // Initializes the text filter on the top of the main root window and requests | 152 // Initializes the text filter on the top of the main root window and requests |
| 151 // focus on its textfield. Uses |image| to place an icon to the left of the text | 153 // focus on its textfield. Uses |image| to place an icon to the left of the text |
| 152 // field. | 154 // field. |
| 153 views::Widget* CreateTextFilter(views::TextfieldController* controller, | 155 views::Widget* CreateTextFilter(views::TextfieldController* controller, |
| 154 WmWindow* root_window, | 156 aura::Window* root_window, |
| 155 const gfx::ImageSkia& image, | 157 const gfx::ImageSkia& image, |
| 156 int* text_filter_bottom) { | 158 int* text_filter_bottom) { |
| 157 views::Widget* widget = new views::Widget; | 159 views::Widget* widget = new views::Widget; |
| 158 views::Widget::InitParams params; | 160 views::Widget::InitParams params; |
| 159 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; | 161 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; |
| 160 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 162 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 161 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 163 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 162 params.accept_events = true; | 164 params.accept_events = true; |
| 163 params.bounds = GetTextFilterPosition(root_window); | 165 params.bounds = GetTextFilterPosition(root_window); |
| 164 params.name = "OverviewModeTextFilter"; | 166 params.name = "OverviewModeTextFilter"; |
| 165 *text_filter_bottom = params.bounds.bottom() + kTextFieldBottomMargin; | 167 *text_filter_bottom = params.bounds.bottom() + kTextFieldBottomMargin; |
| 166 root_window->GetRootWindowController()->ConfigureWidgetInitParamsForContainer( | 168 RootWindowController::ForWindow(root_window) |
| 167 widget, kShellWindowId_StatusContainer, ¶ms); | 169 ->ConfigureWidgetInitParamsForContainer( |
| 170 widget, kShellWindowId_StatusContainer, ¶ms); |
| 168 widget->Init(params); | 171 widget->Init(params); |
| 169 | 172 |
| 170 // Use |container| to specify the padding surrounding the text and to give | 173 // Use |container| to specify the padding surrounding the text and to give |
| 171 // the textfield rounded corners. | 174 // the textfield rounded corners. |
| 172 views::View* container = new RoundedContainerView(kTextFilterCornerRadius, | 175 views::View* container = new RoundedContainerView(kTextFilterCornerRadius, |
| 173 kTextFilterBackgroundColor); | 176 kTextFilterBackgroundColor); |
| 174 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | 177 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
| 175 const int text_height = | 178 const int text_height = |
| 176 std::max(kTextFilterIconSize, | 179 std::max(kTextFilterIconSize, |
| 177 bundle.GetFontList(kTextFilterFontStyle).GetHeight()); | 180 bundle.GetFontList(kTextFilterFontStyle).GetHeight()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 192 container->AddChildView(image_view); | 195 container->AddChildView(image_view); |
| 193 textfield->SetFontList(bundle.GetFontList(kTextFilterFontStyle)); | 196 textfield->SetFontList(bundle.GetFontList(kTextFilterFontStyle)); |
| 194 container->AddChildView(textfield); | 197 container->AddChildView(textfield); |
| 195 layout->SetFlexForView(textfield, 1); | 198 layout->SetFlexForView(textfield, 1); |
| 196 widget->SetContentsView(container); | 199 widget->SetContentsView(container); |
| 197 | 200 |
| 198 // The textfield initially contains no text, so shift its position to be | 201 // The textfield initially contains no text, so shift its position to be |
| 199 // outside the visible bounds of the screen. | 202 // outside the visible bounds of the screen. |
| 200 gfx::Transform transform; | 203 gfx::Transform transform; |
| 201 transform.Translate(0, -(*text_filter_bottom)); | 204 transform.Translate(0, -(*text_filter_bottom)); |
| 202 WmWindow* text_filter_widget_window = | 205 aura::Window* text_filter_widget_window = widget->GetNativeWindow(); |
| 203 WmWindow::Get(widget->GetNativeWindow()); | 206 text_filter_widget_window->layer()->SetOpacity(0); |
| 204 text_filter_widget_window->SetOpacity(0); | |
| 205 text_filter_widget_window->SetTransform(transform); | 207 text_filter_widget_window->SetTransform(transform); |
| 206 widget->Show(); | 208 widget->Show(); |
| 207 textfield->RequestFocus(); | 209 textfield->RequestFocus(); |
| 208 | 210 |
| 209 return widget; | 211 return widget; |
| 210 } | 212 } |
| 211 | 213 |
| 212 } // namespace | 214 } // namespace |
| 213 | 215 |
| 214 // static | 216 // static |
| 215 bool WindowSelector::IsSelectable(WmWindow* window) { | 217 bool WindowSelector::IsSelectable(aura::Window* window) { |
| 216 wm::WindowState* state = window->GetWindowState(); | 218 return wm::GetWindowState(window)->IsUserPositionable(); |
| 217 return state->IsUserPositionable(); | |
| 218 } | 219 } |
| 219 | 220 |
| 220 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate) | 221 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate) |
| 221 : delegate_(delegate), | 222 : delegate_(delegate), |
| 222 restore_focus_window_(WmWindow::Get(wm::GetFocusedWindow())), | 223 restore_focus_window_(wm::GetFocusedWindow()), |
| 223 ignore_activations_(false), | 224 ignore_activations_(false), |
| 224 selected_grid_index_(0), | 225 selected_grid_index_(0), |
| 225 overview_start_time_(base::Time::Now()), | 226 overview_start_time_(base::Time::Now()), |
| 226 num_key_presses_(0), | 227 num_key_presses_(0), |
| 227 num_items_(0), | 228 num_items_(0), |
| 228 showing_text_filter_(false), | 229 showing_text_filter_(false), |
| 229 text_filter_string_length_(0), | 230 text_filter_string_length_(0), |
| 230 num_times_textfield_cleared_(0), | 231 num_times_textfield_cleared_(0), |
| 231 restoring_minimized_windows_(false), | 232 restoring_minimized_windows_(false), |
| 232 text_filter_bottom_(0) { | 233 text_filter_bottom_(0) { |
| 233 DCHECK(delegate_); | 234 DCHECK(delegate_); |
| 234 } | 235 } |
| 235 | 236 |
| 236 WindowSelector::~WindowSelector() { | 237 WindowSelector::~WindowSelector() { |
| 237 RemoveAllObservers(); | 238 RemoveAllObservers(); |
| 238 } | 239 } |
| 239 | 240 |
| 240 // NOTE: The work done in Init() is not done in the constructor because it may | 241 // NOTE: The work done in Init() is not done in the constructor because it may |
| 241 // cause other, unrelated classes, (ie PanelLayoutManager) to make indirect | 242 // cause other, unrelated classes, (ie PanelLayoutManager) to make indirect |
| 242 // calls to restoring_minimized_windows() on a partially constructed object. | 243 // calls to restoring_minimized_windows() on a partially constructed object. |
| 243 void WindowSelector::Init(const WindowList& windows) { | 244 void WindowSelector::Init(const WindowList& windows) { |
| 244 if (restore_focus_window_) | 245 if (restore_focus_window_) |
| 245 restore_focus_window_->aura_window()->AddObserver(this); | 246 restore_focus_window_->AddObserver(this); |
| 246 | 247 |
| 247 ShellPort* shell_port = ShellPort::Get(); | 248 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
| 248 | |
| 249 std::vector<WmWindow*> root_windows = shell_port->GetAllRootWindows(); | |
| 250 std::sort(root_windows.begin(), root_windows.end(), | 249 std::sort(root_windows.begin(), root_windows.end(), |
| 251 [](const WmWindow* a, const WmWindow* b) { | 250 [](const aura::Window* a, const aura::Window* b) { |
| 252 // Since we don't know if windows are vertically or horizontally | 251 // Since we don't know if windows are vertically or horizontally |
| 253 // oriented we use both x and y position. This may be confusing | 252 // oriented we use both x and y position. This may be confusing |
| 254 // if you have 3 or more monitors which are not strictly | 253 // if you have 3 or more monitors which are not strictly |
| 255 // horizontal or vertical but that case is not yet supported. | 254 // horizontal or vertical but that case is not yet supported. |
| 256 return (a->GetBoundsInScreen().x() + a->GetBoundsInScreen().y()) < | 255 return (a->GetBoundsInScreen().x() + a->GetBoundsInScreen().y()) < |
| 257 (b->GetBoundsInScreen().x() + b->GetBoundsInScreen().y()); | 256 (b->GetBoundsInScreen().x() + b->GetBoundsInScreen().y()); |
| 258 }); | 257 }); |
| 259 | 258 |
| 260 for (WmWindow* root : root_windows) { | 259 for (auto* root : root_windows) { |
| 261 // Observed switchable containers for newly created windows on all root | 260 // Observed switchable containers for newly created windows on all root |
| 262 // windows. | 261 // windows. |
| 263 for (size_t i = 0; i < wm::kSwitchableWindowContainerIdsLength; ++i) { | 262 for (size_t i = 0; i < wm::kSwitchableWindowContainerIdsLength; ++i) { |
| 264 WmWindow* container = | 263 aura::Window* container = |
| 265 root->GetChildByShellWindowId(wm::kSwitchableWindowContainerIds[i]); | 264 root->GetChildById(wm::kSwitchableWindowContainerIds[i]); |
| 266 container->aura_window()->AddObserver(this); | 265 container->AddObserver(this); |
| 267 observed_windows_.insert(container); | 266 observed_windows_.insert(container); |
| 268 } | 267 } |
| 269 | 268 |
| 270 // Hide the callout widgets for panels. It is safe to call this for | 269 // Hide the callout widgets for panels. It is safe to call this for |
| 271 // root windows that don't contain any panel windows. | 270 // root windows that don't contain any panel windows. |
| 272 PanelLayoutManager::Get(root)->SetShowCalloutWidgets(false); | 271 PanelLayoutManager::Get(WmWindow::Get(root))->SetShowCalloutWidgets(false); |
| 273 | 272 |
| 274 std::unique_ptr<WindowGrid> grid(new WindowGrid(root, windows, this)); | 273 std::unique_ptr<WindowGrid> grid(new WindowGrid(root, windows, this)); |
| 275 if (grid->empty()) | 274 if (grid->empty()) |
| 276 continue; | 275 continue; |
| 277 num_items_ += grid->size(); | 276 num_items_ += grid->size(); |
| 278 grid_list_.push_back(std::move(grid)); | 277 grid_list_.push_back(std::move(grid)); |
| 279 } | 278 } |
| 280 | 279 |
| 281 { | 280 { |
| 282 // The calls to WindowGrid::PrepareForOverview() and CreateTextFilter(...) | 281 // The calls to WindowGrid::PrepareForOverview() and CreateTextFilter(...) |
| 283 // requires some LayoutManagers (ie PanelLayoutManager) to perform layouts | 282 // requires some LayoutManagers (ie PanelLayoutManager) to perform layouts |
| 284 // so that windows are correctly visible and properly animated in overview | 283 // so that windows are correctly visible and properly animated in overview |
| 285 // mode. Otherwise these layouts should be suppressed during overview mode | 284 // mode. Otherwise these layouts should be suppressed during overview mode |
| 286 // so they don't conflict with overview mode animations. The | 285 // so they don't conflict with overview mode animations. The |
| 287 // |restoring_minimized_windows_| flag enables the PanelLayoutManager to | 286 // |restoring_minimized_windows_| flag enables the PanelLayoutManager to |
| 288 // make this decision. | 287 // make this decision. |
| 289 base::AutoReset<bool> auto_restoring_minimized_windows( | 288 base::AutoReset<bool> auto_restoring_minimized_windows( |
| 290 &restoring_minimized_windows_, true); | 289 &restoring_minimized_windows_, true); |
| 291 | 290 |
| 292 // Do not call PrepareForOverview until all items are added to window_list_ | 291 // Do not call PrepareForOverview until all items are added to window_list_ |
| 293 // as we don't want to cause any window updates until all windows in | 292 // as we don't want to cause any window updates until all windows in |
| 294 // overview are observed. See http://crbug.com/384495. | 293 // overview are observed. See http://crbug.com/384495. |
| 295 for (std::unique_ptr<WindowGrid>& window_grid : grid_list_) { | 294 for (std::unique_ptr<WindowGrid>& window_grid : grid_list_) { |
| 296 window_grid->PrepareForOverview(); | 295 window_grid->PrepareForOverview(); |
| 297 window_grid->PositionWindows(true); | 296 window_grid->PositionWindows(true); |
| 298 } | 297 } |
| 299 | 298 |
| 300 search_image_ = gfx::CreateVectorIcon(ui::kSearchIcon, kTextFilterIconSize, | 299 search_image_ = gfx::CreateVectorIcon(ui::kSearchIcon, kTextFilterIconSize, |
| 301 kTextFilterIconColor); | 300 kTextFilterIconColor); |
| 302 WmWindow* root_window = WmWindow::Get(Shell::GetPrimaryRootWindow()); | 301 aura::Window* root_window = Shell::GetPrimaryRootWindow(); |
| 303 text_filter_widget_.reset(CreateTextFilter(this, root_window, search_image_, | 302 text_filter_widget_.reset(CreateTextFilter(this, root_window, search_image_, |
| 304 &text_filter_bottom_)); | 303 &text_filter_bottom_)); |
| 305 } | 304 } |
| 306 | 305 |
| 307 DCHECK(!grid_list_.empty()); | 306 DCHECK(!grid_list_.empty()); |
| 308 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); | 307 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); |
| 309 | 308 |
| 310 Shell::Get()->activation_client()->AddObserver(this); | 309 Shell::Get()->activation_client()->AddObserver(this); |
| 311 | 310 |
| 312 display::Screen::GetScreen()->AddObserver(this); | 311 display::Screen::GetScreen()->AddObserver(this); |
| 313 shell_port->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); | 312 ShellPort::Get()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); |
| 314 // Send an a11y alert. | 313 // Send an a11y alert. |
| 315 Shell::Get()->accessibility_delegate()->TriggerAccessibilityAlert( | 314 Shell::Get()->accessibility_delegate()->TriggerAccessibilityAlert( |
| 316 A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); | 315 A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); |
| 317 | 316 |
| 318 UpdateShelfVisibility(); | 317 UpdateShelfVisibility(); |
| 319 } | 318 } |
| 320 | 319 |
| 321 // NOTE: The work done in Shutdown() is not done in the destructor because it | 320 // NOTE: The work done in Shutdown() is not done in the destructor because it |
| 322 // may cause other, unrelated classes, (ie PanelLayoutManager) to make indirect | 321 // may cause other, unrelated classes, (ie PanelLayoutManager) to make indirect |
| 323 // calls to restoring_minimized_windows() on a partially destructed object. | 322 // calls to restoring_minimized_windows() on a partially destructed object. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.ItemsWhenTextFilteringUsed", | 365 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.ItemsWhenTextFilteringUsed", |
| 367 remaining_items); | 366 remaining_items); |
| 368 } | 367 } |
| 369 | 368 |
| 370 // Clearing the window list resets the ignored_by_shelf flag on the windows. | 369 // Clearing the window list resets the ignored_by_shelf flag on the windows. |
| 371 grid_list_.clear(); | 370 grid_list_.clear(); |
| 372 UpdateShelfVisibility(); | 371 UpdateShelfVisibility(); |
| 373 } | 372 } |
| 374 | 373 |
| 375 void WindowSelector::RemoveAllObservers() { | 374 void WindowSelector::RemoveAllObservers() { |
| 376 for (WmWindow* window : observed_windows_) | 375 for (auto* window : observed_windows_) |
| 377 window->aura_window()->RemoveObserver(this); | 376 window->RemoveObserver(this); |
| 378 | 377 |
| 379 Shell::Get()->activation_client()->RemoveObserver(this); | 378 Shell::Get()->activation_client()->RemoveObserver(this); |
| 380 display::Screen::GetScreen()->RemoveObserver(this); | 379 display::Screen::GetScreen()->RemoveObserver(this); |
| 381 if (restore_focus_window_) | 380 if (restore_focus_window_) |
| 382 restore_focus_window_->aura_window()->RemoveObserver(this); | 381 restore_focus_window_->RemoveObserver(this); |
| 383 } | 382 } |
| 384 | 383 |
| 385 void WindowSelector::CancelSelection() { | 384 void WindowSelector::CancelSelection() { |
| 386 delegate_->OnSelectionEnded(); | 385 delegate_->OnSelectionEnded(); |
| 387 } | 386 } |
| 388 | 387 |
| 389 void WindowSelector::OnGridEmpty(WindowGrid* grid) { | 388 void WindowSelector::OnGridEmpty(WindowGrid* grid) { |
| 390 size_t index = 0; | 389 size_t index = 0; |
| 391 for (auto iter = grid_list_.begin(); iter != grid_list_.end(); ++iter) { | 390 for (auto iter = grid_list_.begin(); iter != grid_list_.end(); ++iter) { |
| 392 if (grid == (*iter).get()) { | 391 if (grid == (*iter).get()) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 414 } | 413 } |
| 415 | 414 |
| 416 bool WindowSelector::AcceptSelection() { | 415 bool WindowSelector::AcceptSelection() { |
| 417 if (!grid_list_[selected_grid_index_]->is_selecting()) | 416 if (!grid_list_[selected_grid_index_]->is_selecting()) |
| 418 return false; | 417 return false; |
| 419 SelectWindow(grid_list_[selected_grid_index_]->SelectedWindow()); | 418 SelectWindow(grid_list_[selected_grid_index_]->SelectedWindow()); |
| 420 return true; | 419 return true; |
| 421 } | 420 } |
| 422 | 421 |
| 423 void WindowSelector::SelectWindow(WindowSelectorItem* item) { | 422 void WindowSelector::SelectWindow(WindowSelectorItem* item) { |
| 424 WmWindow* window = item->GetWindow(); | 423 aura::Window* window = item->GetWindow(); |
| 425 std::vector<WmWindow*> window_list = | 424 aura::Window::Windows window_list = |
| 426 Shell::Get()->mru_window_tracker()->BuildMruWindowList(); | 425 Shell::Get()->mru_window_tracker()->BuildMruWindowList(); |
| 427 if (!window_list.empty()) { | 426 if (!window_list.empty()) { |
| 428 // Record UMA_WINDOW_OVERVIEW_ACTIVE_WINDOW_CHANGED if the user is selecting | 427 // Record UMA_WINDOW_OVERVIEW_ACTIVE_WINDOW_CHANGED if the user is selecting |
| 429 // a window other than the window that was active prior to entering overview | 428 // a window other than the window that was active prior to entering overview |
| 430 // mode (i.e., the window at the front of the MRU list). | 429 // mode (i.e., the window at the front of the MRU list). |
| 431 if (window_list[0] != window) { | 430 if (window_list[0] != window) { |
| 432 ShellPort::Get()->RecordUserMetricsAction( | 431 ShellPort::Get()->RecordUserMetricsAction( |
| 433 UMA_WINDOW_OVERVIEW_ACTIVE_WINDOW_CHANGED); | 432 UMA_WINDOW_OVERVIEW_ACTIVE_WINDOW_CHANGED); |
| 434 } | 433 } |
| 435 const auto it = std::find(window_list.begin(), window_list.end(), window); | 434 const auto it = std::find(window_list.begin(), window_list.end(), window); |
| 436 if (it != window_list.end()) { | 435 if (it != window_list.end()) { |
| 437 // Record 1-based index so that selecting a top MRU window will record 1. | 436 // Record 1-based index so that selecting a top MRU window will record 1. |
| 438 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.SelectionDepth", | 437 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.SelectionDepth", |
| 439 1 + it - window_list.begin()); | 438 1 + it - window_list.begin()); |
| 440 } | 439 } |
| 441 } | 440 } |
| 442 item->EnsureVisible(); | 441 item->EnsureVisible(); |
| 443 window->GetWindowState()->Activate(); | 442 wm::GetWindowState(window)->Activate(); |
| 444 } | 443 } |
| 445 | 444 |
| 446 void WindowSelector::WindowClosing(WindowSelectorItem* window) { | 445 void WindowSelector::WindowClosing(WindowSelectorItem* window) { |
| 447 grid_list_[selected_grid_index_]->WindowClosing(window); | 446 grid_list_[selected_grid_index_]->WindowClosing(window); |
| 448 } | 447 } |
| 449 | 448 |
| 450 bool WindowSelector::HandleKeyEvent(views::Textfield* sender, | 449 bool WindowSelector::HandleKeyEvent(views::Textfield* sender, |
| 451 const ui::KeyEvent& key_event) { | 450 const ui::KeyEvent& key_event) { |
| 452 if (key_event.type() != ui::ET_KEY_PRESSED) | 451 if (key_event.type() != ui::ET_KEY_PRESSED) |
| 453 return false; | 452 return false; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 | 512 |
| 514 void WindowSelector::OnDisplayMetricsChanged(const display::Display& display, | 513 void WindowSelector::OnDisplayMetricsChanged(const display::Display& display, |
| 515 uint32_t metrics) { | 514 uint32_t metrics) { |
| 516 PositionWindows(/* animate */ false); | 515 PositionWindows(/* animate */ false); |
| 517 RepositionTextFilterOnDisplayMetricsChange(); | 516 RepositionTextFilterOnDisplayMetricsChange(); |
| 518 } | 517 } |
| 519 | 518 |
| 520 void WindowSelector::OnWindowHierarchyChanged( | 519 void WindowSelector::OnWindowHierarchyChanged( |
| 521 const HierarchyChangeParams& params) { | 520 const HierarchyChangeParams& params) { |
| 522 // Only care about newly added children of |observed_windows_|. | 521 // Only care about newly added children of |observed_windows_|. |
| 523 if (!observed_windows_.count(WmWindow::Get(params.receiver)) || | 522 if (!observed_windows_.count(params.receiver) || |
| 524 !observed_windows_.count(WmWindow::Get(params.new_parent))) { | 523 !observed_windows_.count(params.new_parent)) { |
| 525 return; | 524 return; |
| 526 } | 525 } |
| 527 | 526 |
| 528 WmWindow* new_window = WmWindow::Get(params.target); | 527 aura::Window* new_window = params.target; |
| 529 if (!IsSelectable(new_window)) | 528 if (!IsSelectable(new_window)) |
| 530 return; | 529 return; |
| 531 | 530 |
| 532 for (size_t i = 0; i < wm::kSwitchableWindowContainerIdsLength; ++i) { | 531 for (size_t i = 0; i < wm::kSwitchableWindowContainerIdsLength; ++i) { |
| 533 if (new_window->GetParent()->aura_window()->id() == | 532 if (new_window->parent()->id() == wm::kSwitchableWindowContainerIds[i] && |
| 534 wm::kSwitchableWindowContainerIds[i] && | 533 !::wm::GetTransientParent(new_window)) { |
| 535 !new_window->GetTransientParent()) { | |
| 536 // The new window is in one of the switchable containers, abort overview. | 534 // The new window is in one of the switchable containers, abort overview. |
| 537 CancelSelection(); | 535 CancelSelection(); |
| 538 return; | 536 return; |
| 539 } | 537 } |
| 540 } | 538 } |
| 541 } | 539 } |
| 542 | 540 |
| 543 void WindowSelector::OnWindowDestroying(aura::Window* window) { | 541 void WindowSelector::OnWindowDestroying(aura::Window* window) { |
| 544 window->RemoveObserver(this); | 542 window->RemoveObserver(this); |
| 545 observed_windows_.erase(WmWindow::Get(window)); | 543 observed_windows_.erase(window); |
| 546 if (WmWindow::Get(window) == restore_focus_window_) | 544 if (window == restore_focus_window_) |
| 547 restore_focus_window_ = nullptr; | 545 restore_focus_window_ = nullptr; |
| 548 } | 546 } |
| 549 | 547 |
| 550 void WindowSelector::OnWindowActivated(ActivationReason reason, | 548 void WindowSelector::OnWindowActivated(ActivationReason reason, |
| 551 aura::Window* gained_active, | 549 aura::Window* gained_active, |
| 552 aura::Window* lost_active) { | 550 aura::Window* lost_active) { |
| 553 WmWindow* wm_gained_active = WmWindow::Get(gained_active); | 551 if (ignore_activations_ || !gained_active || |
| 554 if (ignore_activations_ || !wm_gained_active || | 552 gained_active == GetTextFilterWidgetWindow()) { |
| 555 wm_gained_active == GetTextFilterWidgetWindow()) { | |
| 556 return; | 553 return; |
| 557 } | 554 } |
| 558 | 555 |
| 559 WmWindow* root_window = wm_gained_active->GetRootWindow(); | 556 aura::Window* root_window = gained_active->GetRootWindow(); |
| 560 auto grid = | 557 auto grid = |
| 561 std::find_if(grid_list_.begin(), grid_list_.end(), | 558 std::find_if(grid_list_.begin(), grid_list_.end(), |
| 562 [root_window](const std::unique_ptr<WindowGrid>& grid) { | 559 [root_window](const std::unique_ptr<WindowGrid>& grid) { |
| 563 return grid->root_window() == root_window; | 560 return grid->root_window() == root_window; |
| 564 }); | 561 }); |
| 565 if (grid == grid_list_.end()) | 562 if (grid == grid_list_.end()) |
| 566 return; | 563 return; |
| 567 const auto& windows = (*grid)->window_list(); | 564 const auto& windows = (*grid)->window_list(); |
| 568 | 565 |
| 569 auto iter = std::find_if( | 566 auto iter = std::find_if( |
| 570 windows.begin(), windows.end(), | 567 windows.begin(), windows.end(), |
| 571 [wm_gained_active](const std::unique_ptr<WindowSelectorItem>& window) { | 568 [gained_active](const std::unique_ptr<WindowSelectorItem>& window) { |
| 572 return window->Contains(wm_gained_active); | 569 return window->Contains(gained_active); |
| 573 }); | 570 }); |
| 574 | 571 |
| 575 if (iter == windows.end() && showing_text_filter_ && | 572 if (iter == windows.end() && showing_text_filter_ && |
| 576 WmWindow::Get(lost_active) == GetTextFilterWidgetWindow()) { | 573 lost_active == GetTextFilterWidgetWindow()) { |
| 577 return; | 574 return; |
| 578 } | 575 } |
| 579 | 576 |
| 580 // Don't restore focus on exit if a window was just activated. | 577 // Don't restore focus on exit if a window was just activated. |
| 581 ResetFocusRestoreWindow(false); | 578 ResetFocusRestoreWindow(false); |
| 582 CancelSelection(); | 579 CancelSelection(); |
| 583 } | 580 } |
| 584 | 581 |
| 585 void WindowSelector::OnAttemptToReactivateWindow(aura::Window* request_active, | 582 void WindowSelector::OnAttemptToReactivateWindow(aura::Window* request_active, |
| 586 aura::Window* actual_active) { | 583 aura::Window* actual_active) { |
| 587 OnWindowActivated(ActivationReason::ACTIVATION_CLIENT, request_active, | 584 OnWindowActivated(ActivationReason::ACTIVATION_CLIENT, request_active, |
| 588 actual_active); | 585 actual_active); |
| 589 } | 586 } |
| 590 | 587 |
| 591 void WindowSelector::ContentsChanged(views::Textfield* sender, | 588 void WindowSelector::ContentsChanged(views::Textfield* sender, |
| 592 const base::string16& new_contents) { | 589 const base::string16& new_contents) { |
| 593 text_filter_string_length_ = new_contents.length(); | 590 text_filter_string_length_ = new_contents.length(); |
| 594 if (!text_filter_string_length_) | 591 if (!text_filter_string_length_) |
| 595 num_times_textfield_cleared_++; | 592 num_times_textfield_cleared_++; |
| 596 | 593 |
| 597 bool should_show_text_filter = !new_contents.empty(); | 594 bool should_show_text_filter = !new_contents.empty(); |
| 598 if (showing_text_filter_ != should_show_text_filter) { | 595 if (showing_text_filter_ != should_show_text_filter) { |
| 599 WmWindow* text_filter_widget_window = GetTextFilterWidgetWindow(); | 596 aura::Window* text_filter_widget_window = GetTextFilterWidgetWindow(); |
| 600 ui::ScopedLayerAnimationSettings animation_settings( | 597 ui::ScopedLayerAnimationSettings animation_settings( |
| 601 text_filter_widget_window->GetLayer()->GetAnimator()); | 598 text_filter_widget_window->layer()->GetAnimator()); |
| 602 animation_settings.SetPreemptionStrategy( | 599 animation_settings.SetPreemptionStrategy( |
| 603 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 600 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 604 animation_settings.SetTweenType(showing_text_filter_ | 601 animation_settings.SetTweenType(showing_text_filter_ |
| 605 ? gfx::Tween::FAST_OUT_LINEAR_IN | 602 ? gfx::Tween::FAST_OUT_LINEAR_IN |
| 606 : gfx::Tween::LINEAR_OUT_SLOW_IN); | 603 : gfx::Tween::LINEAR_OUT_SLOW_IN); |
| 607 | 604 |
| 608 gfx::Transform transform; | 605 gfx::Transform transform; |
| 609 if (should_show_text_filter) { | 606 if (should_show_text_filter) { |
| 610 transform.Translate(0, 0); | 607 transform.Translate(0, 0); |
| 611 text_filter_widget_window->SetOpacity(1); | 608 text_filter_widget_window->layer()->SetOpacity(1); |
| 612 } else { | 609 } else { |
| 613 transform.Translate(0, -text_filter_bottom_); | 610 transform.Translate(0, -text_filter_bottom_); |
| 614 text_filter_widget_window->SetOpacity(0); | 611 text_filter_widget_window->layer()->SetOpacity(0); |
| 615 } | 612 } |
| 616 | 613 |
| 617 text_filter_widget_window->SetTransform(transform); | 614 text_filter_widget_window->SetTransform(transform); |
| 618 showing_text_filter_ = should_show_text_filter; | 615 showing_text_filter_ = should_show_text_filter; |
| 619 } | 616 } |
| 620 for (auto iter = grid_list_.begin(); iter != grid_list_.end(); iter++) | 617 for (auto iter = grid_list_.begin(); iter != grid_list_.end(); iter++) |
| 621 (*iter)->FilterItems(new_contents); | 618 (*iter)->FilterItems(new_contents); |
| 622 | 619 |
| 623 // If the selection widget is not active, execute a Move() command so that it | 620 // If the selection widget is not active, execute a Move() command so that it |
| 624 // shows up on the first undimmed item. | 621 // shows up on the first undimmed item. |
| 625 if (grid_list_[selected_grid_index_]->is_selecting()) | 622 if (grid_list_[selected_grid_index_]->is_selecting()) |
| 626 return; | 623 return; |
| 627 Move(WindowSelector::RIGHT, false); | 624 Move(WindowSelector::RIGHT, false); |
| 628 } | 625 } |
| 629 | 626 |
| 630 WmWindow* WindowSelector::GetTextFilterWidgetWindow() { | 627 aura::Window* WindowSelector::GetTextFilterWidgetWindow() { |
| 631 return WmWindow::Get(text_filter_widget_->GetNativeWindow()); | 628 return text_filter_widget_->GetNativeWindow(); |
| 632 } | 629 } |
| 633 | 630 |
| 634 void WindowSelector::PositionWindows(bool animate) { | 631 void WindowSelector::PositionWindows(bool animate) { |
| 635 for (std::unique_ptr<WindowGrid>& grid : grid_list_) | 632 for (std::unique_ptr<WindowGrid>& grid : grid_list_) |
| 636 grid->PositionWindows(animate); | 633 grid->PositionWindows(animate); |
| 637 } | 634 } |
| 638 | 635 |
| 639 void WindowSelector::RepositionTextFilterOnDisplayMetricsChange() { | 636 void WindowSelector::RepositionTextFilterOnDisplayMetricsChange() { |
| 640 WmWindow* root_window = WmWindow::Get(Shell::GetPrimaryRootWindow()); | 637 const gfx::Rect rect = GetTextFilterPosition(Shell::GetPrimaryRootWindow()); |
| 641 const gfx::Rect rect = GetTextFilterPosition(root_window); | |
| 642 text_filter_bottom_ = rect.bottom() + kTextFieldBottomMargin; | 638 text_filter_bottom_ = rect.bottom() + kTextFieldBottomMargin; |
| 643 text_filter_widget_->SetBounds(rect); | 639 text_filter_widget_->SetBounds(rect); |
| 644 | 640 |
| 645 gfx::Transform transform; | 641 gfx::Transform transform; |
| 646 transform.Translate( | 642 transform.Translate( |
| 647 0, text_filter_string_length_ == 0 ? -text_filter_bottom_ : 0); | 643 0, text_filter_string_length_ == 0 ? -text_filter_bottom_ : 0); |
| 648 WmWindow* text_filter_window = GetTextFilterWidgetWindow(); | 644 aura::Window* text_filter_window = GetTextFilterWidgetWindow(); |
| 649 text_filter_window->SetOpacity(text_filter_string_length_ == 0 ? 0 : 1); | 645 text_filter_window->layer()->SetOpacity(text_filter_string_length_ == 0 ? 0 |
| 646 : 1); |
| 650 text_filter_window->SetTransform(transform); | 647 text_filter_window->SetTransform(transform); |
| 651 } | 648 } |
| 652 | 649 |
| 653 void WindowSelector::ResetFocusRestoreWindow(bool focus) { | 650 void WindowSelector::ResetFocusRestoreWindow(bool focus) { |
| 654 if (!restore_focus_window_) | 651 if (!restore_focus_window_) |
| 655 return; | 652 return; |
| 656 if (focus) { | 653 if (focus) { |
| 657 base::AutoReset<bool> restoring_focus(&ignore_activations_, true); | 654 base::AutoReset<bool> restoring_focus(&ignore_activations_, true); |
| 658 restore_focus_window_->Activate(); | 655 wm::ActivateWindow(restore_focus_window_); |
| 659 } | 656 } |
| 660 // If the window is in the observed_windows_ list it needs to continue to be | 657 // If the window is in the observed_windows_ list it needs to continue to be |
| 661 // observed. | 658 // observed. |
| 662 if (observed_windows_.find(restore_focus_window_) == | 659 if (observed_windows_.find(restore_focus_window_) == |
| 663 observed_windows_.end()) { | 660 observed_windows_.end()) { |
| 664 restore_focus_window_->aura_window()->RemoveObserver(this); | 661 restore_focus_window_->RemoveObserver(this); |
| 665 } | 662 } |
| 666 restore_focus_window_ = nullptr; | 663 restore_focus_window_ = nullptr; |
| 667 } | 664 } |
| 668 | 665 |
| 669 void WindowSelector::Move(Direction direction, bool animate) { | 666 void WindowSelector::Move(Direction direction, bool animate) { |
| 670 // Direction to move if moving past the end of a display. | 667 // Direction to move if moving past the end of a display. |
| 671 int display_direction = (direction == RIGHT || direction == DOWN) ? 1 : -1; | 668 int display_direction = (direction == RIGHT || direction == DOWN) ? 1 : -1; |
| 672 | 669 |
| 673 // If this is the first move and it's going backwards, start on the last | 670 // If this is the first move and it's going backwards, start on the last |
| 674 // display. | 671 // display. |
| 675 if (display_direction == -1 && !grid_list_.empty() && | 672 if (display_direction == -1 && !grid_list_.empty() && |
| 676 !grid_list_[selected_grid_index_]->is_selecting()) { | 673 !grid_list_[selected_grid_index_]->is_selecting()) { |
| 677 selected_grid_index_ = grid_list_.size() - 1; | 674 selected_grid_index_ = grid_list_.size() - 1; |
| 678 } | 675 } |
| 679 | 676 |
| 680 // Keep calling Move() on the grids until one of them reports no overflow or | 677 // Keep calling Move() on the grids until one of them reports no overflow or |
| 681 // we made a full cycle on all the grids. | 678 // we made a full cycle on all the grids. |
| 682 for (size_t i = 0; i <= grid_list_.size() && | 679 for (size_t i = 0; i <= grid_list_.size() && |
| 683 grid_list_[selected_grid_index_]->Move(direction, animate); | 680 grid_list_[selected_grid_index_]->Move(direction, animate); |
| 684 i++) { | 681 i++) { |
| 685 selected_grid_index_ = | 682 selected_grid_index_ = |
| 686 (selected_grid_index_ + display_direction + grid_list_.size()) % | 683 (selected_grid_index_ + display_direction + grid_list_.size()) % |
| 687 grid_list_.size(); | 684 grid_list_.size(); |
| 688 } | 685 } |
| 689 } | 686 } |
| 690 | 687 |
| 691 } // namespace ash | 688 } // namespace ash |
| OLD | NEW |