summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-21 12:11:48 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-21 12:11:48 +0000
commit4fe2f9c7623f5227774aa2efef4fec1d3320a93d (patch)
tree46c57c04cd85383133d16548dc941af25822fde3 /ash
parent86f3df423e5c8b861ecbac4c7d3450d3351214db (diff)
downloadchromium_src-4fe2f9c7623f5227774aa2efef4fec1d3320a93d.zip
chromium_src-4fe2f9c7623f5227774aa2efef4fec1d3320a93d.tar.gz
chromium_src-4fe2f9c7623f5227774aa2efef4fec1d3320a93d.tar.bz2
Separate the function to update bounds for state transition
BUG=318325 Review URL: https://codereview.chromium.org/202943002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258540 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/wm/default_state.cc285
-rw-r--r--ash/wm/default_state.h25
-rw-r--r--ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc35
3 files changed, 174 insertions, 171 deletions
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc
index 4911483..c7f2cc2 100644
--- a/ash/wm/default_state.cc
+++ b/ash/wm/default_state.cc
@@ -128,87 +128,30 @@ void DefaultState::OnWMEvent(WindowState* window_state,
return;
}
- if (current != next_state_type) {
- state_type_ = next_state_type;
- window_state->UpdateWindowShowStateFromStateType();
- window_state->NotifyPreStateTypeChange(current);
- // TODO(oshima): Make docked window a state.
- if (window_state->IsSnapped() ||
- (!window_state->IsDocked() && !IsPanel(window_state->window()))) {
- UpdateBounds(window_state, current);
- }
- window_state->NotifyPostStateTypeChange(current);
- }
+ EnterToNextState(window_state, next_state_type);
}
WindowStateType DefaultState::GetType() const {
return state_type_;
}
-void DefaultState::AttachState(WindowState* window_state,
- WindowState::State* previous_state) {
+void DefaultState::AttachState(
+ WindowState* window_state,
+ WindowState::State* state_in_previous_mode) {
DCHECK_EQ(stored_window_state_, window_state);
- WindowStateType old_state_type = state_type_;
- state_type_ = previous_state->GetType();
- // Forget our restore sizes when the workspace size has changed.
- bool workspace_unchanged = stored_workspace_size_ ==
- window_state->window()->parent()->bounds().size();
+ ReenterToCurrentState(window_state, state_in_previous_mode);
- // Set the restore bounds to be the previous bounds - this might be required
- // for some state transitions like restore, so that the animations are sound.
- if (!stored_bounds_.IsEmpty() && workspace_unchanged)
- window_state->SetRestoreBoundsInParent(stored_bounds_);
- else
- window_state->ClearRestoreBounds();
-
- if (old_state_type != state_type_) {
- wm::WMEventType type = wm::WM_EVENT_NORMAL;
- switch (old_state_type) {
- case wm::WINDOW_STATE_TYPE_DEFAULT:
- case wm::WINDOW_STATE_TYPE_AUTO_POSITIONED:
- case wm::WINDOW_STATE_TYPE_NORMAL:
- case wm::WINDOW_STATE_TYPE_DETACHED:
- case wm::WINDOW_STATE_TYPE_END:
- break;
- case wm::WINDOW_STATE_TYPE_MINIMIZED:
- type = wm::WM_EVENT_MINIMIZE;
- break;
- case wm::WINDOW_STATE_TYPE_MAXIMIZED:
- type = wm::WM_EVENT_MAXIMIZE;
- break;
- case wm::WINDOW_STATE_TYPE_INACTIVE:
- type = wm::WM_EVENT_SHOW_INACTIVE;
- break;
- case wm::WINDOW_STATE_TYPE_FULLSCREEN:
- type = wm::WM_EVENT_TOGGLE_FULLSCREEN;
- break;
- case wm::WINDOW_STATE_TYPE_LEFT_SNAPPED:
- type = wm::WM_EVENT_SNAP_LEFT;
- break;
- case wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED:
- type = wm::WM_EVENT_SNAP_RIGHT;
- break;
- }
- wm::WMEvent event(type);
+ // If the display has changed while in the another mode,
+ // we need to let windows know the change.
+ gfx::Display current_display = Shell::GetScreen()->
+ GetDisplayNearestWindow(window_state->window());
+ if (stored_display_state_.bounds() != current_display.bounds()) {
+ const WMEvent event(wm::WM_EVENT_DISPLAY_BOUNDS_CHANGED);
+ window_state->OnWMEvent(&event);
+ } else if (stored_display_state_.work_area() != current_display.work_area()) {
+ const WMEvent event(wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED);
window_state->OnWMEvent(&event);
- }
-
- if (workspace_unchanged) {
- // If the bounds are not yet set and valid we restore them.
- if (!stored_bounds_.IsEmpty() &&
- stored_bounds_ != window_state->window()->bounds()) {
- if (state_type_ == wm::WINDOW_STATE_TYPE_MINIMIZED)
- window_state->SetBoundsDirect(stored_bounds_);
- else
- window_state->SetBoundsDirectAnimated(stored_bounds_);
- }
-
- // Then restore the restore bounds to their previous value.
- if (!stored_restore_bounds_.IsEmpty())
- window_state->SetRestoreBoundsInParent(stored_restore_bounds_);
- else
- window_state->ClearRestoreBounds();
}
}
@@ -218,10 +161,12 @@ void DefaultState::DetachState(WindowState* window_state) {
stored_bounds_ = window->bounds();
stored_restore_bounds_ = window_state->HasRestoreBounds() ?
window_state->GetRestoreBoundsInParent() : gfx::Rect();
- // If the container size for this window has changed we need to restore the
- // proper location of the window within the container. Note that this might
- // not be the same as the screen resolution.
- stored_workspace_size_ = window_state->window()->parent()->bounds().size();
+ // Remember the display state so that in case of the display change
+ // while in the other mode, we can perform necessary action to
+ // restore the window state to the proper state for the current
+ // display.
+ stored_display_state_ = Shell::GetScreen()->
+ GetDisplayNearestWindow(window_state->window());
}
// static
@@ -439,44 +384,125 @@ bool DefaultState::ProcessWorkspaceEvents(WindowState* window_state,
}
// static
-void DefaultState::UpdateBounds(WindowState* window_state,
- WindowStateType old_state_type) {
- aura::Window* window = window_state->window();
- // Do nothing If this is not yet added to the container.
- if (!window->parent())
+bool DefaultState::SetMaximizedOrFullscreenBounds(WindowState* window_state) {
+ DCHECK(!window_state->is_dragged());
+ if (window_state->IsMaximized()) {
+ window_state->SetBoundsDirect(
+ ScreenUtil::GetMaximizedWindowBoundsInParent(window_state->window()));
+ return true;
+ }
+ if (window_state->IsFullscreen()) {
+ window_state->SetBoundsDirect(
+ ScreenUtil::GetDisplayBoundsInParent(window_state->window()));
+ return true;
+ }
+ return false;
+}
+
+// static
+void DefaultState::SetBounds(WindowState* window_state,
+ const SetBoundsEvent* event) {
+ if (window_state->is_dragged()) {
+ window_state->SetBoundsDirect(event->requested_bounds());
+ } else if (window_state->IsSnapped()) {
+ gfx::Rect work_area_in_parent =
+ ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_state->window());
+ gfx::Rect child_bounds(event->requested_bounds());
+ AdjustBoundsSmallerThan(work_area_in_parent.size(), &child_bounds);
+ window_state->AdjustSnappedBounds(&child_bounds);
+ window_state->SetBoundsDirect(child_bounds);
+ } else if (!SetMaximizedOrFullscreenBounds(window_state)) {
+ window_state->SetBoundsConstrained(event->requested_bounds());
+ }
+}
+
+void DefaultState::EnterToNextState(WindowState* window_state,
+ WindowStateType next_state_type) {
+ // Do nothing if we're already in the same state.
+ if (state_type_ == next_state_type)
return;
- if (!window_state->HasRestoreBounds() &&
- (old_state_type == WINDOW_STATE_TYPE_DEFAULT ||
- old_state_type == WINDOW_STATE_TYPE_NORMAL) &&
- !window_state->IsMinimized() &&
- !window_state->IsNormalStateType()) {
- window_state->SaveCurrentBoundsForRestore();
+ WindowStateType previous_state_type = state_type_;
+ state_type_ = next_state_type;
+
+ window_state->UpdateWindowShowStateFromStateType();
+ window_state->NotifyPreStateTypeChange(previous_state_type);
+
+ // This Docked/Snapped hack is due to the issue that IsDocked returns
+ // true for dragging window. TODO(oshima): Make docked window a state
+ // and remove this hack.
+ if (window_state->window()->parent() &&
+ (window_state->IsSnapped() ||
+ (!window_state->IsDocked() && !IsPanel(window_state->window())))) {
+ if (!window_state->HasRestoreBounds() &&
+ (previous_state_type == WINDOW_STATE_TYPE_DEFAULT ||
+ previous_state_type == WINDOW_STATE_TYPE_NORMAL) &&
+ !window_state->IsMinimized() &&
+ !window_state->IsNormalStateType()) {
+ window_state->SaveCurrentBoundsForRestore();
+ }
+
+ // When restoring from a minimized state, we want to restore to the previous
+ // bounds. However, we want to maintain the restore bounds. (The restore
+ // bounds are set if a user maximized the window in one axis by double
+ // clicking the window border for example).
+ gfx::Rect restore_bounds_in_screen;
+ if (previous_state_type == WINDOW_STATE_TYPE_MINIMIZED &&
+ window_state->IsNormalStateType() &&
+ window_state->HasRestoreBounds() &&
+ !window_state->unminimize_to_restore_bounds()) {
+ restore_bounds_in_screen = window_state->GetRestoreBoundsInScreen();
+ window_state->SaveCurrentBoundsForRestore();
+ }
+
+ if (window_state->IsMaximizedOrFullscreen())
+ MoveToDisplayForRestore(window_state);
+
+ UpdateBoundsFromState(window_state, previous_state_type);
+
+ // Normal state should have no restore bounds unless it's
+ // unminimzied.
+ if (!restore_bounds_in_screen.IsEmpty())
+ window_state->SetRestoreBoundsInScreen(restore_bounds_in_screen);
+ else if (window_state->IsNormalStateType())
+ window_state->ClearRestoreBounds();
}
+ window_state->NotifyPostStateTypeChange(previous_state_type);
+}
- // When restoring from a minimized state, we want to restore to the previous
- // bounds. However, we want to maintain the restore bounds. (The restore
- // bounds are set if a user maximized the window in one axis by double
- // clicking the window border for example).
- gfx::Rect restore_bounds_in_screen;
- if (old_state_type == WINDOW_STATE_TYPE_MINIMIZED &&
- window_state->IsNormalStateType() &&
- window_state->HasRestoreBounds() &&
- !window_state->unminimize_to_restore_bounds()) {
- restore_bounds_in_screen = window_state->GetRestoreBoundsInScreen();
- window_state->SaveCurrentBoundsForRestore();
+void DefaultState::ReenterToCurrentState(
+ WindowState* window_state,
+ WindowState::State* state_in_previous_mode) {
+ WindowStateType previous_state_type = state_in_previous_mode->GetType();
+ window_state->UpdateWindowShowStateFromStateType();
+ window_state->NotifyPreStateTypeChange(previous_state_type);
+
+ if (state_type_ == wm::WINDOW_STATE_TYPE_NORMAL ||
+ state_type_ == wm::WINDOW_STATE_TYPE_DEFAULT) {
+ // Use the restore mechanism to set the bounds for
+ // the window in normal state. This also covers unminimize case.
+ window_state->SetRestoreBoundsInParent(stored_bounds_);
}
- if (window_state->IsMaximizedOrFullscreen())
- MoveToDisplayForRestore(window_state);
+ UpdateBoundsFromState(window_state, state_in_previous_mode->GetType());
- WindowStateType state_type = window_state->GetStateType();
- gfx::Rect bounds_in_parent;
+ // Then restore the restore bounds to their previous value.
+ if (!stored_restore_bounds_.IsEmpty())
+ window_state->SetRestoreBoundsInParent(stored_restore_bounds_);
+ else
+ window_state->ClearRestoreBounds();
+
+ window_state->NotifyPostStateTypeChange(previous_state_type);
+}
- switch (state_type) {
+void DefaultState::UpdateBoundsFromState(WindowState* window_state,
+ WindowStateType previous_state_type) {
+ aura::Window* window = window_state->window();
+ gfx::Rect bounds_in_parent;
+ switch (state_type_) {
case WINDOW_STATE_TYPE_LEFT_SNAPPED:
case WINDOW_STATE_TYPE_RIGHT_SNAPPED:
- bounds_in_parent = state_type == WINDOW_STATE_TYPE_LEFT_SNAPPED ?
+ bounds_in_parent = state_type_ == WINDOW_STATE_TYPE_LEFT_SNAPPED ?
GetDefaultLeftSnappedWindowBoundsInParent(window_state->window()) :
GetDefaultRightSnappedWindowBoundsInParent(window_state->window());
break;
@@ -510,12 +536,12 @@ void DefaultState::UpdateBounds(WindowState* window_state,
return;
}
- if (state_type != WINDOW_STATE_TYPE_MINIMIZED) {
- if (old_state_type == WINDOW_STATE_TYPE_MINIMIZED ||
+ if (state_type_ != WINDOW_STATE_TYPE_MINIMIZED) {
+ if (previous_state_type == WINDOW_STATE_TYPE_MINIMIZED ||
window_state->IsFullscreen()) {
window_state->SetBoundsDirect(bounds_in_parent);
} else if (window_state->IsMaximized() ||
- IsMaximizedOrFullscreenWindowStateType(old_state_type)) {
+ IsMaximizedOrFullscreenWindowStateType(previous_state_type)) {
window_state->SetBoundsDirectCrossFade(bounds_in_parent);
} else if (window_state->is_dragged()) {
// SetBoundsDirectAnimated does not work when the window gets reparented.
@@ -529,7 +555,7 @@ void DefaultState::UpdateBounds(WindowState* window_state,
if (window_state->IsMinimized()) {
// Save the previous show state so that we can correctly restore it.
window_state->window()->SetProperty(aura::client::kRestoreShowStateKey,
- ToWindowShowState(old_state_type));
+ ToWindowShowState(previous_state_type));
::wm::SetWindowVisibilityAnimationType(
window_state->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
@@ -539,57 +565,16 @@ void DefaultState::UpdateBounds(WindowState* window_state,
if (window_state->IsActive())
window_state->Deactivate();
} else if ((window_state->window()->TargetVisibility() ||
- old_state_type == WINDOW_STATE_TYPE_MINIMIZED) &&
+ previous_state_type == WINDOW_STATE_TYPE_MINIMIZED) &&
!window_state->window()->layer()->visible()) {
// The layer may be hidden if the window was previously minimized. Make
// sure it's visible.
window_state->window()->Show();
- if (old_state_type == WINDOW_STATE_TYPE_MINIMIZED &&
+ if (previous_state_type == WINDOW_STATE_TYPE_MINIMIZED &&
!window_state->IsMaximizedOrFullscreen()) {
window_state->set_unminimize_to_restore_bounds(false);
}
}
-
- if (window_state->IsNormalStateType())
- window_state->ClearRestoreBounds();
-
- // Set the restore rectangle to the previously set restore rectangle.
- if (!restore_bounds_in_screen.IsEmpty())
- window_state->SetRestoreBoundsInScreen(restore_bounds_in_screen);
-}
-
-// static
-bool DefaultState::SetMaximizedOrFullscreenBounds(WindowState* window_state) {
- DCHECK(!window_state->is_dragged());
- if (window_state->IsMaximized()) {
- window_state->SetBoundsDirect(
- ScreenUtil::GetMaximizedWindowBoundsInParent(window_state->window()));
- return true;
- }
- if (window_state->IsFullscreen()) {
- window_state->SetBoundsDirect(
- ScreenUtil::GetDisplayBoundsInParent(window_state->window()));
- return true;
- }
- return false;
-}
-
-// static
-void DefaultState::SetBounds(WindowState* window_state,
- const SetBoundsEvent* event) {
-
- if (window_state->is_dragged()) {
- window_state->SetBoundsDirect(event->requested_bounds());
- } else if (window_state->IsSnapped()) {
- gfx::Rect work_area_in_parent =
- ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_state->window());
- gfx::Rect child_bounds(event->requested_bounds());
- AdjustBoundsSmallerThan(work_area_in_parent.size(), &child_bounds);
- window_state->AdjustSnappedBounds(&child_bounds);
- window_state->SetBoundsDirect(child_bounds);
- } else if (!SetMaximizedOrFullscreenBounds(window_state)) {
- window_state->SetBoundsConstrained(event->requested_bounds());
- }
}
// static
diff --git a/ash/wm/default_state.h b/ash/wm/default_state.h
index cfab381..ccee0f88 100644
--- a/ash/wm/default_state.h
+++ b/ash/wm/default_state.h
@@ -6,6 +6,7 @@
#define ASH_WM_DEFAULT_STATE_H_
#include "ash/wm/window_state.h"
+#include "ui/gfx/display.h"
namespace ash {
namespace wm {
@@ -35,10 +36,6 @@ class DefaultState : public WindowState::State {
static bool ProcessWorkspaceEvents(WindowState* window_state,
const WMEvent* event);
- // Animates to new window bounds based on the current and previous state type.
- static void UpdateBounds(wm::WindowState* window_state,
- wm::WindowStateType old_state_type);
-
// Set the fullscreen/maximized bounds without animation.
static bool SetMaximizedOrFullscreenBounds(wm::WindowState* window_state);
@@ -47,6 +44,21 @@ class DefaultState : public WindowState::State {
static void CenterWindow(WindowState* window_state);
+ // Enters next state. This is used when the state moves from one to another
+ // within the same desktop mode.
+ void EnterToNextState(wm::WindowState* window_state,
+ wm::WindowStateType next_state_type);
+
+ // Reenters the current state. This is called when migrating from
+ // previous desktop mode, and the window's state needs to re-construct the
+ // state/bounds for this state.
+ void ReenterToCurrentState(wm::WindowState* window_state,
+ wm::WindowState::State* state_in_previous_mode);
+
+ // Animates to new window bounds based on the current and previous state type.
+ void UpdateBoundsFromState(wm::WindowState* window_state,
+ wm::WindowStateType old_state_type);
+
// The current type of the window.
WindowStateType state_type_;
@@ -54,9 +66,8 @@ class DefaultState : public WindowState::State {
gfx::Rect stored_bounds_;
gfx::Rect stored_restore_bounds_;
- // The size of the workspace when the mode got started. If it differs from
- // the current values the bounds will get ignored.
- gfx::Size stored_workspace_size_;
+ // The display state in which the mode got started.
+ gfx::Display stored_display_state_;
// The window state only gets remembered for DCHECK reasons.
WindowState* stored_window_state_;
diff --git a/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc b/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
index f2ee161..82b07d7 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
@@ -65,11 +65,10 @@ class MaximizeModeWindowManagerTest : public test::AshTestBase {
// Resize our desktop.
void ResizeDesktop(int width_delta) {
- aura::Window* container = Shell::GetContainer(
- Shell::GetPrimaryRootWindow(), kSwitchableWindowContainerIds[0]);
- gfx::Rect bounds = container->bounds();
- bounds.set_width(bounds.width() - width_delta);
- container->SetBounds(bounds);
+ gfx::Size size = Shell::GetScreen()->GetDisplayNearestWindow(
+ Shell::GetPrimaryRootWindow()).size();
+ size.Enlarge(0, width_delta);
+ UpdateDisplay(size.ToString());
}
private:
@@ -356,31 +355,39 @@ TEST_F(MaximizeModeWindowManagerTest, MinimizedWindowBehavior) {
// Check that resizing the desktop does reposition unmaximizable & managed
// windows.
TEST_F(MaximizeModeWindowManagerTest, DesktopSizeChangeMovesUnmaximizable) {
- gfx::Rect rect(20, 140, 100, 100);
- scoped_ptr<aura::Window> window(
+ UpdateDisplay("400x400");
+ // This window will move because it does not fit the new bounds.
+ gfx::Rect rect(20, 300, 100, 100);
+ scoped_ptr<aura::Window> window1(
CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
- EXPECT_EQ(rect.ToString(), window->bounds().ToString());
+ EXPECT_EQ(rect.ToString(), window1->bounds().ToString());
+
+ // This window will not move because it does fit the new bounds.
+ gfx::Rect rect2(20, 140, 100, 100);
+ scoped_ptr<aura::Window> window2(
+ CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect2));
// Turning on the manager will reposition (but not resize) the window.
ash::internal::MaximizeModeWindowManager* manager =
CreateMaximizeModeWindowManager();
ASSERT_TRUE(manager);
- EXPECT_EQ(1, manager->GetNumberOfManagedWindows());
- gfx::Rect moved_bounds(window->bounds());
+ EXPECT_EQ(2, manager->GetNumberOfManagedWindows());
+ gfx::Rect moved_bounds(window1->bounds());
EXPECT_NE(rect.origin().ToString(), moved_bounds.origin().ToString());
EXPECT_EQ(rect.size().ToString(), moved_bounds.size().ToString());
// Simulating a desktop resize should move the window again.
- ResizeDesktop(-10);
- gfx::Rect new_moved_bounds(window->bounds());
+ UpdateDisplay("300x300");
+ gfx::Rect new_moved_bounds(window1->bounds());
EXPECT_NE(rect.origin().ToString(), new_moved_bounds.origin().ToString());
EXPECT_EQ(rect.size().ToString(), new_moved_bounds.size().ToString());
EXPECT_NE(moved_bounds.origin().ToString(), new_moved_bounds.ToString());
// Turning off the mode should not restore to the initial coordinates since
- // the new resolution is different.
+ // the new resolution is smaller and the window was on the edge.
DestroyMaximizeModeWindowManager();
- EXPECT_NE(rect.ToString(), window->bounds().ToString());
+ EXPECT_NE(rect.ToString(), window1->bounds().ToString());
+ EXPECT_EQ(rect2.ToString(), window2->bounds().ToString());
}
// Check that windows return to original location if desktop size changes to