Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Side by Side Diff: ash/wm/overview/window_overview.cc

Issue 256413004: Relayout windows in overview when display size changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_overview.h" 5 #include "ash/wm/overview/window_overview.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ash/metrics/user_metrics_recorder.h" 9 #include "ash/metrics/user_metrics_recorder.h"
10 #include "ash/screen_util.h" 10 #include "ash/screen_util.h"
11 #include "ash/shell.h" 11 #include "ash/shell.h"
12 #include "ash/shell_window_ids.h" 12 #include "ash/shell_window_ids.h"
13 #include "ash/switchable_windows.h" 13 #include "ash/switchable_windows.h"
14 #include "ash/wm/overview/scoped_transform_overview_window.h" 14 #include "ash/wm/overview/scoped_transform_overview_window.h"
15 #include "ash/wm/overview/window_selector.h" 15 #include "ash/wm/overview/window_selector.h"
16 #include "ash/wm/overview/window_selector_item.h" 16 #include "ash/wm/overview/window_selector_item.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "third_party/skia/include/core/SkColor.h" 18 #include "third_party/skia/include/core/SkColor.h"
19 #include "ui/aura/client/cursor_client.h" 19 #include "ui/aura/client/cursor_client.h"
20 #include "ui/aura/window.h" 20 #include "ui/aura/window.h"
21 #include "ui/aura/window_event_dispatcher.h" 21 #include "ui/aura/window_event_dispatcher.h"
22 #include "ui/compositor/layer_animation_observer.h" 22 #include "ui/compositor/layer_animation_observer.h"
23 #include "ui/compositor/scoped_layer_animation_settings.h" 23 #include "ui/compositor/scoped_layer_animation_settings.h"
24 #include "ui/events/event.h" 24 #include "ui/events/event.h"
25 #include "ui/gfx/screen.h"
25 #include "ui/views/background.h" 26 #include "ui/views/background.h"
26 #include "ui/views/widget/widget.h" 27 #include "ui/views/widget/widget.h"
27 28
28 namespace ash { 29 namespace ash {
29 30
30 namespace { 31 namespace {
31 32
32 // Conceptually the window overview is a table or grid of cells having this 33 // Conceptually the window overview is a table or grid of cells having this
33 // fixed aspect ratio. The number of columns is determined by maximizing the 34 // fixed aspect ratio. The number of columns is determined by maximizing the
34 // area of them based on the number of windows. 35 // area of them based on the number of windows.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 selection_index_(0), 126 selection_index_(0),
126 single_root_window_(single_root_window), 127 single_root_window_(single_root_window),
127 overview_start_time_(base::Time::Now()), 128 overview_start_time_(base::Time::Now()),
128 cursor_client_(NULL) { 129 cursor_client_(NULL) {
129 Shell* shell = Shell::GetInstance(); 130 Shell* shell = Shell::GetInstance();
130 shell->OnOverviewModeStarting(); 131 shell->OnOverviewModeStarting();
131 for (WindowSelectorItemList::iterator iter = windows_->begin(); 132 for (WindowSelectorItemList::iterator iter = windows_->begin();
132 iter != windows_->end(); ++iter) { 133 iter != windows_->end(); ++iter) {
133 (*iter)->PrepareForOverview(); 134 (*iter)->PrepareForOverview();
134 } 135 }
135 PositionWindows(); 136 PositionWindows(/* animate */ true);
136 DCHECK(!windows_->empty()); 137 DCHECK(!windows_->empty());
137 cursor_client_ = aura::client::GetCursorClient( 138 cursor_client_ = aura::client::GetCursorClient(
138 windows_->front()->GetRootWindow()); 139 windows_->front()->GetRootWindow());
139 if (cursor_client_) { 140 if (cursor_client_) {
140 cursor_client_->SetCursor(ui::kCursorPointer); 141 cursor_client_->SetCursor(ui::kCursorPointer);
141 cursor_client_->ShowCursor(); 142 cursor_client_->ShowCursor();
142 // TODO(flackr): Only prevent cursor changes for windows in the overview. 143 // TODO(flackr): Only prevent cursor changes for windows in the overview.
143 // This will be easier to do without exposing the overview mode code if the 144 // This will be easier to do without exposing the overview mode code if the
144 // cursor changes are moved to ToplevelWindowEventHandler::HandleMouseMoved 145 // cursor changes are moved to ToplevelWindowEventHandler::HandleMouseMoved
145 // as suggested there. 146 // as suggested there.
146 cursor_client_->LockCursor(); 147 cursor_client_->LockCursor();
147 } 148 }
148 shell->PrependPreTargetHandler(this); 149 shell->PrependPreTargetHandler(this);
150 shell->GetScreen()->AddObserver(this);
149 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); 151 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW);
150 HideAndTrackNonOverviewWindows(); 152 HideAndTrackNonOverviewWindows();
151 } 153 }
152 154
153 WindowOverview::~WindowOverview() { 155 WindowOverview::~WindowOverview() {
154 const aura::WindowTracker::Windows hidden_windows = hidden_windows_.windows(); 156 const aura::WindowTracker::Windows hidden_windows = hidden_windows_.windows();
155 for (aura::WindowTracker::Windows::const_iterator iter = 157 for (aura::WindowTracker::Windows::const_iterator iter =
156 hidden_windows.begin(); iter != hidden_windows.end(); ++iter) { 158 hidden_windows.begin(); iter != hidden_windows.end(); ++iter) {
157 ui::ScopedLayerAnimationSettings settings( 159 ui::ScopedLayerAnimationSettings settings(
158 (*iter)->layer()->GetAnimator()); 160 (*iter)->layer()->GetAnimator());
159 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( 161 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
160 ScopedTransformOverviewWindow::kTransitionMilliseconds)); 162 ScopedTransformOverviewWindow::kTransitionMilliseconds));
161 settings.SetPreemptionStrategy( 163 settings.SetPreemptionStrategy(
162 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 164 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
163 (*iter)->Show(); 165 (*iter)->Show();
164 (*iter)->layer()->SetOpacity(1); 166 (*iter)->layer()->SetOpacity(1);
165 } 167 }
166 if (cursor_client_) 168 if (cursor_client_)
167 cursor_client_->UnlockCursor(); 169 cursor_client_->UnlockCursor();
168 ash::Shell* shell = ash::Shell::GetInstance(); 170 ash::Shell* shell = ash::Shell::GetInstance();
169 shell->RemovePreTargetHandler(this); 171 shell->RemovePreTargetHandler(this);
172 shell->GetScreen()->RemoveObserver(this);
170 UMA_HISTOGRAM_MEDIUM_TIMES( 173 UMA_HISTOGRAM_MEDIUM_TIMES(
171 "Ash.WindowSelector.TimeInOverview", 174 "Ash.WindowSelector.TimeInOverview",
172 base::Time::Now() - overview_start_time_); 175 base::Time::Now() - overview_start_time_);
173 shell->OnOverviewModeEnding(); 176 shell->OnOverviewModeEnding();
174 } 177 }
175 178
176 void WindowOverview::SetSelection(size_t index) { 179 void WindowOverview::SetSelection(size_t index) {
177 gfx::Rect target_bounds(GetSelectionBounds(index)); 180 gfx::Rect target_bounds(GetSelectionBounds(index));
178 181
179 if (selection_widget_) { 182 if (selection_widget_) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 } else { 237 } else {
235 InitializeSelectionWidget(); 238 InitializeSelectionWidget();
236 selection_widget_->SetBounds(target_bounds); 239 selection_widget_->SetBounds(target_bounds);
237 selection_widget_->GetNativeWindow()->layer()->SetOpacity( 240 selection_widget_->GetNativeWindow()->layer()->SetOpacity(
238 kWindowOverviewSelectionOpacity); 241 kWindowOverviewSelectionOpacity);
239 } 242 }
240 selection_index_ = index; 243 selection_index_ = index;
241 } 244 }
242 245
243 void WindowOverview::OnWindowsChanged() { 246 void WindowOverview::OnWindowsChanged() {
244 PositionWindows(); 247 PositionWindows(/* animate */ true);
245 } 248 }
246 249
247 void WindowOverview::MoveToSingleRootWindow(aura::Window* root_window) { 250 void WindowOverview::MoveToSingleRootWindow(aura::Window* root_window) {
248 single_root_window_ = root_window; 251 single_root_window_ = root_window;
249 PositionWindows(); 252 PositionWindows(/* animate */ true);
250 } 253 }
251 254
252 void WindowOverview::OnKeyEvent(ui::KeyEvent* event) { 255 void WindowOverview::OnKeyEvent(ui::KeyEvent* event) {
253 if (GetTargetedWindow(static_cast<aura::Window*>(event->target()))) 256 if (GetTargetedWindow(static_cast<aura::Window*>(event->target())))
254 event->StopPropagation(); 257 event->StopPropagation();
255 if (event->type() != ui::ET_KEY_PRESSED) 258 if (event->type() != ui::ET_KEY_PRESSED)
256 return; 259 return;
257 260
258 if (event->key_code() == ui::VKEY_ESCAPE) 261 if (event->key_code() == ui::VKEY_ESCAPE)
259 window_selector_->CancelSelection(); 262 window_selector_->CancelSelection();
(...skipping 30 matching lines...) Expand all
290 293
291 // TODO(flackr): StopPropogation prevents generation of gesture events. 294 // TODO(flackr): StopPropogation prevents generation of gesture events.
292 // We should find a better way to prevent events from being delivered to 295 // We should find a better way to prevent events from being delivered to
293 // the window, perhaps a transparent window in front of the target window 296 // the window, perhaps a transparent window in front of the target window
294 // or using EventClientImpl::CanProcessEventsWithinSubtree and then a tap 297 // or using EventClientImpl::CanProcessEventsWithinSubtree and then a tap
295 // gesture could be used to activate the window. 298 // gesture could be used to activate the window.
296 event->SetHandled(); 299 event->SetHandled();
297 window_selector_->SelectWindow(target); 300 window_selector_->SelectWindow(target);
298 } 301 }
299 302
303 void WindowOverview::OnDisplayBoundsChanged(const gfx::Display& display) {
304 PositionWindows(/* animate */ false);
305 }
306
307 void WindowOverview::OnDisplayAdded(const gfx::Display& display) {
308 }
309
310 void WindowOverview::OnDisplayRemoved(const gfx::Display& display) {
311 }
312
300 aura::Window* WindowOverview::GetEventTarget(ui::LocatedEvent* event) { 313 aura::Window* WindowOverview::GetEventTarget(ui::LocatedEvent* event) {
301 aura::Window* target = static_cast<aura::Window*>(event->target()); 314 aura::Window* target = static_cast<aura::Window*>(event->target());
302 // If the target window doesn't actually contain the event location (i.e. 315 // If the target window doesn't actually contain the event location (i.e.
303 // mouse down over the window and mouse up elsewhere) then do not select the 316 // mouse down over the window and mouse up elsewhere) then do not select the
304 // window. 317 // window.
305 if (!target->ContainsPoint(event->location())) 318 if (!target->ContainsPoint(event->location()))
306 return NULL; 319 return NULL;
307 320
308 return GetTargetedWindow(target); 321 return GetTargetedWindow(target);
309 } 322 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 settings.SetPreemptionStrategy( 363 settings.SetPreemptionStrategy(
351 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 364 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
352 (*iter)->Hide(); 365 (*iter)->Hide();
353 // Hiding the window can result in it being destroyed. 366 // Hiding the window can result in it being destroyed.
354 if (!hidden_windows_.Contains(*iter)) 367 if (!hidden_windows_.Contains(*iter))
355 continue; 368 continue;
356 (*iter)->layer()->SetOpacity(0); 369 (*iter)->layer()->SetOpacity(0);
357 } 370 }
358 } 371 }
359 372
360 void WindowOverview::PositionWindows() { 373 void WindowOverview::PositionWindows(bool animate) {
361 if (single_root_window_) { 374 if (single_root_window_) {
362 std::vector<WindowSelectorItem*> windows; 375 std::vector<WindowSelectorItem*> windows;
363 for (WindowSelectorItemList::iterator iter = windows_->begin(); 376 for (WindowSelectorItemList::iterator iter = windows_->begin();
364 iter != windows_->end(); ++iter) { 377 iter != windows_->end(); ++iter) {
365 windows.push_back(*iter); 378 windows.push_back(*iter);
366 } 379 }
367 PositionWindowsOnRoot(single_root_window_, windows); 380 PositionWindowsOnRoot(single_root_window_, windows, animate);
368 } else { 381 } else {
369 aura::Window::Windows root_window_list = Shell::GetAllRootWindows(); 382 aura::Window::Windows root_window_list = Shell::GetAllRootWindows();
370 for (size_t i = 0; i < root_window_list.size(); ++i) 383 for (size_t i = 0; i < root_window_list.size(); ++i)
371 PositionWindowsFromRoot(root_window_list[i]); 384 PositionWindowsFromRoot(root_window_list[i], animate);
372 } 385 }
373 } 386 }
374 387
375 void WindowOverview::PositionWindowsFromRoot(aura::Window* root_window) { 388 void WindowOverview::PositionWindowsFromRoot(aura::Window* root_window,
389 bool animate) {
376 std::vector<WindowSelectorItem*> windows; 390 std::vector<WindowSelectorItem*> windows;
377 for (WindowSelectorItemList::iterator iter = windows_->begin(); 391 for (WindowSelectorItemList::iterator iter = windows_->begin();
378 iter != windows_->end(); ++iter) { 392 iter != windows_->end(); ++iter) {
379 if ((*iter)->GetRootWindow() == root_window) 393 if ((*iter)->GetRootWindow() == root_window)
380 windows.push_back(*iter); 394 windows.push_back(*iter);
381 } 395 }
382 PositionWindowsOnRoot(root_window, windows); 396 PositionWindowsOnRoot(root_window, windows, animate);
383 } 397 }
384 398
385 void WindowOverview::PositionWindowsOnRoot( 399 void WindowOverview::PositionWindowsOnRoot(
386 aura::Window* root_window, 400 aura::Window* root_window,
387 const std::vector<WindowSelectorItem*>& windows) { 401 const std::vector<WindowSelectorItem*>& windows,
402 bool animate) {
388 if (windows.empty()) 403 if (windows.empty())
389 return; 404 return;
390 405
391 gfx::Size window_size; 406 gfx::Size window_size;
392 gfx::Rect total_bounds = ScreenUtil::ConvertRectToScreen( 407 gfx::Rect total_bounds = ScreenUtil::ConvertRectToScreen(
393 root_window, 408 root_window,
394 ScreenUtil::GetDisplayWorkAreaBoundsInParent( 409 ScreenUtil::GetDisplayWorkAreaBoundsInParent(
395 Shell::GetContainer(root_window, kShellWindowId_DefaultContainer))); 410 Shell::GetContainer(root_window, kShellWindowId_DefaultContainer)));
396 411
397 // Find the minimum number of windows per row that will fit all of the 412 // Find the minimum number of windows per row that will fit all of the
(...skipping 16 matching lines...) Expand all
414 rows * window_size.height()) / 2; 429 rows * window_size.height()) / 2;
415 for (size_t i = 0; i < windows.size(); ++i) { 430 for (size_t i = 0; i < windows.size(); ++i) {
416 gfx::Transform transform; 431 gfx::Transform transform;
417 int column = i % columns; 432 int column = i % columns;
418 int row = i / columns; 433 int row = i / columns;
419 gfx::Rect target_bounds(window_size.width() * column + x_offset, 434 gfx::Rect target_bounds(window_size.width() * column + x_offset,
420 window_size.height() * row + y_offset, 435 window_size.height() * row + y_offset,
421 window_size.width(), 436 window_size.width(),
422 window_size.height()); 437 window_size.height());
423 target_bounds.Inset(kWindowMargin, kWindowMargin); 438 target_bounds.Inset(kWindowMargin, kWindowMargin);
424 windows[i]->SetBounds(root_window, target_bounds); 439 windows[i]->SetBounds(root_window, target_bounds, animate);
425 } 440 }
426 } 441 }
427 442
428 void WindowOverview::InitializeSelectionWidget() { 443 void WindowOverview::InitializeSelectionWidget() {
429 selection_widget_.reset(new views::Widget); 444 selection_widget_.reset(new views::Widget);
430 views::Widget::InitParams params; 445 views::Widget::InitParams params;
431 params.type = views::Widget::InitParams::TYPE_POPUP; 446 params.type = views::Widget::InitParams::TYPE_POPUP;
432 params.can_activate = false; 447 params.can_activate = false;
433 params.keep_on_top = false; 448 params.keep_on_top = false;
434 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 449 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
(...skipping 16 matching lines...) Expand all
451 } 466 }
452 467
453 gfx::Rect WindowOverview::GetSelectionBounds(size_t index) { 468 gfx::Rect WindowOverview::GetSelectionBounds(size_t index) {
454 gfx::Rect bounds((*windows_)[index]->bounds()); 469 gfx::Rect bounds((*windows_)[index]->bounds());
455 bounds.Inset(-kWindowOverviewSelectionPadding, 470 bounds.Inset(-kWindowOverviewSelectionPadding,
456 -kWindowOverviewSelectionPadding); 471 -kWindowOverviewSelectionPadding);
457 return bounds; 472 return bounds;
458 } 473 }
459 474
460 } // namespace ash 475 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698