diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-29 01:28:45 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-29 01:28:45 +0000 |
commit | dd040cab9330c2618ee2ffb108e3a1e259c8afe8 (patch) | |
tree | 808b46f238a163bc7d88265393d5cf2cdd3d33ad /ash | |
parent | 9298cbc65bfd6e464548a42402f66da1ad3c82c8 (diff) | |
download | chromium_src-dd040cab9330c2618ee2ffb108e3a1e259c8afe8.zip chromium_src-dd040cab9330c2618ee2ffb108e3a1e259c8afe8.tar.gz chromium_src-dd040cab9330c2618ee2ffb108e3a1e259c8afe8.tar.bz2 |
Introduce WindowShowType which specifies the ash specific window show state.
* define separate file for WindowStateObserver.
Next step.
* Change auto placing code to update the state.
* Notify observers when ash specific state has changed.
Fix code and tests.
BUG=272460
R=jamescook@chromium.org
Review URL: https://codereview.chromium.org/23736012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225870 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
28 files changed, 470 insertions, 256 deletions
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index bf9a812..a6d0d49 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc @@ -826,16 +826,16 @@ bool AcceleratorController::PerformAction(int action, return true; case WINDOW_SNAP_LEFT: case WINDOW_SNAP_RIGHT: { - aura::Window* window = wm::GetActiveWindow(); + wm::WindowState* window_state = wm::GetActiveWindowState(); // Disable window docking shortcut key for full screen window due to // http://crbug.com/135487. - if (!window || - window->type() != aura::client::WINDOW_TYPE_NORMAL || - wm::GetWindowState(window)->IsFullscreen()) { + if (!window_state || + window_state->window()->type() != aura::client::WINDOW_TYPE_NORMAL || + window_state->IsFullscreen()) { break; } - internal::SnapSizer::SnapWindow(window, + internal::SnapSizer::SnapWindow(window_state, action == WINDOW_SNAP_LEFT ? internal::SnapSizer::LEFT_EDGE : internal::SnapSizer::RIGHT_EDGE); return true; diff --git a/ash/ash.gyp b/ash/ash.gyp index fd0a5a5..c0485d2 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -515,12 +515,15 @@ 'wm/window_cycle_list.h', 'wm/window_state.cc', 'wm/window_state.h', + 'wm/window_state_observer.h', 'wm/window_properties.cc', 'wm/window_properties.h', 'wm/window_resizer.cc', 'wm/window_resizer.h', 'wm/window_util.cc', 'wm/window_util.h', + 'wm/wm_types.cc', + 'wm/wm_types.h', 'wm/workspace_controller.cc', 'wm/workspace_controller.h', 'wm/workspace/auto_window_management.cc', diff --git a/ash/wm/base_layout_manager.cc b/ash/wm/base_layout_manager.cc index 7685674..90c0d97 100644 --- a/ash/wm/base_layout_manager.cc +++ b/ash/wm/base_layout_manager.cc @@ -110,29 +110,6 @@ void BaseLayoutManager::SetChildBounds(aura::Window* child, ///////////////////////////////////////////////////////////////////////////// // BaseLayoutManager, aura::WindowObserver overrides: -void BaseLayoutManager::OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) { - if (key == aura::client::kShowStateKey) { - ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old); - ui::WindowShowState new_state = - window->GetProperty(aura::client::kShowStateKey); - wm::WindowState* window_state = wm::GetWindowState(window); - - if (old_state != new_state && old_state != ui::SHOW_STATE_MINIMIZED && - !window_state->HasRestoreBounds() && - ((new_state == ui::SHOW_STATE_MAXIMIZED && - old_state != ui::SHOW_STATE_FULLSCREEN) || - (new_state == ui::SHOW_STATE_FULLSCREEN && - old_state != ui::SHOW_STATE_MAXIMIZED))) { - window_state->SetRestoreBoundsInParent(window->bounds()); - } - - UpdateBoundsFromShowState(window_state); - ShowStateChanged(window_state, old_state); - } -} - void BaseLayoutManager::OnWindowDestroying(aura::Window* window) { if (root_window_ == window) { root_window_->RemoveObserver(this); @@ -168,6 +145,27 @@ void BaseLayoutManager::OnDisplayWorkAreaInsetsChanged() { ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED); } +///////////////////////////////////////////////////////////////////////////// +// BaseLayoutManager, ash::wm::WindowStateObserver overrides: + +void BaseLayoutManager::OnWindowShowTypeChanged(wm::WindowState* window_state, + wm::WindowShowType old_type) { + ui::WindowShowState old_state = ToWindowShowState(old_type); + ui::WindowShowState new_state = window_state->GetShowState(); + + if (old_state != new_state && old_state != ui::SHOW_STATE_MINIMIZED && + !window_state->HasRestoreBounds() && + ((new_state == ui::SHOW_STATE_MAXIMIZED && + old_state != ui::SHOW_STATE_FULLSCREEN) || + (new_state == ui::SHOW_STATE_FULLSCREEN && + old_state != ui::SHOW_STATE_MAXIMIZED))) { + window_state->SetRestoreBoundsInParent(window_state->window()->bounds()); + } + + UpdateBoundsFromShowState(window_state); + ShowStateChanged(window_state, old_state); +} + ////////////////////////////////////////////////////////////////////////////// // BaseLayoutManager, protected: diff --git a/ash/wm/base_layout_manager.h b/ash/wm/base_layout_manager.h index f0deec6..7a94bf38 100644 --- a/ash/wm/base_layout_manager.h +++ b/ash/wm/base_layout_manager.h @@ -9,7 +9,7 @@ #include "ash/ash_export.h" #include "ash/shell_observer.h" -#include "ash/wm/window_state.h" +#include "ash/wm/window_state_observer.h" #include "base/basictypes.h" #include "base/compiler_specific.h" #include "ui/aura/client/activation_change_observer.h" @@ -40,7 +40,7 @@ class ASH_EXPORT BaseLayoutManager public aura::WindowObserver, public aura::client::ActivationChangeObserver, public ShellObserver, - public wm::WindowState::Observer { + public wm::WindowStateObserver { public: typedef std::set<aura::Window*> WindowSet; @@ -66,9 +66,6 @@ class ASH_EXPORT BaseLayoutManager const gfx::Rect& requested_bounds) OVERRIDE; // aura::WindowObserver overrides: - virtual void OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) OVERRIDE; virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; virtual void OnWindowBoundsChanged(aura::Window* window, const gfx::Rect& old_bounds, @@ -81,6 +78,10 @@ class ASH_EXPORT BaseLayoutManager // ash::ShellObserver overrides: virtual void OnDisplayWorkAreaInsetsChanged() OVERRIDE; + // wm::WindowStateObserver overrides: + virtual void OnWindowShowTypeChanged(wm::WindowState* window_state, + wm::WindowShowType type) OVERRIDE; + protected: enum AdjustWindowReason { ADJUST_WINDOW_DISPLAY_SIZE_CHANGED, diff --git a/ash/wm/caption_buttons/frame_maximize_button.cc b/ash/wm/caption_buttons/frame_maximize_button.cc index 9b35281..ca1dfa9 100644 --- a/ash/wm/caption_buttons/frame_maximize_button.cc +++ b/ash/wm/caption_buttons/frame_maximize_button.cc @@ -16,7 +16,6 @@ #include "ash/wm/workspace/phantom_window_controller.h" #include "ash/wm/workspace/snap_sizer.h" #include "grit/ash_strings.h" -#include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" @@ -441,10 +440,11 @@ void FrameMaximizeButton::UpdateSnap(const gfx::Point& location, SnapSizer::InputType input_type = is_touch ? SnapSizer::TOUCH_MAXIMIZE_BUTTON_INPUT : SnapSizer::OTHER_INPUT; - snap_sizer_.reset(new SnapSizer(frame_->GetNativeWindow(), - LocationForSnapSizer(location), - snap_edge, - input_type)); + snap_sizer_.reset(new SnapSizer( + wm::GetWindowState(frame_->GetNativeWindow()), + LocationForSnapSizer(location), + snap_edge, + input_type)); if (select_default) snap_sizer_->SelectDefaultSizeAndDisableResize(); } diff --git a/ash/wm/caption_buttons/frame_maximize_button_unittest.cc b/ash/wm/caption_buttons/frame_maximize_button_unittest.cc index ce1155b..94f57dd 100644 --- a/ash/wm/caption_buttons/frame_maximize_button_unittest.cc +++ b/ash/wm/caption_buttons/frame_maximize_button_unittest.cc @@ -13,7 +13,6 @@ #include "ash/wm/window_util.h" #include "ash/wm/workspace/snap_sizer.h" #include "base/command_line.h" -#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/focus_client.h" #include "ui/aura/root_window.h" #include "ui/aura/test/event_generator.h" @@ -226,7 +225,7 @@ TEST_F(FrameMaximizeButtonTest, MAYBE_ResizeButtonDrag) { EXPECT_FALSE(window_state->IsMaximized()); EXPECT_FALSE(window_state->IsMinimized()); - internal::SnapSizer sizer(window, center, + internal::SnapSizer sizer(window_state, center, internal::SnapSizer::RIGHT_EDGE, internal::SnapSizer::OTHER_INPUT); EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString()); @@ -243,7 +242,7 @@ TEST_F(FrameMaximizeButtonTest, MAYBE_ResizeButtonDrag) { EXPECT_FALSE(window_state->IsMaximized()); EXPECT_FALSE(window_state->IsMinimized()); - internal::SnapSizer sizer(window, center, + internal::SnapSizer sizer(window_state, center, internal::SnapSizer::LEFT_EDGE, internal::SnapSizer::OTHER_INPUT); EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString()); @@ -294,7 +293,7 @@ TEST_F(FrameMaximizeButtonTest, MAYBE_ResizeButtonDrag) { EXPECT_FALSE(window_state->IsMaximized()); EXPECT_FALSE(window_state->IsMinimized()); - internal::SnapSizer sizer(window, center, + internal::SnapSizer sizer(window_state, center, internal::SnapSizer::LEFT_EDGE, internal::SnapSizer::OTHER_INPUT); EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString()); @@ -474,6 +473,7 @@ TEST_F(FrameMaximizeButtonTest, MaximizeLeftButtonDragOut) { // maximize left button) will do the requested action. TEST_F(FrameMaximizeButtonTest, MaximizeLeftByButton) { aura::Window* window = widget()->GetNativeWindow(); + ash::FrameMaximizeButton* maximize_button = FrameMaximizeButtonTest::maximize_button(); maximize_button->set_bubble_appearance_delay_ms(0); @@ -502,7 +502,7 @@ TEST_F(FrameMaximizeButtonTest, MaximizeLeftByButton) { wm::WindowState* window_state = wm::GetWindowState(window); EXPECT_FALSE(window_state->IsMaximized()); EXPECT_FALSE(window_state->IsMinimized()); - internal::SnapSizer sizer(window, button_pos, + internal::SnapSizer sizer(window_state, button_pos, internal::SnapSizer::LEFT_EDGE, internal::SnapSizer::OTHER_INPUT); sizer.SelectDefaultSizeAndDisableResize(); @@ -713,7 +713,7 @@ TEST_F(FrameMaximizeButtonTest, MaximizeMaximizeLeftRestore) { } // Left/right maximize, maximize and then restore should work. -TEST_F(FrameMaximizeButtonTest, MaximizeLeftMaximizeRestore) { +TEST_F(FrameMaximizeButtonTest, MaximizeSnapLeftRestore) { aura::Window* window = widget()->GetNativeWindow(); gfx::Rect initial_bounds = widget()->GetWindowBoundsInScreen(); ash::FrameMaximizeButton* maximize_button = diff --git a/ash/wm/dock/docked_window_layout_manager.cc b/ash/wm/dock/docked_window_layout_manager.cc index 89445e8..27679ff 100644 --- a/ash/wm/dock/docked_window_layout_manager.cc +++ b/ash/wm/dock/docked_window_layout_manager.cc @@ -21,7 +21,6 @@ #include "base/command_line.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/aura/client/activation_client.h" -#include "ui/aura/client/aura_constants.h" #include "ui/aura/focus_manager.h" #include "ui/aura/root_window.h" #include "ui/aura/window.h" @@ -189,8 +188,11 @@ void DockedWindowLayoutManager::Shutdown() { } shelf_layout_manager_ = NULL; launcher_ = NULL; - for (size_t i = 0; i < dock_container_->children().size(); ++i) - dock_container_->children()[i]->RemoveObserver(this); + for (size_t i = 0; i < dock_container_->children().size(); ++i) { + aura::Window* child = dock_container_->children()[i]; + child->RemoveObserver(this); + wm::GetWindowState(child)->RemoveObserver(this); + } aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> RemoveObserver(this); Shell::GetInstance()->RemoveShellObserver(this); @@ -211,8 +213,10 @@ void DockedWindowLayoutManager::StartDragging(aura::Window* window) { dragged_window_ = window; // Start observing a window unless it is docked container's child in which // case it is already observed. - if (dragged_window_->parent() != dock_container_) + if (dragged_window_->parent() != dock_container_) { dragged_window_->AddObserver(this); + wm::GetWindowState(dragged_window_)->AddObserver(this); + } is_dragged_from_dock_ = window->parent() == dock_container_; DCHECK(!is_dragged_window_docked_); } @@ -238,6 +242,7 @@ void DockedWindowLayoutManager::FinishDragging() { // case it needs to keep being observed after the drag completes. if (dragged_window_->parent() != dock_container_) { dragged_window_->RemoveObserver(this); + wm::GetWindowState(dragged_window_)->RemoveObserver(this); if (last_active_window_ == dragged_window_) last_active_window_ = NULL; } else { @@ -359,6 +364,7 @@ void DockedWindowLayoutManager::OnWindowAddedToLayout(aura::Window* child) { } MaybeMinimizeChildrenExcept(child); child->AddObserver(this); + wm::GetWindowState(child)->AddObserver(this); Relayout(); UpdateDockBounds(); } @@ -379,6 +385,7 @@ void DockedWindowLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) { if (last_active_window_ == child) last_active_window_ = NULL; child->RemoveObserver(this); + wm::GetWindowState(child)->RemoveObserver(this); Relayout(); } @@ -388,7 +395,7 @@ void DockedWindowLayoutManager::OnChildWindowVisibilityChanged( if (child->type() == aura::client::WINDOW_TYPE_POPUP) return; if (visible) - child->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); + wm::GetWindowState(child)->Restore(); Relayout(); UpdateDockBounds(); } @@ -429,23 +436,24 @@ void DockedWindowLayoutManager::OnShelfAlignmentChanged( } ///////////////////////////////////////////////////////////////////////////// -// DockLayoutManager, WindowObserver implementation: +// DockLayoutManager, WindowStateObserver implementation: -void DockedWindowLayoutManager::OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) { - if (key != aura::client::kShowStateKey) - return; +void DockedWindowLayoutManager::OnWindowShowTypeChanged( + wm::WindowState* window_state, + wm::WindowShowType old_type) { // The window property will still be set, but no actual change will occur // until WillChangeVisibilityState is called when the shelf is visible again if (shelf_hidden_) return; - if (wm::GetWindowState(window)->IsMinimized()) - MinimizeDockedWindow(window); + if (window_state->IsMinimized()) + MinimizeDockedWindow(window_state); else - RestoreDockedWindow(window); + RestoreDockedWindow(window_state); } +///////////////////////////////////////////////////////////////////////////// +// DockLayoutManager, WindowObserver implementation: + void DockedWindowLayoutManager::OnWindowBoundsChanged( aura::Window* window, const gfx::Rect& old_bounds, @@ -517,12 +525,13 @@ void DockedWindowLayoutManager::WillChangeVisibilityState( aura::Window* window = dock_container_->children()[i]; if (window->type() == aura::client::WINDOW_TYPE_POPUP) continue; + wm::WindowState* window_state = wm::GetWindowState(window); if (shelf_hidden_) { if (window->IsVisible()) - MinimizeDockedWindow(window); + MinimizeDockedWindow(window_state); } else { - if (!wm::GetWindowState(window)->IsMinimized()) - RestoreDockedWindow(window); + if (!window_state->IsMinimized()) + RestoreDockedWindow(window_state); } } } @@ -548,15 +557,17 @@ void DockedWindowLayoutManager::MaybeMinimizeChildrenExcept( } } -void DockedWindowLayoutManager::MinimizeDockedWindow(aura::Window* window) { - DCHECK_NE(window->type(), aura::client::WINDOW_TYPE_POPUP); - window->Hide(); - wm::WindowState* window_state = wm::GetWindowState(window); +void DockedWindowLayoutManager::MinimizeDockedWindow( + wm::WindowState* window_state) { + DCHECK_NE(window_state->window()->type(), aura::client::WINDOW_TYPE_POPUP); + window_state->window()->Hide(); if (window_state->IsActive()) window_state->Deactivate(); } -void DockedWindowLayoutManager::RestoreDockedWindow(aura::Window* window) { +void DockedWindowLayoutManager::RestoreDockedWindow( + wm::WindowState* window_state) { + aura::Window* window = window_state->window(); DCHECK_NE(window->type(), aura::client::WINDOW_TYPE_POPUP); // Always place restored window at the top shuffling the other windows down. // TODO(varkha): add a separate container for docked windows to keep track diff --git a/ash/wm/dock/docked_window_layout_manager.h b/ash/wm/dock/docked_window_layout_manager.h index 124ffc1..109987b 100644 --- a/ash/wm/dock/docked_window_layout_manager.h +++ b/ash/wm/dock/docked_window_layout_manager.h @@ -9,6 +9,7 @@ #include "ash/shelf/shelf_layout_manager_observer.h" #include "ash/shell_observer.h" #include "ash/wm/dock/dock_types.h" +#include "ash/wm/window_state_observer.h" #include "ash/wm/workspace/snap_types.h" #include "base/basictypes.h" #include "base/compiler_specific.h" @@ -59,7 +60,8 @@ class ASH_EXPORT DockedWindowLayoutManager public aura::WindowObserver, public aura::client::ActivationChangeObserver, public keyboard::KeyboardControllerObserver, - public ash::ShelfLayoutManagerObserver { + public ash::ShelfLayoutManagerObserver, + public wm::WindowStateObserver { public: // Maximum width of the docked windows area. static const int kMaxDockWidth; @@ -125,10 +127,11 @@ class ASH_EXPORT DockedWindowLayoutManager // ash::ShellObserver: virtual void OnShelfAlignmentChanged(aura::RootWindow* root_window) OVERRIDE; + // wm::WindowStateObserver: + virtual void OnWindowShowTypeChanged(wm::WindowState* window_state, + wm::WindowShowType old_type) OVERRIDE; + // aura::WindowObserver: - virtual void OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) OVERRIDE; virtual void OnWindowBoundsChanged(aura::Window* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) OVERRIDE; @@ -179,8 +182,8 @@ class ASH_EXPORT DockedWindowLayoutManager void MaybeMinimizeChildrenExcept(aura::Window* child); // Minimize / restore window and relayout. - void MinimizeDockedWindow(aura::Window* window); - void RestoreDockedWindow(aura::Window* window); + void MinimizeDockedWindow(wm::WindowState* window_state); + void RestoreDockedWindow(wm::WindowState* window_state); // Updates docked layout state when a window gets inside the dock. void OnWindowDocked(aura::Window* window); diff --git a/ash/wm/frame_painter.cc b/ash/wm/frame_painter.cc index 0e53e33..f92bc0b 100644 --- a/ash/wm/frame_painter.cc +++ b/ash/wm/frame_painter.cc @@ -618,37 +618,32 @@ void FramePainter::OnThemeChanged() { } /////////////////////////////////////////////////////////////////////////////// -// WindowState::Observer overrides: -void FramePainter::OnTrackedByWorkspaceChanged(aura::Window* window, +// WindowStateObserver overrides: +void FramePainter::OnTrackedByWorkspaceChanged(wm::WindowState* window_state, bool old) { // When 'TrackedByWorkspace' changes, we are going to paint the header // differently. Schedule a paint to ensure everything is updated correctly. - if (wm::GetWindowState(window)->tracked_by_workspace()) + if (window_state->tracked_by_workspace()) frame_->non_client_view()->SchedulePaint(); } -/////////////////////////////////////////////////////////////////////////////// -// aura::WindowObserver overrides: - -void FramePainter::OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) { - if (key != aura::client::kShowStateKey) - return; - +void FramePainter::OnWindowShowTypeChanged(wm::WindowState* window_state, + wm::WindowShowType old_type) { // Maximized and fullscreen windows don't want resize handles overlapping the // content area, because when the user moves the cursor to the right screen // edge we want them to be able to hit the scroll bar. - wm::WindowState* window_state = wm::GetWindowState(window); if (window_state->IsMaximizedOrFullscreen()) { - window->set_hit_test_bounds_override_inner(gfx::Insets()); + window_state->window()->set_hit_test_bounds_override_inner(gfx::Insets()); } else { - window->set_hit_test_bounds_override_inner( + window_state->window()->set_hit_test_bounds_override_inner( gfx::Insets(kResizeInsideBoundsSize, kResizeInsideBoundsSize, kResizeInsideBoundsSize, kResizeInsideBoundsSize)); } } +/////////////////////////////////////////////////////////////////////////////// +// aura::WindowObserver overrides: + void FramePainter::OnWindowVisibilityChanged(aura::Window* window, bool visible) { // OnWindowVisibilityChanged can be called for the child windows of |window_|. diff --git a/ash/wm/frame_painter.h b/ash/wm/frame_painter.h index f1fddb1..37fb097 100644 --- a/ash/wm/frame_painter.h +++ b/ash/wm/frame_painter.h @@ -6,7 +6,7 @@ #define ASH_WM_FRAME_PAINTER_H_ #include "ash/ash_export.h" -#include "ash/wm/window_state.h" +#include "ash/wm/window_state_observer.h" #include "base/basictypes.h" #include "base/compiler_specific.h" // OVERRIDE #include "base/gtest_prod_util.h" @@ -41,7 +41,7 @@ class FrameCaptionButtonContainerView; // layout constants for Ash window frames. class ASH_EXPORT FramePainter : public aura::WindowObserver, public gfx::AnimationDelegate, - public wm::WindowState::Observer { + public wm::WindowStateObserver { public: // Opacity values for the window header in various states, from 0 to 255. static int kActiveWindowOpacity; @@ -133,9 +133,6 @@ class ASH_EXPORT FramePainter : public aura::WindowObserver, void OnThemeChanged(); // aura::WindowObserver overrides: - virtual void OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) OVERRIDE; virtual void OnWindowVisibilityChanged(aura::Window* window, bool visible) OVERRIDE; virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; @@ -145,9 +142,11 @@ class ASH_EXPORT FramePainter : public aura::WindowObserver, virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE; virtual void OnWindowRemovingFromRootWindow(aura::Window* window) OVERRIDE; - // ash::WindowSettings::Observer overrides: - virtual void OnTrackedByWorkspaceChanged(aura::Window* window, + // ash::WindowStateObserver overrides: + virtual void OnTrackedByWorkspaceChanged(wm::WindowState* window_state, bool old) OVERRIDE; + virtual void OnWindowShowTypeChanged(wm::WindowState* window_state, + wm::WindowShowType old_type) OVERRIDE; // Overridden from gfx::AnimationDelegate virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; diff --git a/ash/wm/gestures/system_pinch_handler.cc b/ash/wm/gestures/system_pinch_handler.cc index be776b5..2c06616 100644 --- a/ash/wm/gestures/system_pinch_handler.cc +++ b/ash/wm/gestures/system_pinch_handler.cc @@ -86,7 +86,7 @@ SystemGestureStatus SystemPinchHandler::ProcessGestureEvent( // Snap for left/right swipes. ui::ScopedLayerAnimationSettings settings( target_->layer()->GetAnimator()); - internal::SnapSizer::SnapWindow(target_, + internal::SnapSizer::SnapWindow(window_state, event.details().swipe_left() ? internal::SnapSizer::LEFT_EDGE : internal::SnapSizer::RIGHT_EDGE); } else if (event.details().swipe_up()) { diff --git a/ash/wm/gestures/two_finger_drag_handler.cc b/ash/wm/gestures/two_finger_drag_handler.cc index d5e28d8..f4d2e68 100644 --- a/ash/wm/gestures/two_finger_drag_handler.cc +++ b/ash/wm/gestures/two_finger_drag_handler.cc @@ -148,7 +148,7 @@ bool TwoFingerDragHandler::ProcessGestureEvent(aura::Window* target, target->layer()->GetAnimator()); scoped_setter.SetPreemptionStrategy( ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); - internal::SnapSizer::SnapWindow(target, + internal::SnapSizer::SnapWindow(window_state, event.details().swipe_left() ? internal::SnapSizer::LEFT_EDGE : internal::SnapSizer::RIGHT_EDGE); } diff --git a/ash/wm/panels/panel_layout_manager.cc b/ash/wm/panels/panel_layout_manager.cc index 579b346..a41b100 100644 --- a/ash/wm/panels/panel_layout_manager.cc +++ b/ash/wm/panels/panel_layout_manager.cc @@ -25,7 +25,6 @@ #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkPath.h" #include "ui/aura/client/activation_client.h" -#include "ui/aura/client/aura_constants.h" #include "ui/aura/focus_manager.h" #include "ui/aura/root_window.h" #include "ui/aura/window.h" @@ -321,12 +320,11 @@ void PanelLayoutManager::SetLauncher(ash::Launcher* launcher) { void PanelLayoutManager::ToggleMinimize(aura::Window* panel) { DCHECK(panel->parent() == panel_container_); - if (panel->GetProperty(aura::client::kShowStateKey) == - ui::SHOW_STATE_MINIMIZED) { - panel->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); - } else { - panel->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); - } + wm::WindowState* window_state = wm::GetWindowState(panel); + if (window_state->IsMinimized()) + window_state->Restore(); + else + window_state->Minimize(); } views::Widget* PanelLayoutManager::GetCalloutWidgetForPanel( @@ -374,6 +372,7 @@ void PanelLayoutManager::OnWindowAddedToLayout(aura::Window* child) { } panel_windows_.push_back(panel_info); child->AddObserver(this); + wm::GetWindowState(child)->AddObserver(this); Relayout(); } @@ -390,6 +389,7 @@ void PanelLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) { panel_windows_.erase(found); } child->RemoveObserver(this); + wm::GetWindowState(child)->RemoveObserver(this); if (dragged_panel_ == child) dragged_panel_ = NULL; @@ -461,27 +461,23 @@ void PanelLayoutManager::OnShelfAlignmentChanged( ///////////////////////////////////////////////////////////////////////////// // PanelLayoutManager, WindowObserver implementation: -void PanelLayoutManager::OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) { - if (key != aura::client::kShowStateKey) - return; +void PanelLayoutManager::OnWindowShowTypeChanged( + wm::WindowState* window_state, + wm::WindowShowType old_type) { // The window property will still be set, but no actual change will occur // until WillChangeVisibilityState is called when the shelf is visible again. if (shelf_hidden_) return; - ui::WindowShowState new_state = - window->GetProperty(aura::client::kShowStateKey); - if (new_state == ui::SHOW_STATE_MINIMIZED) - MinimizePanel(window); + if (window_state->IsMinimized()) + MinimizePanel(window_state->window()); else - RestorePanel(window); + RestorePanel(window_state->window()); } void PanelLayoutManager::OnWindowVisibilityChanged( aura::Window* window, bool visible) { if (visible) - window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); + wm::GetWindowState(window)->Restore(); } //////////////////////////////////////////////////////////////////////////////// @@ -520,10 +516,8 @@ void PanelLayoutManager::WillChangeVisibilityState( if (iter->window->IsVisible()) MinimizePanel(iter->window); } else { - if (iter->window->GetProperty(aura::client::kShowStateKey) != - ui::SHOW_STATE_MINIMIZED) { + if (!wm::GetWindowState(iter->window)->IsMinimized()) RestorePanel(iter->window); - } } } } diff --git a/ash/wm/panels/panel_layout_manager.h b/ash/wm/panels/panel_layout_manager.h index 9c35b00..27ec0cd 100644 --- a/ash/wm/panels/panel_layout_manager.h +++ b/ash/wm/panels/panel_layout_manager.h @@ -12,6 +12,7 @@ #include "ash/launcher/launcher_icon_observer.h" #include "ash/shelf/shelf_layout_manager_observer.h" #include "ash/shell_observer.h" +#include "ash/wm/window_state_observer.h" #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" @@ -58,7 +59,8 @@ class ASH_EXPORT PanelLayoutManager public aura::client::ActivationChangeObserver, public keyboard::KeyboardControllerObserver, public DisplayController::Observer, - public ShelfLayoutManagerObserver { + public ShelfLayoutManagerObserver, + public wm::WindowStateObserver { public: explicit PanelLayoutManager(aura::Window* panel_container); virtual ~PanelLayoutManager(); @@ -93,10 +95,11 @@ class ASH_EXPORT PanelLayoutManager // Overridden from ash::ShellObserver virtual void OnShelfAlignmentChanged(aura::RootWindow* root_window) OVERRIDE; + // Overridden from ash::wm::WindowStateObserver + virtual void OnWindowShowTypeChanged(wm::WindowState* window_state, + wm::WindowShowType old_type) OVERRIDE; + // Overridden from aura::WindowObserver - virtual void OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) OVERRIDE; virtual void OnWindowVisibilityChanged(aura::Window* window, bool visible) OVERRIDE; diff --git a/ash/wm/panels/panel_window_event_handler.cc b/ash/wm/panels/panel_window_event_handler.cc index b15d8b6..cb49469 100644 --- a/ash/wm/panels/panel_window_event_handler.cc +++ b/ash/wm/panels/panel_window_event_handler.cc @@ -4,7 +4,7 @@ #include "ash/wm/panels/panel_window_event_handler.h" -#include "ui/aura/client/aura_constants.h" +#include "ash/wm/window_state.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" #include "ui/base/hit_test.h" @@ -27,7 +27,7 @@ void PanelWindowEventHandler::OnMouseEvent(ui::MouseEvent* event) { event->IsOnlyLeftMouseButton() && target->delegate()->GetNonClientComponent(event->location()) == HTCAPTION) { - target->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); + wm::GetWindowState(target)->Minimize(); return; } ToplevelWindowEventHandler::OnMouseEvent(event); @@ -39,7 +39,7 @@ void PanelWindowEventHandler::OnGestureEvent(ui::GestureEvent* event) { event->details().tap_count() == 2 && target->delegate()->GetNonClientComponent(event->location()) == HTCAPTION) { - target->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); + wm::GetWindowState(target)->Minimize(); event->StopPropagation(); return; } diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc index 46cf9c5d..f76d33d 100644 --- a/ash/wm/toplevel_window_event_handler.cc +++ b/ash/wm/toplevel_window_event_handler.cc @@ -8,11 +8,11 @@ #include "ash/wm/resize_shadow_controller.h" #include "ash/wm/window_resizer.h" #include "ash/wm/window_state.h" +#include "ash/wm/window_state_observer.h" #include "ash/wm/window_util.h" #include "ash/wm/workspace/snap_sizer.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/cursor_client.h" #include "ui/aura/env.h" #include "ui/aura/root_window.h" @@ -53,7 +53,8 @@ gfx::Point ConvertPointToParent(aura::Window* window, // the window is destroyed ResizerWindowDestroyed() is invoked back on the // ToplevelWindowEventHandler to clean up. class ToplevelWindowEventHandler::ScopedWindowResizer - : public aura::WindowObserver { + : public aura::WindowObserver, + public wm::WindowStateObserver { public: ScopedWindowResizer(ToplevelWindowEventHandler* handler, WindowResizer* resizer); @@ -64,11 +65,12 @@ class ToplevelWindowEventHandler::ScopedWindowResizer // WindowObserver overrides: virtual void OnWindowHierarchyChanging( const HierarchyChangeParams& params) OVERRIDE; - virtual void OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) OVERRIDE; virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; + // WindowStateObserver overrides: + virtual void OnWindowShowTypeChanged(wm::WindowState* window_state, + wm::WindowShowType type) OVERRIDE; + private: void AddHandlers(aura::Window* container); void RemoveHandlers(); @@ -89,14 +91,18 @@ ToplevelWindowEventHandler::ScopedWindowResizer::ScopedWindowResizer( : handler_(handler), resizer_(resizer), target_container_(NULL) { - if (resizer_) + if (resizer_) { resizer_->GetTarget()->AddObserver(this); + wm::GetWindowState(resizer_->GetTarget())->AddObserver(this); + } } ToplevelWindowEventHandler::ScopedWindowResizer::~ScopedWindowResizer() { RemoveHandlers(); - if (resizer_) + if (resizer_) { resizer_->GetTarget()->RemoveObserver(this); + wm::GetWindowState(resizer_->GetTarget())->RemoveObserver(this); + } } void ToplevelWindowEventHandler::ScopedWindowResizer::OnWindowHierarchyChanging( @@ -112,12 +118,10 @@ void ToplevelWindowEventHandler::ScopedWindowResizer::OnWindowHierarchyChanging( } } -void ToplevelWindowEventHandler::ScopedWindowResizer::OnWindowPropertyChanged( - aura::Window* window, - const void* key, - intptr_t old) { - if (key == aura::client::kShowStateKey && - !wm::GetWindowState(window)->IsNormalShowState()) +void ToplevelWindowEventHandler::ScopedWindowResizer::OnWindowShowTypeChanged( + wm::WindowState* window_state, + wm::WindowShowType old) { + if (!window_state->IsNormalShowState()) handler_->CompleteDrag(DRAG_COMPLETE, 0); } @@ -311,7 +315,7 @@ void ToplevelWindowEventHandler::OnGestureEvent(ui::GestureEvent* event) { target->layer()->GetAnimator()); scoped_setter.SetPreemptionStrategy( ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); - internal::SnapSizer::SnapWindow(target, + internal::SnapSizer::SnapWindow(window_state, event->details().velocity_x() < 0 ? internal::SnapSizer::LEFT_EDGE : internal::SnapSizer::RIGHT_EDGE); } diff --git a/ash/wm/toplevel_window_event_handler_unittest.cc b/ash/wm/toplevel_window_event_handler_unittest.cc index b51a330..5f37213 100644 --- a/ash/wm/toplevel_window_event_handler_unittest.cc +++ b/ash/wm/toplevel_window_event_handler_unittest.cc @@ -379,6 +379,7 @@ TEST_F(ToplevelWindowEventHandlerTest, GestureDrag) { new TestWindowDelegate(HTCAPTION), 0, gfx::Rect(0, 0, 100, 100))); + wm::WindowState* window_state = wm::GetWindowState(target.get()); aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), target.get()); gfx::Rect old_bounds = target->bounds(); @@ -390,7 +391,7 @@ TEST_F(ToplevelWindowEventHandlerTest, GestureDrag) { // Snap right; { // Get the expected snapped bounds before snapping. - internal::SnapSizer sizer(target.get(), location, + internal::SnapSizer sizer(window_state, location, internal::SnapSizer::RIGHT_EDGE, internal::SnapSizer::OTHER_INPUT); gfx::Rect snapped_bounds = sizer.GetSnapBounds(target->bounds()); @@ -411,7 +412,7 @@ TEST_F(ToplevelWindowEventHandlerTest, GestureDrag) { // Snap left. { // Get the expected snapped bounds before snapping. - internal::SnapSizer sizer(target.get(), location, + internal::SnapSizer sizer(window_state, location, internal::SnapSizer::LEFT_EDGE, internal::SnapSizer::OTHER_INPUT); gfx::Rect snapped_bounds = sizer.GetSnapBounds(target->bounds()); @@ -439,7 +440,6 @@ TEST_F(ToplevelWindowEventHandlerTest, GestureDrag) { 10); RunAllPendingInMessageLoop(); - wm::WindowState* window_state = wm::GetWindowState(target.get()); EXPECT_NE(old_bounds.ToString(), target->bounds().ToString()); EXPECT_TRUE(window_state->IsMaximized()); EXPECT_EQ(old_bounds.ToString(), @@ -520,6 +520,7 @@ TEST_F(ToplevelWindowEventHandlerTest, GestureDragToRestore) { // Tests that an unresizable window cannot be dragged or snapped using gestures. TEST_F(ToplevelWindowEventHandlerTest, GestureDragForUnresizableWindow) { scoped_ptr<aura::Window> target(CreateWindow(HTCAPTION)); + wm::WindowState* window_state = wm::GetWindowState(target.get()); aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), target.get()); @@ -533,7 +534,7 @@ TEST_F(ToplevelWindowEventHandlerTest, GestureDragForUnresizableWindow) { // Try to snap right. The window is not resizable. So it should not snap. { // Get the expected snapped bounds before the gesture. - internal::SnapSizer sizer(target.get(), location, + internal::SnapSizer sizer(window_state, location, internal::SnapSizer::RIGHT_EDGE, internal::SnapSizer::OTHER_INPUT); gfx::Rect snapped_bounds = sizer.GetSnapBounds(target->bounds()); @@ -558,7 +559,7 @@ TEST_F(ToplevelWindowEventHandlerTest, GestureDragForUnresizableWindow) { // Try to snap left. It should not snap. { // Get the expected snapped bounds before the gesture. - internal::SnapSizer sizer(target.get(), location, + internal::SnapSizer sizer(window_state, location, internal::SnapSizer::LEFT_EDGE, internal::SnapSizer::OTHER_INPUT); gfx::Rect snapped_bounds = sizer.GetSnapBounds(target->bounds()); diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index bbb3fc7..775a3f7 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc @@ -8,7 +8,9 @@ #include "ash/screen_ash.h" #include "ash/shell_window_ids.h" #include "ash/wm/window_properties.h" +#include "ash/wm/window_state_observer.h" #include "ash/wm/window_util.h" +#include "ash/wm/wm_types.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" @@ -32,7 +34,9 @@ WindowState::WindowState(aura::Window* window) panel_attached_(true), continue_drag_after_reparent_(false), ignored_by_shelf_(false), - always_restores_to_restore_bounds_(false) { + always_restores_to_restore_bounds_(false), + window_show_type_(ToWindowShowType(GetShowState())) { + window_->AddObserver(this); } WindowState::~WindowState() { @@ -110,6 +114,14 @@ void WindowState::Maximize() { window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); } +void WindowState::SnapLeft(const gfx::Rect& bounds) { + SnapWindow(SHOW_TYPE_LEFT_SNAPPED, bounds); +} + +void WindowState::SnapRight(const gfx::Rect& bounds) { + SnapWindow(SHOW_TYPE_LEFT_SNAPPED, bounds); +} + void WindowState::Minimize() { window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); } @@ -182,11 +194,11 @@ void WindowState::SetPreAutoManageWindowBounds( pre_auto_manage_window_bounds_.reset(new gfx::Rect(bounds)); } -void WindowState::AddObserver(Observer* observer) { +void WindowState::AddObserver(WindowStateObserver* observer) { observer_list_.AddObserver(observer); } -void WindowState::RemoveObserver(Observer* observer) { +void WindowState::RemoveObserver(WindowStateObserver* observer) { observer_list_.RemoveObserver(observer); } @@ -195,8 +207,49 @@ void WindowState::SetTrackedByWorkspace(bool tracked_by_workspace) { return; bool old = tracked_by_workspace_; tracked_by_workspace_ = tracked_by_workspace; - FOR_EACH_OBSERVER(Observer, observer_list_, - OnTrackedByWorkspaceChanged(window_, old)); + FOR_EACH_OBSERVER(WindowStateObserver, observer_list_, + OnTrackedByWorkspaceChanged(this, old)); +} + +void WindowState::OnWindowPropertyChanged(aura::Window* window, + const void* key, + intptr_t old) { + DCHECK_EQ(window, window_); + if (key == aura::client::kShowStateKey) { + window_show_type_ = ToWindowShowType(GetShowState()); + ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old); + // TODO(oshima): Notify only when the state has changed. + // Doing so break a few tests now. + FOR_EACH_OBSERVER( + WindowStateObserver, observer_list_, + OnWindowShowTypeChanged(this, ToWindowShowType(old_state))); + } +} + +void WindowState::OnWindowDestroying(aura::Window* window) { + window_->RemoveObserver(this); +} + +void WindowState::SnapWindow(WindowShowType left_or_right, + const gfx::Rect& bounds) { + if (IsMaximizedOrFullscreen()) { + // Before we can set the bounds we need to restore the window. + // Restoring the window will set the window to its restored bounds. + // To avoid an unnecessary bounds changes (which may have side effects) + // we set the restore bounds to the bounds we want, restore the window, + // then reset the restore bounds. This way no unnecessary bounds + // changes occurs and the original restore bounds is remembered. + gfx::Rect restore_bounds_in_screen = + GetRestoreBoundsInScreen(); + SetRestoreBoundsInParent(bounds); + Restore(); + SetRestoreBoundsInScreen(restore_bounds_in_screen); + } else { + window_->SetBounds(bounds); + } + DCHECK(left_or_right == SHOW_TYPE_LEFT_SNAPPED || + left_or_right == SHOW_TYPE_RIGHT_SNAPPED); + window_show_type_ = left_or_right; } WindowState* GetActiveWindowState() { diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h index 6145de0..2cdccc6 100644 --- a/ash/wm/window_state.h +++ b/ash/wm/window_state.h @@ -6,9 +6,11 @@ #define ASH_WM_WINDOW_STATE_H_ #include "ash/ash_export.h" +#include "ash/wm/wm_types.h" #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "base/observer_list.h" +#include "ui/aura/window_observer.h" #include "ui/base/ui_base_types.h" namespace aura { @@ -21,6 +23,7 @@ class Rect; namespace ash { namespace wm { +class WindowStateObserver; // WindowState manages and defines ash specific window state and // behavior. Ash specific per-window state (such as ones that controls @@ -33,26 +36,24 @@ namespace wm { // Prefer using this class instead of passing aura::Window* around in // ash code as this is often what you need to interact with, and // accessing the window using |window()| is cheap. -class ASH_EXPORT WindowState { +class ASH_EXPORT WindowState : public aura::WindowObserver { public: - class ASH_EXPORT Observer { - public: - // Called when the tracked_by_workspace has changed. - virtual void OnTrackedByWorkspaceChanged(aura::Window* window, - bool old_value) {} - }; - static bool IsMaximizedOrFullscreenState(ui::WindowShowState state); explicit WindowState(aura::Window* window); - ~WindowState(); + virtual ~WindowState(); aura::Window* window() { return window_; } const aura::Window* window() const { return window_; } - // Returns the window's current shows tate. + // Returns the window's current show state. ui::WindowShowState GetShowState() const; + // Returns the window's current ash show type. + // Refer to WindowShowType definition in wm_types.h as for why Ash + // has its own show type. + WindowShowType window_show_type() const { return window_show_type_; } + // Predicates to check window state. bool IsMinimized() const; bool IsMaximized() const; @@ -80,6 +81,8 @@ class ASH_EXPORT WindowState { void Deactivate(); void Restore(); void ToggleMaximized(); + void SnapLeft(const gfx::Rect& bounds); + void SnapRight(const gfx::Rect& bounds); // Sets the window's bounds in screen coordinates. void SetBoundsInScreen(const gfx::Rect& bounds_in_screen); @@ -128,8 +131,8 @@ class ASH_EXPORT WindowState { // Layout related properties - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); + void AddObserver(WindowStateObserver* observer); + void RemoveObserver(WindowStateObserver* observer); // Whether the window is tracked by workspace code. Default is // true. If set to false the workspace does not switch the current @@ -175,7 +178,17 @@ class ASH_EXPORT WindowState { ignored_by_shelf_ = ignored_by_shelf; } + // aura::WindowObserver overrides: + virtual void OnWindowPropertyChanged(aura::Window* window, + const void* key, + intptr_t old) OVERRIDE; + virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; + private: + // Snaps the window to left or right of the desktop with given bounds. + void SnapWindow(WindowShowType left_or_right, + const gfx::Rect& bounds); + // The owner of this window settings. aura::Window* window_; @@ -193,7 +206,9 @@ class ASH_EXPORT WindowState { // restored when only this one window gets shown. scoped_ptr<gfx::Rect> pre_auto_manage_window_bounds_; - ObserverList<Observer> observer_list_; + ObserverList<WindowStateObserver> observer_list_; + + WindowShowType window_show_type_; DISALLOW_COPY_AND_ASSIGN(WindowState); }; diff --git a/ash/wm/window_state_observer.h b/ash/wm/window_state_observer.h new file mode 100644 index 0000000..c8bb553 --- /dev/null +++ b/ash/wm/window_state_observer.h @@ -0,0 +1,32 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_WM_WINDOW_STATE_OBSERVER_H_ +#define ASH_WM_WINDOW_STATE_OBSERVER_H_ + +#include "ash/wm/wm_types.h" + +namespace ash { +namespace wm { +class WindowState; + +class ASH_EXPORT WindowStateObserver { + public: + // Called when the tracked_by_workspace has changed. + virtual void OnTrackedByWorkspaceChanged( + WindowState* window, + bool old_value) {} + + // Called when the window's show type has changed. + // This is different from kWindowShowStatekey property change + // as this will be invoked when the window gets left/right maximized, + // and auto positioned. + virtual void OnWindowShowTypeChanged(WindowState* window_state, + WindowShowType type) {} +}; + +} // namespace wm +} // namespace ash + +#endif // ASH_WM_WINDOW_STATE_OBSERVER_H_ diff --git a/ash/wm/wm_types.cc b/ash/wm/wm_types.cc new file mode 100644 index 0000000..c7f45ce --- /dev/null +++ b/ash/wm/wm_types.cc @@ -0,0 +1,49 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/wm/wm_types.h" + +#include "base/basictypes.h" +#include "base/logging.h" + +namespace ash { +namespace wm { + +// This is to catch the change to WindowShowState. +COMPILE_ASSERT( + ui::SHOW_STATE_END == static_cast<ui::WindowShowState>(SHOW_TYPE_END), + show_enum_mismatch); + +WindowShowType ToWindowShowType(ui::WindowShowState state) { + return static_cast<WindowShowType>(state); +} + +ui::WindowShowState ToWindowShowState(WindowShowType type) { + switch (type) { + case SHOW_TYPE_DEFAULT: + return ui::SHOW_STATE_DEFAULT; + case SHOW_TYPE_NORMAL: + case SHOW_TYPE_RIGHT_SNAPPED: + case SHOW_TYPE_LEFT_SNAPPED: + case SHOW_TYPE_AUTO_POSITIONED: + return ui::SHOW_STATE_NORMAL; + case SHOW_TYPE_MINIMIZED: + return ui::SHOW_STATE_MINIMIZED; + case SHOW_TYPE_MAXIMIZED: + return ui::SHOW_STATE_MAXIMIZED; + case SHOW_TYPE_INACTIVE: + return ui::SHOW_STATE_INACTIVE; + case SHOW_TYPE_FULLSCREEN: + return ui::SHOW_STATE_FULLSCREEN; + case SHOW_TYPE_DETACHED: + return ui::SHOW_STATE_DETACHED; + case SHOW_TYPE_END: + NOTREACHED(); + } + NOTREACHED(); + return ui::SHOW_STATE_DEFAULT; +} + +} // namespace wm +} // namespace ash diff --git a/ash/wm/wm_types.h b/ash/wm/wm_types.h new file mode 100644 index 0000000..da3db00 --- /dev/null +++ b/ash/wm/wm_types.h @@ -0,0 +1,52 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_WM_WM_TYPES_H_ +#define ASH_WM_WM_TYPES_H_ + +#include "ui/base/ui_base_types.h" + +namespace ash { +namespace wm { + +// This enum defines both common show state copied from +// ui::WindowShowState as well as new states intoruduced in ash. +// The separate enum is defined here because we don't want to leak +// these type to ui/base until they're stable and we know for sure +// that they'll persist over time. +enum WindowShowType { + // Common state + SHOW_TYPE_DEFAULT = 0, + + // Normal represents a state where the position/size has been + // specified by a use. + SHOW_TYPE_NORMAL, + SHOW_TYPE_MINIMIZED, + SHOW_TYPE_MAXIMIZED, + SHOW_TYPE_INACTIVE, + SHOW_TYPE_FULLSCREEN, + SHOW_TYPE_DETACHED, + SHOW_TYPE_END, // to avoid using SHOW_STATE_END + + // Ash specific states: + + SHOW_TYPE_LEFT_SNAPPED, + SHOW_TYPE_RIGHT_SNAPPED, + + // A window is in this state when it is automatically placed and + // sized by the window manager. (it's newly opened, or pushed to the side + // due to new window, for example). + SHOW_TYPE_AUTO_POSITIONED, +}; + +// Utility functions to convert WindowShowType <-> ui::WindowShowState. +// Note: LEFT/RIGHT MAXIMIZED, AUTO_POSITIONED type will be lost when +// converting to ui::WindowShowState. +WindowShowType ToWindowShowType(ui::WindowShowState state); +ui::WindowShowState ToWindowShowState(WindowShowType type); + +} // namespace +} // namespace + +#endif // ASH_WM_WM_TYPES_H_ diff --git a/ash/wm/workspace/snap_sizer.cc b/ash/wm/workspace/snap_sizer.cc index 8f2ed39..f101441 100644 --- a/ash/wm/workspace/snap_sizer.cc +++ b/ash/wm/workspace/snap_sizer.cc @@ -126,31 +126,22 @@ std::vector<int> BuildIdealWidthList(aura::Window* window) { // Changes |window|'s bounds to |snap_bounds| while preserving the restore // bounds. void SnapWindowToBounds(wm::WindowState* window_state, + SnapSizer::Edge edge, const gfx::Rect& snap_bounds) { - if (window_state->IsMaximizedOrFullscreen()) { - // Before we can set the bounds we need to restore the window. - // Restoring the window will set the window to its restored bounds. - // To avoid an unnecessary bounds changes (which may have side effects) - // we set the restore bounds to the bounds we want, restore the window, - // then reset the restore bounds. This way no unnecessary bounds - // changes occurs and the original restore bounds is remembered. - gfx::Rect restore_bounds_in_screen = - window_state->GetRestoreBoundsInScreen(); - window_state->SetRestoreBoundsInParent(snap_bounds); - window_state->Restore(); - window_state->SetRestoreBoundsInScreen(restore_bounds_in_screen); + if (edge == SnapSizer::LEFT_EDGE) { + window_state->SnapLeft(snap_bounds); } else { - window_state->window()->SetBounds(snap_bounds); + window_state->SnapRight(snap_bounds); } } } // namespace -SnapSizer::SnapSizer(aura::Window* window, +SnapSizer::SnapSizer(wm::WindowState* window_state, const gfx::Point& start, Edge edge, InputType input_type) - : window_(window), + : window_state_(window_state), edge_(edge), time_last_update_(base::TimeTicks::Now()), size_index_(0), @@ -161,7 +152,7 @@ SnapSizer::SnapSizer(aura::Window* window, last_update_x_(start.x()), start_x_(start.x()), input_type_(input_type), - usable_width_(BuildIdealWidthList(window)) { + usable_width_(BuildIdealWidthList(window_state->window())) { DCHECK(!usable_width_.empty()); target_bounds_ = GetTargetBounds(); } @@ -169,18 +160,18 @@ SnapSizer::SnapSizer(aura::Window* window, SnapSizer::~SnapSizer() { } -void SnapSizer::SnapWindow(aura::Window* window, SnapSizer::Edge edge) { - wm::WindowState* window_state = wm::GetWindowState(window); +void SnapSizer::SnapWindow(wm::WindowState* window_state, + SnapSizer::Edge edge) { if (!window_state->CanSnap()) return; - internal::SnapSizer sizer(window, gfx::Point(), edge, + internal::SnapSizer sizer(window_state, gfx::Point(), edge, internal::SnapSizer::OTHER_INPUT); - SnapWindowToBounds(window_state, + SnapWindowToBounds(window_state, edge, sizer.GetSnapBounds(window_state->window()->bounds())); } void SnapSizer::SnapWindowToTargetBounds() { - SnapWindowToBounds(wm::GetWindowState(window_), target_bounds()); + SnapWindowToBounds(window_state_, edge_, target_bounds()); } void SnapSizer::Update(const gfx::Point& location) { @@ -194,7 +185,8 @@ void SnapSizer::Update(const gfx::Point& location) { bool along_edge = AlongEdge(location.x()); int pixels_before_adjust = kPixelsBeforeAdjust; if (input_type_ == TOUCH_MAXIMIZE_BUTTON_INPUT) { - const gfx::Rect& workspace_bounds = window_->parent()->bounds(); + const gfx::Rect& workspace_bounds = + window_state_->window()->parent()->bounds(); if (start_x_ > location.x()) { pixels_before_adjust = std::min(pixels_before_adjust, start_x_ / 10); @@ -238,12 +230,13 @@ void SnapSizer::SelectDefaultSizeAndDisableResize() { } gfx::Rect SnapSizer::GetTargetBoundsForSize(size_t size_index) const { - gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_)); + gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent( + window_state_->window())); int y = work_area.y(); int max_y = work_area.bottom(); int width = 0; if (resize_disabled_) { - width = GetDefaultWidth(window_); + width = GetDefaultWidth(window_state_->window()); } else { DCHECK(size_index < usable_width_.size()); width = usable_width_[size_index]; @@ -293,7 +286,8 @@ gfx::Rect SnapSizer::GetTargetBounds() const { } bool SnapSizer::AlongEdge(int x) const { - gfx::Rect area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_)); + gfx::Rect area(ScreenAsh::GetDisplayWorkAreaBoundsInParent( + window_state_->window())); return (x <= area.x()) || (x >= area.right() - 1); } diff --git a/ash/wm/workspace/snap_sizer.h b/ash/wm/workspace/snap_sizer.h index b241ef8..b32c3c8 100644 --- a/ash/wm/workspace/snap_sizer.h +++ b/ash/wm/workspace/snap_sizer.h @@ -12,11 +12,11 @@ #include "base/time/time.h" #include "ui/gfx/rect.h" -namespace aura { -class Window; +namespace ash { +namespace wm { +class WindowState; } -namespace ash { namespace internal { // SnapSizer is responsible for determining the resulting bounds of a window @@ -37,14 +37,14 @@ class ASH_EXPORT SnapSizer { // Set |input_type| to |TOUCH_MAXIMIZE_BUTTON_INPUT| when called by a touch // operation by the maximize button. This will allow the user to snap resize // the window beginning close to the border. - SnapSizer(aura::Window* window, + SnapSizer(wm::WindowState* window_state, const gfx::Point& start, Edge edge, InputType input_type); virtual ~SnapSizer(); // Snaps a window left or right. - static void SnapWindow(aura::Window* window, Edge edge); + static void SnapWindow(wm::WindowState* window_state, Edge edge); // Snaps |window_| to the target bounds. void SnapWindowToTargetBounds(); @@ -87,8 +87,8 @@ class ASH_EXPORT SnapSizer { // Returns true if the specified point is along the edge of the screen. bool AlongEdge(int x) const; - // Window being snapped. - aura::Window* window_; + // WindowState of the window being snapped. + wm::WindowState* window_state_; const Edge edge_; diff --git a/ash/wm/workspace/snap_sizer_unittest.cc b/ash/wm/workspace/snap_sizer_unittest.cc index e0c9033..236a16e 100644 --- a/ash/wm/workspace/snap_sizer_unittest.cc +++ b/ash/wm/workspace/snap_sizer_unittest.cc @@ -36,8 +36,8 @@ TEST_F(SnapSizerTest, MultipleDisplays) { scoped_ptr<aura::Window> window( CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); - - SnapSizer::SnapWindow(window.get(), SnapSizer::LEFT_EDGE); + wm::WindowState* window_state = wm::GetWindowState(window.get()); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); gfx::Rect expected = gfx::Rect( kPrimaryDisplayWorkAreaBounds.x(), kPrimaryDisplayWorkAreaBounds.y(), @@ -45,7 +45,7 @@ TEST_F(SnapSizerTest, MultipleDisplays) { kPrimaryDisplayWorkAreaBounds.height()); EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); - SnapSizer::SnapWindow(window.get(), SnapSizer::RIGHT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); // The width should not change when a window switches from being snapped to // the left edge to being snapped to the right edge. expected.set_x(kPrimaryDisplayWorkAreaBounds.right() - expected.width()); @@ -55,7 +55,7 @@ TEST_F(SnapSizerTest, MultipleDisplays) { window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100), ScreenAsh::GetSecondaryDisplay()); - SnapSizer::SnapWindow(window.get(), SnapSizer::RIGHT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); expected = gfx::Rect( kSecondaryDisplayWorkAreaBounds.right() - window->bounds().width(), kSecondaryDisplayWorkAreaBounds.y(), @@ -63,7 +63,7 @@ TEST_F(SnapSizerTest, MultipleDisplays) { kSecondaryDisplayWorkAreaBounds.height()); EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); - SnapSizer::SnapWindow(window.get(), SnapSizer::LEFT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); // The width should not change when a window switches from being snapped to // the right edge to being snapped to the left edge. expected.set_x(kSecondaryDisplayWorkAreaBounds.x()); @@ -88,7 +88,7 @@ TEST_F(SnapSizerTest, MinimumSize) { delegate.set_minimum_size(gfx::Size(kWorkAreaBounds.width() - 1, 0)); wm::WindowState* window_state = wm::GetWindowState(window.get()); EXPECT_TRUE(window_state->CanSnap()); - SnapSizer::SnapWindow(window.get(), SnapSizer::RIGHT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x() + 1, kWorkAreaBounds.y(), kWorkAreaBounds.width() - 1, @@ -113,33 +113,34 @@ TEST_F(SnapSizerTest, StepThroughSizes) { scoped_ptr<aura::Window> window( CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); + wm::WindowState* window_state = wm::GetWindowState(window.get()); // Make sure that the work area is the size we expect it to be. EXPECT_GT(kWorkAreaBounds.width() * 0.9, 768); // The first width should be 1024 * 0.9 because the larger ideal widths // (1280, 1024) > 1024 * 0.9. - SnapSizer::SnapWindow(window.get(), SnapSizer::LEFT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(), kWorkAreaBounds.y(), kWorkAreaBounds.width() * 0.9, kWorkAreaBounds.height()); EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); - SnapSizer::SnapWindow(window.get(), SnapSizer::LEFT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); expected.set_width(768); EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); - SnapSizer::SnapWindow(window.get(), SnapSizer::LEFT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); expected.set_width(640); EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); - SnapSizer::SnapWindow(window.get(), SnapSizer::LEFT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); expected.set_width(kWorkAreaBounds.width() * 0.5); EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); // Wrap around. - SnapSizer::SnapWindow(window.get(), SnapSizer::LEFT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); expected.set_width(kWorkAreaBounds.width() * 0.9); EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); } @@ -151,8 +152,8 @@ TEST_F(SnapSizerTest, Default) { scoped_ptr<aura::Window> window( CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); - SnapSizer sizer(window.get(), gfx::Point(), SnapSizer::LEFT_EDGE, - SnapSizer::OTHER_INPUT); + SnapSizer sizer(wm::GetWindowState(window.get()), gfx::Point(), + SnapSizer::LEFT_EDGE, SnapSizer::OTHER_INPUT); // For small workspace widths, we should snap to 90% of the workspace width // because it is the largest width the window can snap to. @@ -199,8 +200,8 @@ TEST_F(SnapSizerTest, AlternateFrameCaptionButtonStyle) { scoped_ptr<aura::Window> window( CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); - - SnapSizer::SnapWindow(window.get(), SnapSizer::LEFT_EDGE); + wm::WindowState* window_state = wm::GetWindowState(window.get()); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(), kWorkAreaBounds.y(), kWorkAreaBounds.width() / 2, @@ -210,17 +211,17 @@ TEST_F(SnapSizerTest, AlternateFrameCaptionButtonStyle) { // Because a window can only be snapped to one size when using the alternate // caption button style, a second call to SnapSizer::SnapWindow() should have // no effect. - SnapSizer::SnapWindow(window.get(), SnapSizer::LEFT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); // It should still be possible to switch a window from being snapped to the // left edge to being snapped to the right edge. - SnapSizer::SnapWindow(window.get(), SnapSizer::RIGHT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); expected.set_x(kWorkAreaBounds.right() - expected.width()); EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); // If resizing is disabled, the window should be snapped to 50% too. - SnapSizer sizer(window.get(), gfx::Point(), SnapSizer::RIGHT_EDGE, + SnapSizer sizer(window_state, gfx::Point(), SnapSizer::RIGHT_EDGE, SnapSizer::OTHER_INPUT); sizer.SelectDefaultSizeAndDisableResize(); sizer.SnapWindowToTargetBounds(); @@ -239,8 +240,8 @@ TEST_F(SnapSizerTest, RestoreBounds) { gfx::Rect restore_bounds = window->GetBoundsInScreen(); restore_bounds.set_width(restore_bounds.width() + 1); window_state->SetRestoreBoundsInScreen(restore_bounds); - SnapSizer::SnapWindow(window.get(), SnapSizer::LEFT_EDGE); - SnapSizer::SnapWindow(window.get(), SnapSizer::RIGHT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); EXPECT_EQ(restore_bounds.ToString(), window_state->GetRestoreBoundsInScreen().ToString()); @@ -254,7 +255,7 @@ TEST_F(SnapSizerTest, RestoreBounds) { EXPECT_EQ(restore_bounds.ToString(), window_state->GetRestoreBoundsInScreen().ToString()); - SnapSizer::SnapWindow(window.get(), SnapSizer::LEFT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); EXPECT_NE(maximized_bounds.ToString(), window->GetBoundsInScreen().ToString()); @@ -276,7 +277,7 @@ TEST_F(SnapSizerTest, AutoManaged) { window->Show(); window_state->Maximize(); - SnapSizer::SnapWindow(window.get(), SnapSizer::RIGHT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); const gfx::Rect kWorkAreaBounds = ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); @@ -289,7 +290,7 @@ TEST_F(SnapSizerTest, AutoManaged) { window->GetBoundsInScreen().ToString()); // The window should still be auto managed despite being right maximized. - EXPECT_TRUE(wm::GetWindowState(window.get())->window_position_managed()); + EXPECT_TRUE(window_state->window_position_managed()); } } // namespace ash diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc index c4d72c0..a0c3a58 100644 --- a/ash/wm/workspace/workspace_layout_manager.cc +++ b/ash/wm/workspace/workspace_layout_manager.cc @@ -140,47 +140,9 @@ void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() { } } -void WorkspaceLayoutManager::OnTrackedByWorkspaceChanged(Window* window, - bool old){ - if (wm::GetWindowState(window)->tracked_by_workspace()) - SetMaximizedOrFullscreenBounds(wm::GetWindowState(window)); -} - void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window, const void* key, intptr_t old) { - wm::WindowState* window_state = wm::GetWindowState(window); - if (key == aura::client::kShowStateKey) { - ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old); - ui::WindowShowState new_state = window_state->GetShowState(); - if (old_state != ui::SHOW_STATE_MINIMIZED && - !window_state->HasRestoreBounds() && - window_state->IsMaximizedOrFullscreen() && - !wm::WindowState::IsMaximizedOrFullscreenState(old_state)) { - window_state->SaveCurrentBoundsForRestore(); - } - // When restoring from a minimized state, we want to restore to the - // previous (maybe L/R maximized) state. Since we do also want to keep the - // restore rectangle, we set the restore rectangle to the rectangle we want - // to restore to and restore it after we switched so that it is preserved. - gfx::Rect restore; - if (old_state == ui::SHOW_STATE_MINIMIZED && - (new_state == ui::SHOW_STATE_NORMAL || - new_state == ui::SHOW_STATE_DEFAULT) && - window_state->HasRestoreBounds() && - !window_state->always_restores_to_restore_bounds()) { - restore = window_state->GetRestoreBoundsInScreen(); - window_state->SaveCurrentBoundsForRestore(); - } - - UpdateBoundsFromShowState(window_state, old_state); - ShowStateChanged(window_state, old_state); - - // Set the restore rectangle to the previously set restore rectangle. - if (!restore.IsEmpty()) - window_state->SetRestoreBoundsInScreen(restore); - } - if (key == aura::client::kAlwaysOnTopKey && window->GetProperty(aura::client::kAlwaysOnTopKey)) { GetRootWindowController(window->GetRootWindow())-> @@ -188,6 +150,46 @@ void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window, } } +void WorkspaceLayoutManager::OnTrackedByWorkspaceChanged( + wm::WindowState* window_state, + bool old){ + if (window_state->tracked_by_workspace()) + SetMaximizedOrFullscreenBounds(window_state); +} + +void WorkspaceLayoutManager::OnWindowShowTypeChanged( + wm::WindowState* window_state, + wm::WindowShowType old_type) { + ui::WindowShowState old_state = ToWindowShowState(old_type); + ui::WindowShowState new_state = window_state->GetShowState(); + if (old_state != ui::SHOW_STATE_MINIMIZED && + !window_state->HasRestoreBounds() && + window_state->IsMaximizedOrFullscreen() && + !wm::WindowState::IsMaximizedOrFullscreenState(old_state)) { + window_state->SaveCurrentBoundsForRestore(); + } + // When restoring from a minimized state, we want to restore to the + // previous (maybe L/R maximized) state. Since we do also want to keep the + // restore rectangle, we set the restore rectangle to the rectangle we want + // to restore to and restore it after we switched so that it is preserved. + gfx::Rect restore; + if (old_state == ui::SHOW_STATE_MINIMIZED && + (new_state == ui::SHOW_STATE_NORMAL || + new_state == ui::SHOW_STATE_DEFAULT) && + window_state->HasRestoreBounds() && + !window_state->always_restores_to_restore_bounds()) { + restore = window_state->GetRestoreBoundsInScreen(); + window_state->SaveCurrentBoundsForRestore(); + } + + UpdateBoundsFromShowState(window_state, old_state); + ShowStateChanged(window_state, old_state); + + // Set the restore rectangle to the previously set restore rectangle. + if (!restore.IsEmpty()) + window_state->SetRestoreBoundsInScreen(restore); +} + void WorkspaceLayoutManager::ShowStateChanged( wm::WindowState* state, ui::WindowShowState last_show_state) { diff --git a/ash/wm/workspace/workspace_layout_manager.h b/ash/wm/workspace/workspace_layout_manager.h index 607a099..d7dcae7 100644 --- a/ash/wm/workspace/workspace_layout_manager.h +++ b/ash/wm/workspace/workspace_layout_manager.h @@ -57,9 +57,13 @@ class ASH_EXPORT WorkspaceLayoutManager : public BaseLayoutManager { intptr_t old) OVERRIDE; // ash::WindowSettings::Observer overrides: - virtual void OnTrackedByWorkspaceChanged(aura::Window* window, + virtual void OnTrackedByWorkspaceChanged(wm::WindowState* window_state, bool old) OVERRIDE; + // WindowStateObserver overrides: + virtual void OnWindowShowTypeChanged(wm::WindowState* window_state, + wm::WindowShowType old_type) OVERRIDE; + private: // Overridden from BaseLayoutManager: virtual void ShowStateChanged(wm::WindowState* window_state, diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index 81c34e6..18fe6ba 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc @@ -903,7 +903,7 @@ void WorkspaceWindowResizer::UpdateSnapPhantomWindow(const gfx::Point& location, SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE; if (!snap_sizer_) { - snap_sizer_.reset(new SnapSizer(window(), + snap_sizer_.reset(new SnapSizer(window_state(), location, edge, internal::SnapSizer::OTHER_INPUT)); |