Index: ash/wm/workspace/workspace_layout_manager.cc |
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc |
index a0ae8cc370528d126b15e364b1b26fffd34623f6..a25c80f109f653013719765dd2cc1422f10bd3a1 100644 |
--- a/ash/wm/workspace/workspace_layout_manager.cc |
+++ b/ash/wm/workspace/workspace_layout_manager.cc |
@@ -20,6 +20,7 @@ |
#include "ui/aura/window.h" |
#include "ui/aura/window_observer.h" |
#include "ui/base/ui_base_types.h" |
+#include "ui/compositor/scoped_layer_animation_settings.h" |
#include "ui/events/event.h" |
#include "ui/views/corewm/window_util.h" |
@@ -35,6 +36,9 @@ namespace { |
// must be visible when the window is added to the workspace. |
const float kMinimumPercentOnScreenArea = 0.3f; |
+// Duration of slide animation used when a snapped window is adjusted. |
+const int kSlideDurationMs = 120; |
+ |
void MoveToDisplayForRestore(wm::WindowState* window_state) { |
if (!window_state->HasRestoreBounds()) |
return; |
@@ -117,20 +121,27 @@ void WorkspaceLayoutManager::OnChildWindowVisibilityChanged(Window* child, |
void WorkspaceLayoutManager::SetChildBounds( |
Window* child, |
const gfx::Rect& requested_bounds) { |
- if (!wm::GetWindowState(child)->tracked_by_workspace()) { |
+ wm::WindowState* window_state = wm::GetWindowState(child); |
+ if (!window_state->tracked_by_workspace()) { |
SetChildBoundsDirect(child, requested_bounds); |
return; |
} |
gfx::Rect child_bounds(requested_bounds); |
// Some windows rely on this to set their initial bounds. |
- if (!SetMaximizedOrFullscreenBounds(wm::GetWindowState(child))) { |
+ if (!SetMaximizedOrFullscreenBounds(window_state)) { |
// Non-maximized/full-screen windows have their size constrained to the |
// work-area. |
child_bounds.set_width(std::min(work_area_in_parent_.width(), |
child_bounds.width())); |
child_bounds.set_height( |
std::min(work_area_in_parent_.height(), child_bounds.height())); |
- SetChildBoundsDirect(child, child_bounds); |
+ AdjustSnappedBounds(window_state, &child_bounds); |
+ if (window_state->window_show_type() == wm::SHOW_TYPE_LEFT_SNAPPED || |
+ 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.
|
+ SetChildBoundsAnimated(child, child_bounds); |
+ } else { |
+ SetChildBoundsDirect(child, child_bounds); |
+ } |
} |
UpdateDesktopVisibility(); |
} |
@@ -249,8 +260,9 @@ void WorkspaceLayoutManager::AdjustWindowBoundsForWorkAreaChange( |
work_area_in_parent_, &bounds); |
break; |
} |
+ AdjustSnappedBounds(window_state, &bounds); |
if (window_state->window()->bounds() != bounds) |
- window_state->window()->SetBounds(bounds); |
+ SetChildBoundsAnimated(window_state->window(), bounds); |
} |
void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded( |
@@ -281,6 +293,7 @@ void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded( |
ash::wm::AdjustBoundsToEnsureWindowVisibility( |
display_area, min_width, min_height, &bounds); |
+ AdjustSnappedBounds(window_state, &bounds); |
if (window->bounds() != bounds) |
window->SetBounds(bounds); |
} |
@@ -299,6 +312,12 @@ void WorkspaceLayoutManager::UpdateBoundsFromShowState( |
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
|
case ui::SHOW_STATE_DEFAULT: |
case ui::SHOW_STATE_NORMAL: { |
+ if ((last_show_state == ui::SHOW_STATE_DEFAULT || |
+ last_show_state == ui::SHOW_STATE_NORMAL) && |
+ (window_state->window_show_type() != wm::SHOW_TYPE_NORMAL)) { |
+ // Do not override bounds of snapped windows. |
+ break; |
+ } |
// Make sure that the part of the window is always visible |
// when restored. |
gfx::Rect bounds_in_parent; |
@@ -385,5 +404,34 @@ bool WorkspaceLayoutManager::SetMaximizedOrFullscreenBounds( |
return false; |
} |
+void WorkspaceLayoutManager::AdjustSnappedBounds(wm::WindowState* window_state, |
+ gfx::Rect* bounds) { |
+ if (!window_state->tracked_by_workspace() || |
+ !window_state->IsNormalShowState() || |
+ (window_state->window_show_type() != wm::SHOW_TYPE_LEFT_SNAPPED && |
+ window_state->window_show_type() != wm::SHOW_TYPE_RIGHT_SNAPPED)) { |
+ return; |
+ } |
+ gfx::Rect maximized_bounds = ScreenAsh::GetMaximizedWindowBoundsInParent( |
+ window_state->window()->parent()->parent()); |
+ if (window_state->window_show_type() == wm::SHOW_TYPE_LEFT_SNAPPED) |
+ bounds->set_x(maximized_bounds.x()); |
+ else if (window_state->window_show_type() == wm::SHOW_TYPE_RIGHT_SNAPPED) |
+ bounds->set_x(maximized_bounds.right() - bounds->width()); |
+ bounds->set_y(maximized_bounds.y()); |
+ bounds->set_height(maximized_bounds.height()); |
+} |
+ |
+void WorkspaceLayoutManager::SetChildBoundsAnimated(Window* child, |
+ const gfx::Rect& bounds) { |
+ ui::Layer* layer = child->layer(); |
+ ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator()); |
+ slide_settings.SetPreemptionStrategy( |
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
+ slide_settings.SetTransitionDuration( |
+ base::TimeDelta::FromMilliseconds(kSlideDurationMs)); |
+ SetChildBoundsDirect(child, bounds); |
+} |
+ |
} // namespace internal |
} // namespace ash |