| Index: ash/wm/window_state.cc
|
| diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc
|
| index 81f23fe30c216b5b23f81b36121a43780da162fd..9f8959695cee3a1ac3f0b2700ae838581b654833 100644
|
| --- a/ash/wm/window_state.cc
|
| +++ b/ash/wm/window_state.cc
|
| @@ -17,14 +17,67 @@
|
| #include "base/auto_reset.h"
|
| #include "base/command_line.h"
|
| #include "ui/aura/client/aura_constants.h"
|
| +#include "ui/aura/layout_manager.h"
|
| #include "ui/aura/window.h"
|
| #include "ui/aura/window_delegate.h"
|
| +#include "ui/compositor/scoped_layer_animation_settings.h"
|
| #include "ui/gfx/display.h"
|
| #include "ui/views/corewm/window_util.h"
|
|
|
| namespace ash {
|
| namespace wm {
|
|
|
| +namespace {
|
| +
|
| +// A tentative class to set the bounds on the window.
|
| +// TODO(oshima): Once all logic is cleaned up, move this to the real layout
|
| +// manager with proper friendship.
|
| +class BoundsSetter : public aura::LayoutManager {
|
| + public:
|
| + BoundsSetter() {}
|
| + virtual ~BoundsSetter() {}
|
| +
|
| + // aura::LayoutManager overrides:
|
| + virtual void OnWindowResized() OVERRIDE {}
|
| + virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE {}
|
| + virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {}
|
| + virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {}
|
| + virtual void OnChildWindowVisibilityChanged(
|
| + aura::Window* child, bool visible) OVERRIDE {}
|
| + virtual void SetChildBounds(
|
| + aura::Window* child, const gfx::Rect& requested_bounds) OVERRIDE {}
|
| +
|
| + void SetBounds(aura::Window* window, const gfx::Rect& bounds) {
|
| + SetChildBoundsDirect(window, bounds);
|
| + }
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(BoundsSetter);
|
| +};
|
| +
|
| +WMEvent WMEventFromShowState(ui::WindowShowState requested_show_state) {
|
| + switch (requested_show_state) {
|
| + case ui::SHOW_STATE_DEFAULT:
|
| + case ui::SHOW_STATE_NORMAL:
|
| + return NORMAL;
|
| + case ui::SHOW_STATE_MINIMIZED:
|
| + return MINIMIZE;
|
| + case ui::SHOW_STATE_MAXIMIZED:
|
| + return MAXIMIZE;
|
| + case ui::SHOW_STATE_FULLSCREEN:
|
| + return FULLSCREEN;
|
| + case ui::SHOW_STATE_INACTIVE:
|
| + return SHOW_INACTIVE;
|
| + case ui::SHOW_STATE_DETACHED:
|
| + case ui::SHOW_STATE_END:
|
| + NOTREACHED() << "No WMEvent defined for the show type:"
|
| + << requested_show_state;
|
| + }
|
| + return NORMAL;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| WindowState::WindowState(aura::Window* window)
|
| : window_(window),
|
| window_position_managed_(false),
|
| @@ -38,11 +91,10 @@ WindowState::WindowState(aura::Window* window)
|
| hide_shelf_when_fullscreen_(true),
|
| animate_to_fullscreen_(true),
|
| minimum_visibility_(false),
|
| - in_set_window_show_type_(false),
|
| + ignore_property_change_(false),
|
| window_show_type_(ToWindowShowType(GetShowState())),
|
| current_state_(new DefaultState) {
|
| window_->AddObserver(this);
|
| -
|
| #if defined(OS_CHROMEOS)
|
| // NOTE(pkotwicz): Animating to immersive fullscreen does not look good. When
|
| // switches::UseImmersiveFullscreenForAllWindows() returns true, most windows
|
| @@ -182,23 +234,11 @@ void WindowState::Deactivate() {
|
|
|
| void WindowState::Restore() {
|
| if (!IsNormalShowType())
|
| - SetWindowShowType(SHOW_TYPE_NORMAL);
|
| + OnWMEvent(NORMAL);
|
| }
|
|
|
| void WindowState::ToggleFullscreen() {
|
| - // Window which cannot be maximized should not be fullscreened.
|
| - // It can, however, be restored if it was fullscreened.
|
| - bool is_fullscreen = IsFullscreen();
|
| - if (!is_fullscreen && !CanMaximize())
|
| - return;
|
| - if (delegate_ && delegate_->ToggleFullscreen(this))
|
| - return;
|
| - if (is_fullscreen) {
|
| - Restore();
|
| - } else {
|
| - window_->SetProperty(aura::client::kShowStateKey,
|
| - ui::SHOW_STATE_FULLSCREEN);
|
| - }
|
| + OnWMEvent(TOGGLE_FULLSCREEN);
|
| }
|
|
|
| void WindowState::OnWMEvent(WMEvent event) {
|
| @@ -273,12 +313,25 @@ void WindowState::SetAndClearRestoreBounds() {
|
| ClearRestoreBounds();
|
| }
|
|
|
| +void WindowState::AdjustSnappedBounds(gfx::Rect* bounds) {
|
| + if (is_dragged() || !IsSnapped())
|
| + return;
|
| + gfx::Rect maximized_bounds = ScreenUtil::GetMaximizedWindowBoundsInParent(
|
| + window_);
|
| + if (window_show_type() == SHOW_TYPE_LEFT_SNAPPED)
|
| + bounds->set_x(maximized_bounds.x());
|
| + else if (window_show_type() == 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 WindowState::OnWindowPropertyChanged(aura::Window* window,
|
| const void* key,
|
| intptr_t old) {
|
| DCHECK_EQ(window, window_);
|
| - if (key == aura::client::kShowStateKey)
|
| - SetWindowShowType(ToWindowShowType(GetShowState()));
|
| + if (key == aura::client::kShowStateKey && !ignore_property_change_)
|
| + OnWMEvent(WMEventFromShowState(GetShowState()));
|
| }
|
|
|
| void WindowState::SnapWindow(WindowShowType left_or_right,
|
| @@ -299,7 +352,9 @@ void WindowState::SnapWindow(WindowShowType left_or_right,
|
|
|
| DCHECK(left_or_right == SHOW_TYPE_LEFT_SNAPPED ||
|
| left_or_right == SHOW_TYPE_RIGHT_SNAPPED);
|
| - SetWindowShowType(left_or_right);
|
| + OnWMEvent(left_or_right == SHOW_TYPE_LEFT_SNAPPED ?
|
| + SNAP_LEFT : SNAP_RIGHT);
|
| +
|
| // TODO(varkha): Ideally the bounds should be changed in a LayoutManager upon
|
| // observing the WindowShowType change.
|
| // If the window is a child of kShellWindowId_DockedContainer such as during
|
| @@ -312,21 +367,41 @@ void WindowState::SnapWindow(WindowShowType left_or_right,
|
| SetRestoreBoundsInScreen(restore_bounds_in_screen);
|
| }
|
|
|
| -void WindowState::SetWindowShowType(WindowShowType new_window_show_type) {
|
| - if (in_set_window_show_type_)
|
| - return;
|
| - base::AutoReset<bool> resetter(&in_set_window_show_type_, true);
|
| -
|
| +void WindowState::UpdateWindowShowType(WindowShowType new_window_show_type) {
|
| ui::WindowShowState new_window_state =
|
| ToWindowShowState(new_window_show_type);
|
| - if (new_window_state != GetShowState())
|
| + if (new_window_state != GetShowState()) {
|
| + base::AutoReset<bool> resetter(&ignore_property_change_, true);
|
| window_->SetProperty(aura::client::kShowStateKey, new_window_state);
|
| - WindowShowType old_window_show_type = window_show_type_;
|
| - window_show_type_ = new_window_show_type;
|
| - if (old_window_show_type != window_show_type_) {
|
| - FOR_EACH_OBSERVER(WindowStateObserver, observer_list_,
|
| - OnWindowShowTypeChanged(this, old_window_show_type));
|
| }
|
| + window_show_type_ = new_window_show_type;
|
| +}
|
| +
|
| +void WindowState::NotifyPreShowTypeChange(WindowShowType old_window_show_type) {
|
| + FOR_EACH_OBSERVER(WindowStateObserver, observer_list_,
|
| + OnPreWindowShowTypeChange(this, old_window_show_type));
|
| +}
|
| +
|
| +void WindowState::NotifyPostShowTypeChange(
|
| + WindowShowType old_window_show_type) {
|
| + FOR_EACH_OBSERVER(WindowStateObserver, observer_list_,
|
| + OnPostWindowShowTypeChange(this, old_window_show_type));
|
| +}
|
| +
|
| +void WindowState::SetBoundsDirect(const gfx::Rect& bounds) {
|
| + BoundsSetter().SetBounds(window_, bounds);
|
| +}
|
| +
|
| +void WindowState::SetBoundsDirectAnimated(const gfx::Rect& bounds) {
|
| + const int kBoundsChangeSlideDurationMs = 120;
|
| +
|
| + ui::Layer* layer = window_->layer();
|
| + ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator());
|
| + slide_settings.SetPreemptionStrategy(
|
| + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
|
| + slide_settings.SetTransitionDuration(
|
| + base::TimeDelta::FromMilliseconds(kBoundsChangeSlideDurationMs));
|
| + SetBoundsDirect(bounds);
|
| }
|
|
|
| WindowState* GetActiveWindowState() {
|
|
|