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

Side by Side Diff: ash/wm/workspace/workspace_layout_manager.cc

Issue 68033003: Undocks window first before side-snapping bounds (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Undocks window first before side-snapping bounds (rebase) Created 7 years 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/workspace/workspace_layout_manager.h" 5 #include "ash/wm/workspace/workspace_layout_manager.h"
6 6
7 #include "ash/display/display_controller.h" 7 #include "ash/display/display_controller.h"
8 #include "ash/root_window_controller.h" 8 #include "ash/root_window_controller.h"
9 #include "ash/screen_ash.h" 9 #include "ash/screen_ash.h"
10 #include "ash/shelf/shelf_layout_manager.h" 10 #include "ash/shelf/shelf_layout_manager.h"
11 #include "ash/shell.h" 11 #include "ash/shell.h"
12 #include "ash/wm/always_on_top_controller.h" 12 #include "ash/wm/always_on_top_controller.h"
13 #include "ash/wm/base_layout_manager.h" 13 #include "ash/wm/base_layout_manager.h"
14 #include "ash/wm/window_animations.h" 14 #include "ash/wm/window_animations.h"
15 #include "ash/wm/window_positioner.h" 15 #include "ash/wm/window_positioner.h"
16 #include "ash/wm/window_properties.h" 16 #include "ash/wm/window_properties.h"
17 #include "ash/wm/window_state.h" 17 #include "ash/wm/window_state.h"
18 #include "ash/wm/window_util.h" 18 #include "ash/wm/window_util.h"
19 #include "ui/aura/client/aura_constants.h" 19 #include "ui/aura/client/aura_constants.h"
20 #include "ui/aura/window.h" 20 #include "ui/aura/window.h"
21 #include "ui/aura/window_observer.h" 21 #include "ui/aura/window_observer.h"
22 #include "ui/base/ui_base_types.h" 22 #include "ui/base/ui_base_types.h"
23 #include "ui/compositor/scoped_layer_animation_settings.h"
23 #include "ui/events/event.h" 24 #include "ui/events/event.h"
24 #include "ui/views/corewm/window_util.h" 25 #include "ui/views/corewm/window_util.h"
25 26
26 using aura::Window; 27 using aura::Window;
27 28
28 namespace ash { 29 namespace ash {
29 30
30 namespace internal { 31 namespace internal {
31 32
32 namespace { 33 namespace {
33 34
34 // This specifies how much percent 30% of a window rect (width / height) 35 // This specifies how much percent 30% of a window rect (width / height)
35 // must be visible when the window is added to the workspace. 36 // must be visible when the window is added to the workspace.
36 const float kMinimumPercentOnScreenArea = 0.3f; 37 const float kMinimumPercentOnScreenArea = 0.3f;
37 38
39 // Duration of slide animation used when a snapped window is adjusted.
40 const int kSlideDurationMs = 120;
41
38 void MoveToDisplayForRestore(wm::WindowState* window_state) { 42 void MoveToDisplayForRestore(wm::WindowState* window_state) {
39 if (!window_state->HasRestoreBounds()) 43 if (!window_state->HasRestoreBounds())
40 return; 44 return;
41 const gfx::Rect& restore_bounds = window_state->GetRestoreBoundsInScreen(); 45 const gfx::Rect& restore_bounds = window_state->GetRestoreBoundsInScreen();
42 46
43 // Move only if the restore bounds is outside of 47 // Move only if the restore bounds is outside of
44 // the display. There is no information about in which 48 // the display. There is no information about in which
45 // display it should be restored, so this is best guess. 49 // display it should be restored, so this is best guess.
46 // TODO(oshima): Restore information should contain the 50 // TODO(oshima): Restore information should contain the
47 // work area information like WindowResizer does for the 51 // work area information like WindowResizer does for the
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 false, child->GetRootWindow()); 114 false, child->GetRootWindow());
111 } 115 }
112 WindowPositioner::RearrangeVisibleWindowOnHideOrRemove(child); 116 WindowPositioner::RearrangeVisibleWindowOnHideOrRemove(child);
113 } 117 }
114 UpdateDesktopVisibility(); 118 UpdateDesktopVisibility();
115 } 119 }
116 120
117 void WorkspaceLayoutManager::SetChildBounds( 121 void WorkspaceLayoutManager::SetChildBounds(
118 Window* child, 122 Window* child,
119 const gfx::Rect& requested_bounds) { 123 const gfx::Rect& requested_bounds) {
120 if (!wm::GetWindowState(child)->tracked_by_workspace()) { 124 wm::WindowState* window_state = wm::GetWindowState(child);
125 if (!window_state->tracked_by_workspace()) {
121 SetChildBoundsDirect(child, requested_bounds); 126 SetChildBoundsDirect(child, requested_bounds);
122 return; 127 return;
123 } 128 }
124 gfx::Rect child_bounds(requested_bounds); 129 gfx::Rect child_bounds(requested_bounds);
125 // Some windows rely on this to set their initial bounds. 130 // Some windows rely on this to set their initial bounds.
126 if (!SetMaximizedOrFullscreenBounds(wm::GetWindowState(child))) { 131 if (!SetMaximizedOrFullscreenBounds(window_state)) {
127 // Non-maximized/full-screen windows have their size constrained to the 132 // Non-maximized/full-screen windows have their size constrained to the
128 // work-area. 133 // work-area.
129 child_bounds.set_width(std::min(work_area_in_parent_.width(), 134 child_bounds.set_width(std::min(work_area_in_parent_.width(),
130 child_bounds.width())); 135 child_bounds.width()));
131 child_bounds.set_height( 136 child_bounds.set_height(
132 std::min(work_area_in_parent_.height(), child_bounds.height())); 137 std::min(work_area_in_parent_.height(), child_bounds.height()));
133 SetChildBoundsDirect(child, child_bounds); 138 AdjustSnappedBounds(window_state, &child_bounds);
139 if (window_state->window_show_type() == wm::SHOW_TYPE_LEFT_SNAPPED ||
140 window_state->window_show_type() == wm::SHOW_TYPE_RIGHT_SNAPPED) {
oshima 2013/11/25 23:20:40 Maybe we should have WindowState::IsLeftOrRightSna
varkha 2013/11/26 22:16:58 Done.
141 SetChildBoundsAnimated(child, child_bounds);
142 } else {
143 SetChildBoundsDirect(child, child_bounds);
144 }
134 } 145 }
135 UpdateDesktopVisibility(); 146 UpdateDesktopVisibility();
136 } 147 }
137 148
138 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() { 149 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() {
139 const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent( 150 const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
140 window_->parent())); 151 window_->parent()));
141 if (work_area != work_area_in_parent_) { 152 if (work_area != work_area_in_parent_) {
142 AdjustAllWindowsBoundsForWorkAreaChange( 153 AdjustAllWindowsBoundsForWorkAreaChange(
143 ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED); 154 ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED: 253 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED:
243 // The work area may be smaller than the full screen. Put as much of the 254 // The work area may be smaller than the full screen. Put as much of the
244 // window as possible within the display area. 255 // window as possible within the display area.
245 bounds.AdjustToFit(work_area_in_parent_); 256 bounds.AdjustToFit(work_area_in_parent_);
246 break; 257 break;
247 case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED: 258 case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED:
248 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( 259 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
249 work_area_in_parent_, &bounds); 260 work_area_in_parent_, &bounds);
250 break; 261 break;
251 } 262 }
263 AdjustSnappedBounds(window_state, &bounds);
252 if (window_state->window()->bounds() != bounds) 264 if (window_state->window()->bounds() != bounds)
253 window_state->window()->SetBounds(bounds); 265 SetChildBoundsAnimated(window_state->window(), bounds);
254 } 266 }
255 267
256 void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded( 268 void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded(
257 wm::WindowState* window_state) { 269 wm::WindowState* window_state) {
258 // Don't adjust window bounds if the bounds are empty as this 270 // Don't adjust window bounds if the bounds are empty as this
259 // happens when a new views::Widget is created. 271 // happens when a new views::Widget is created.
260 // When a window is dragged and dropped onto a different 272 // When a window is dragged and dropped onto a different
261 // root window, the bounds will be updated after they are added 273 // root window, the bounds will be updated after they are added
262 // to the root window. 274 // to the root window.
263 if (window_state->window()->bounds().IsEmpty()) 275 if (window_state->window()->bounds().IsEmpty())
(...skipping 10 matching lines...) Expand all
274 int min_width = bounds.width() * kMinimumPercentOnScreenArea; 286 int min_width = bounds.width() * kMinimumPercentOnScreenArea;
275 int min_height = bounds.height() * kMinimumPercentOnScreenArea; 287 int min_height = bounds.height() * kMinimumPercentOnScreenArea;
276 // Use entire display instead of workarea because the workarea can 288 // Use entire display instead of workarea because the workarea can
277 // be further shrunk by the docked area. The logic ensures 30% 289 // be further shrunk by the docked area. The logic ensures 30%
278 // visibility which should be enough to see where the window gets 290 // visibility which should be enough to see where the window gets
279 // moved. 291 // moved.
280 gfx::Rect display_area = ScreenAsh::GetDisplayBoundsInParent(window); 292 gfx::Rect display_area = ScreenAsh::GetDisplayBoundsInParent(window);
281 293
282 ash::wm::AdjustBoundsToEnsureWindowVisibility( 294 ash::wm::AdjustBoundsToEnsureWindowVisibility(
283 display_area, min_width, min_height, &bounds); 295 display_area, min_width, min_height, &bounds);
296 AdjustSnappedBounds(window_state, &bounds);
284 if (window->bounds() != bounds) 297 if (window->bounds() != bounds)
285 window->SetBounds(bounds); 298 window->SetBounds(bounds);
286 } 299 }
287 300
288 void WorkspaceLayoutManager::UpdateDesktopVisibility() { 301 void WorkspaceLayoutManager::UpdateDesktopVisibility() {
289 if (shelf_) 302 if (shelf_)
290 shelf_->UpdateVisibilityState(); 303 shelf_->UpdateVisibilityState();
291 } 304 }
292 305
293 void WorkspaceLayoutManager::UpdateBoundsFromShowState( 306 void WorkspaceLayoutManager::UpdateBoundsFromShowState(
294 wm::WindowState* window_state, 307 wm::WindowState* window_state,
295 ui::WindowShowState last_show_state) { 308 ui::WindowShowState last_show_state) {
296 aura::Window* window = window_state->window(); 309 aura::Window* window = window_state->window();
297 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in 310 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in
298 // these calculation. 311 // these calculation.
299 switch (window_state->GetShowState()) { 312 switch (window_state->GetShowState()) {
oshima 2013/11/25 23:20:40 is it possible to switch to use WindowShowType ins
varkha 2013/11/26 22:16:58 As we discussed this offline - let's do that in an
300 case ui::SHOW_STATE_DEFAULT: 313 case ui::SHOW_STATE_DEFAULT:
301 case ui::SHOW_STATE_NORMAL: { 314 case ui::SHOW_STATE_NORMAL: {
315 if ((last_show_state == ui::SHOW_STATE_DEFAULT ||
316 last_show_state == ui::SHOW_STATE_NORMAL) &&
317 (window_state->window_show_type() != wm::SHOW_TYPE_NORMAL)) {
318 // Do not override bounds of snapped windows.
319 break;
320 }
302 // Make sure that the part of the window is always visible 321 // Make sure that the part of the window is always visible
303 // when restored. 322 // when restored.
304 gfx::Rect bounds_in_parent; 323 gfx::Rect bounds_in_parent;
305 if (window_state->HasRestoreBounds()) { 324 if (window_state->HasRestoreBounds()) {
306 bounds_in_parent = window_state->GetRestoreBoundsInParent(); 325 bounds_in_parent = window_state->GetRestoreBoundsInParent();
307 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( 326 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
308 work_area_in_parent_, &bounds_in_parent); 327 work_area_in_parent_, &bounds_in_parent);
309 } else { 328 } else {
310 // Minimized windows have no restore bounds. 329 // Minimized windows have no restore bounds.
311 // Use the current bounds instead. 330 // Use the current bounds instead.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 if (window_state->IsFullscreen()) { 397 if (window_state->IsFullscreen()) {
379 SetChildBoundsDirect( 398 SetChildBoundsDirect(
380 window_state->window(), 399 window_state->window(),
381 ScreenAsh::GetDisplayBoundsInParent( 400 ScreenAsh::GetDisplayBoundsInParent(
382 window_state->window()->parent()->parent())); 401 window_state->window()->parent()->parent()));
383 return true; 402 return true;
384 } 403 }
385 return false; 404 return false;
386 } 405 }
387 406
407 void WorkspaceLayoutManager::AdjustSnappedBounds(wm::WindowState* window_state,
408 gfx::Rect* bounds) {
409 if (!window_state->tracked_by_workspace() ||
410 !window_state->IsNormalShowState() ||
411 (window_state->window_show_type() != wm::SHOW_TYPE_LEFT_SNAPPED &&
412 window_state->window_show_type() != wm::SHOW_TYPE_RIGHT_SNAPPED)) {
413 return;
414 }
415 gfx::Rect maximized_bounds = ScreenAsh::GetMaximizedWindowBoundsInParent(
416 window_state->window()->parent()->parent());
417 if (window_state->window_show_type() == wm::SHOW_TYPE_LEFT_SNAPPED)
418 bounds->set_x(maximized_bounds.x());
419 else if (window_state->window_show_type() == wm::SHOW_TYPE_RIGHT_SNAPPED)
420 bounds->set_x(maximized_bounds.right() - bounds->width());
421 bounds->set_y(maximized_bounds.y());
422 bounds->set_height(maximized_bounds.height());
423 }
424
425 void WorkspaceLayoutManager::SetChildBoundsAnimated(Window* child,
426 const gfx::Rect& bounds) {
427 ui::Layer* layer = child->layer();
428 ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator());
429 slide_settings.SetPreemptionStrategy(
430 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
431 slide_settings.SetTransitionDuration(
432 base::TimeDelta::FromMilliseconds(kSlideDurationMs));
433 SetChildBoundsDirect(child, bounds);
434 }
435
388 } // namespace internal 436 } // namespace internal
389 } // namespace ash 437 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698