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

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 (nits) 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 {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 false, child->GetRootWindow()); 111 false, child->GetRootWindow());
111 } 112 }
112 WindowPositioner::RearrangeVisibleWindowOnHideOrRemove(child); 113 WindowPositioner::RearrangeVisibleWindowOnHideOrRemove(child);
113 } 114 }
114 UpdateDesktopVisibility(); 115 UpdateDesktopVisibility();
115 } 116 }
116 117
117 void WorkspaceLayoutManager::SetChildBounds( 118 void WorkspaceLayoutManager::SetChildBounds(
118 Window* child, 119 Window* child,
119 const gfx::Rect& requested_bounds) { 120 const gfx::Rect& requested_bounds) {
120 if (!wm::GetWindowState(child)->tracked_by_workspace()) { 121 wm::WindowState* window_state = wm::GetWindowState(child);
122 if (!window_state->tracked_by_workspace()) {
121 SetChildBoundsDirect(child, requested_bounds); 123 SetChildBoundsDirect(child, requested_bounds);
122 return; 124 return;
123 } 125 }
124 gfx::Rect child_bounds(requested_bounds); 126 gfx::Rect child_bounds(requested_bounds);
125 // Some windows rely on this to set their initial bounds. 127 // Some windows rely on this to set their initial bounds.
126 if (!SetMaximizedOrFullscreenBounds(wm::GetWindowState(child))) { 128 if (!SetMaximizedOrFullscreenBounds(window_state)) {
127 // Non-maximized/full-screen windows have their size constrained to the 129 // Non-maximized/full-screen windows have their size constrained to the
128 // work-area. 130 // work-area.
129 child_bounds.set_width(std::min(work_area_in_parent_.width(), 131 child_bounds.set_width(std::min(work_area_in_parent_.width(),
130 child_bounds.width())); 132 child_bounds.width()));
131 child_bounds.set_height( 133 child_bounds.set_height(std::min(work_area_in_parent_.height(),
132 std::min(work_area_in_parent_.height(), child_bounds.height())); 134 child_bounds.height()));
135 AdjustSnappedBounds(window_state, &child_bounds);
oshima 2014/02/12 17:55:04 This is the one I had a question about.
pkotwicz 2014/02/12 21:15:22 AdjustSnappedBounds() is needed to prevent v2 apps
133 SetChildBoundsDirect(child, child_bounds); 136 SetChildBoundsDirect(child, child_bounds);
134 } 137 }
135 UpdateDesktopVisibility(); 138 UpdateDesktopVisibility();
136 } 139 }
137 140
138 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() { 141 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() {
139 const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent( 142 const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
140 window_->parent())); 143 window_->parent()));
141 if (work_area != work_area_in_parent_) { 144 if (work_area != work_area_in_parent_) {
142 AdjustAllWindowsBoundsForWorkAreaChange( 145 AdjustAllWindowsBoundsForWorkAreaChange(
143 ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED); 146 ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED);
144 } 147 }
145 } 148 }
146 149
147 void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window, 150 void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window,
148 const void* key, 151 const void* key,
149 intptr_t old) { 152 intptr_t old) {
150 if (key == aura::client::kAlwaysOnTopKey && 153 if (key == aura::client::kAlwaysOnTopKey &&
151 window->GetProperty(aura::client::kAlwaysOnTopKey)) { 154 window->GetProperty(aura::client::kAlwaysOnTopKey)) {
152 GetRootWindowController(window->GetRootWindow())-> 155 GetRootWindowController(window->GetRootWindow())->
153 always_on_top_controller()->GetContainer(window)->AddChild(window); 156 always_on_top_controller()->GetContainer(window)->AddChild(window);
154 } 157 }
155 } 158 }
156 159
157 void WorkspaceLayoutManager::OnTrackedByWorkspaceChanged( 160 void WorkspaceLayoutManager::OnTrackedByWorkspaceChanged(
158 wm::WindowState* window_state, 161 wm::WindowState* window_state,
159 bool old){ 162 bool old){
160 if (window_state->tracked_by_workspace()) 163 if (window_state->tracked_by_workspace()) {
161 SetMaximizedOrFullscreenBounds(window_state); 164 if (!SetMaximizedOrFullscreenBounds(window_state)) {
165 gfx::Rect bounds = window_state->window()->bounds();
166 AdjustSnappedBounds(window_state, &bounds);
167 if (window_state->window()->bounds() != bounds)
168 SetChildBoundsDirect(window_state->window(), bounds);
169 }
170 }
162 } 171 }
163 172
164 void WorkspaceLayoutManager::OnWindowShowTypeChanged( 173 void WorkspaceLayoutManager::OnWindowShowTypeChanged(
165 wm::WindowState* window_state, 174 wm::WindowState* window_state,
166 wm::WindowShowType old_type) { 175 wm::WindowShowType old_type) {
167 ui::WindowShowState old_state = ToWindowShowState(old_type); 176 ui::WindowShowState old_state = ToWindowShowState(old_type);
168 ui::WindowShowState new_state = window_state->GetShowState(); 177 ui::WindowShowState new_state = window_state->GetShowState();
169 if (old_state != ui::SHOW_STATE_MINIMIZED && 178 if (old_state != ui::SHOW_STATE_MINIMIZED &&
170 !window_state->HasRestoreBounds() && 179 !window_state->HasRestoreBounds() &&
171 window_state->IsMaximizedOrFullscreen() && 180 window_state->IsMaximizedOrFullscreen() &&
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED: 251 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED:
243 // The work area may be smaller than the full screen. Put as much of the 252 // The work area may be smaller than the full screen. Put as much of the
244 // window as possible within the display area. 253 // window as possible within the display area.
245 bounds.AdjustToFit(work_area_in_parent_); 254 bounds.AdjustToFit(work_area_in_parent_);
246 break; 255 break;
247 case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED: 256 case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED:
248 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( 257 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
249 work_area_in_parent_, &bounds); 258 work_area_in_parent_, &bounds);
250 break; 259 break;
251 } 260 }
261 AdjustSnappedBounds(window_state, &bounds);
oshima 2014/02/12 01:43:41 varkha@, sorry to ask you about old CL. All tests
varkha 2014/02/12 02:27:29 I think this was to keep a window snapped when doc
pkotwicz 2014/02/12 03:14:52 I just checked. AdjustSnappedBounds() is similar t
oshima 2014/02/12 17:55:04 Doh, sorry I put the comment in wrong place. See a
252 if (window_state->window()->bounds() != bounds) 262 if (window_state->window()->bounds() != bounds)
253 window_state->window()->SetBounds(bounds); 263 SetChildBoundsAnimated(window_state->window(), bounds);
254 } 264 }
255 265
256 void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded( 266 void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded(
257 wm::WindowState* window_state) { 267 wm::WindowState* window_state) {
258 // Don't adjust window bounds if the bounds are empty as this 268 // Don't adjust window bounds if the bounds are empty as this
259 // happens when a new views::Widget is created. 269 // happens when a new views::Widget is created.
260 // When a window is dragged and dropped onto a different 270 // When a window is dragged and dropped onto a different
261 // root window, the bounds will be updated after they are added 271 // root window, the bounds will be updated after they are added
262 // to the root window. 272 // to the root window.
263 if (window_state->window()->bounds().IsEmpty()) 273 if (window_state->window()->bounds().IsEmpty())
(...skipping 10 matching lines...) Expand all
274 int min_width = bounds.width() * kMinimumPercentOnScreenArea; 284 int min_width = bounds.width() * kMinimumPercentOnScreenArea;
275 int min_height = bounds.height() * kMinimumPercentOnScreenArea; 285 int min_height = bounds.height() * kMinimumPercentOnScreenArea;
276 // Use entire display instead of workarea because the workarea can 286 // Use entire display instead of workarea because the workarea can
277 // be further shrunk by the docked area. The logic ensures 30% 287 // be further shrunk by the docked area. The logic ensures 30%
278 // visibility which should be enough to see where the window gets 288 // visibility which should be enough to see where the window gets
279 // moved. 289 // moved.
280 gfx::Rect display_area = ScreenAsh::GetDisplayBoundsInParent(window); 290 gfx::Rect display_area = ScreenAsh::GetDisplayBoundsInParent(window);
281 291
282 ash::wm::AdjustBoundsToEnsureWindowVisibility( 292 ash::wm::AdjustBoundsToEnsureWindowVisibility(
283 display_area, min_width, min_height, &bounds); 293 display_area, min_width, min_height, &bounds);
294 AdjustSnappedBounds(window_state, &bounds);
284 if (window->bounds() != bounds) 295 if (window->bounds() != bounds)
285 window->SetBounds(bounds); 296 window->SetBounds(bounds);
286 } 297 }
287 298
288 void WorkspaceLayoutManager::UpdateDesktopVisibility() { 299 void WorkspaceLayoutManager::UpdateDesktopVisibility() {
289 if (shelf_) 300 if (shelf_)
290 shelf_->UpdateVisibilityState(); 301 shelf_->UpdateVisibilityState();
291 } 302 }
292 303
293 void WorkspaceLayoutManager::UpdateBoundsFromShowState( 304 void WorkspaceLayoutManager::UpdateBoundsFromShowState(
294 wm::WindowState* window_state, 305 wm::WindowState* window_state,
295 ui::WindowShowState last_show_state) { 306 ui::WindowShowState last_show_state) {
296 aura::Window* window = window_state->window(); 307 aura::Window* window = window_state->window();
297 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in 308 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in
298 // these calculation. 309 // these calculation.
310 // TODO(varkha): Change the switch statement below to use wm::WindowShowType.
299 switch (window_state->GetShowState()) { 311 switch (window_state->GetShowState()) {
300 case ui::SHOW_STATE_DEFAULT: 312 case ui::SHOW_STATE_DEFAULT:
301 case ui::SHOW_STATE_NORMAL: { 313 case ui::SHOW_STATE_NORMAL: {
302 // Make sure that the part of the window is always visible 314 // Make sure that the part of the window is always visible
303 // when restored. 315 // when restored.
304 gfx::Rect bounds_in_parent; 316 gfx::Rect bounds_in_parent;
305 if (window_state->HasRestoreBounds()) { 317 if (window_state->HasRestoreBounds()) {
306 bounds_in_parent = window_state->GetRestoreBoundsInParent(); 318 bounds_in_parent = window_state->GetRestoreBoundsInParent();
307 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( 319 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
308 work_area_in_parent_, &bounds_in_parent); 320 work_area_in_parent_, &bounds_in_parent);
309 } else { 321 } else {
310 // Minimized windows have no restore bounds. 322 // Minimized windows have no restore bounds.
311 // Use the current bounds instead. 323 // Use the current bounds instead.
312 bounds_in_parent = window->bounds(); 324 bounds_in_parent = window->bounds();
313 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( 325 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
314 work_area_in_parent_, &bounds_in_parent); 326 work_area_in_parent_, &bounds_in_parent);
315 // Don't start animation if the bounds didn't change. 327 // Don't start animation if the bounds didn't change.
316 if (bounds_in_parent == window->bounds()) 328 if (bounds_in_parent == window->bounds())
317 bounds_in_parent.SetRect(0, 0, 0, 0); 329 bounds_in_parent.SetRect(0, 0, 0, 0);
318 } 330 }
319 if (!bounds_in_parent.IsEmpty()) { 331 if (!bounds_in_parent.IsEmpty()) {
320 gfx::Rect new_bounds = BaseLayoutManager::BoundsWithScreenEdgeVisible( 332 if ((last_show_state == ui::SHOW_STATE_DEFAULT ||
321 window->parent()->parent(), 333 last_show_state == ui::SHOW_STATE_NORMAL) &&
322 bounds_in_parent); 334 window_state->IsSnapped()) {
323 if (last_show_state == ui::SHOW_STATE_MINIMIZED) 335 AdjustSnappedBounds(window_state, &bounds_in_parent);
324 SetChildBoundsDirect(window, new_bounds); 336 SetChildBoundsAnimated(window, bounds_in_parent);
325 else 337 } else {
326 CrossFadeToBounds(window, new_bounds); 338 gfx::Rect new_bounds = BaseLayoutManager::BoundsWithScreenEdgeVisible(
339 window->parent()->parent(),
340 bounds_in_parent);
341 if (last_show_state == ui::SHOW_STATE_MINIMIZED)
342 SetChildBoundsDirect(window, new_bounds);
343 else
344 CrossFadeToBounds(window, new_bounds);
345 }
327 } 346 }
328 window_state->ClearRestoreBounds(); 347 window_state->ClearRestoreBounds();
329 break; 348 break;
330 } 349 }
331 350
332 case ui::SHOW_STATE_MAXIMIZED: { 351 case ui::SHOW_STATE_MAXIMIZED: {
333 MoveToDisplayForRestore(window_state); 352 MoveToDisplayForRestore(window_state);
334 gfx::Rect new_bounds = ScreenAsh::GetMaximizedWindowBoundsInParent( 353 gfx::Rect new_bounds = ScreenAsh::GetMaximizedWindowBoundsInParent(
335 window->parent()->parent()); 354 window->parent()->parent());
336 // If the window is restored from minimized state, do not make the cross 355 // If the window is restored from minimized state, do not make the cross
(...skipping 41 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 // TODO(varkha): DockedWindowResizer sets |WindowState::tracked_by_workspace_|
410 // to false during the drag. The same can be done in WorkspaceWindowResizer.
411 // This will allow us to remove the check for window_resizer() to determine if
412 // the window is being dragged.
413 if (!window_state->tracked_by_workspace() ||
414 !window_state->IsSnapped() ||
415 window_state->window_resizer())
416 return;
417 gfx::Rect maximized_bounds = ScreenAsh::GetMaximizedWindowBoundsInParent(
418 window_state->window()->parent()->parent());
419 if (window_state->window_show_type() == wm::SHOW_TYPE_LEFT_SNAPPED)
420 bounds->set_x(maximized_bounds.x());
421 else if (window_state->window_show_type() == wm::SHOW_TYPE_RIGHT_SNAPPED)
422 bounds->set_x(maximized_bounds.right() - bounds->width());
423 bounds->set_y(maximized_bounds.y());
424 // TODO(varkha): Set width to 50% here for snapped windows.
425 bounds->set_height(maximized_bounds.height());
426 }
427
428 void WorkspaceLayoutManager::SetChildBoundsAnimated(Window* child,
429 const gfx::Rect& bounds) {
430 const int kBoundsChangeSlideDurationMs = 120;
431
432 ui::Layer* layer = child->layer();
433 ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator());
434 slide_settings.SetPreemptionStrategy(
435 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
436 slide_settings.SetTransitionDuration(
437 base::TimeDelta::FromMilliseconds(kBoundsChangeSlideDurationMs));
438 SetChildBoundsDirect(child, bounds);
439 }
440
388 } // namespace internal 441 } // namespace internal
389 } // namespace ash 442 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/workspace/workspace_layout_manager.h ('k') | ash/wm/workspace/workspace_window_resizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698