Chromium Code Reviews| Index: ash/wm/window_state.cc |
| diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc |
| index 81f23fe30c216b5b23f81b36121a43780da162fd..82eb0c32b0622205c770a81268111c91dd059a44 100644 |
| --- a/ash/wm/window_state.cc |
| +++ b/ash/wm/window_state.cc |
| @@ -17,14 +17,66 @@ |
| #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 are cleaned up, move this to the real layout |
|
pkotwicz
2014/02/12 22:27:27
Nit: all logic are cleaned up -> all logic is clea
oshima
2014/02/13 14:52:34
Done.
|
| +// 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: |
| + 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 +90,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 |
| @@ -111,6 +162,11 @@ bool WindowState::IsSnapped() const { |
| window_show_type_ == SHOW_TYPE_RIGHT_SNAPPED; |
| } |
| +bool WindowState::IsPanel() const { |
| + return window_->parent() && |
| + window_->parent()->id() == internal::kShellWindowId_PanelContainer; |
| +} |
| + |
| bool WindowState::CanMaximize() const { |
| return window_->GetProperty(aura::client::kCanMaximizeKey); |
| } |
| @@ -182,23 +238,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 +317,25 @@ void WindowState::SetAndClearRestoreBounds() { |
| ClearRestoreBounds(); |
| } |
| +void WindowState::AdjustSnappedBounds(gfx::Rect* bounds) { |
| + if (is_dragged() || !IsSnapped()) |
|
pkotwicz
2014/02/12 22:27:27
AdjustSnappedBounds() is suboptimal but is ok for
oshima
2014/02/13 14:52:34
yes this is temporal. This method should not be ex
|
| + return; |
| + gfx::Rect maximized_bounds = ScreenUtil::GetMaximizedWindowBoundsInParent( |
| + window_); |
| + if (window_show_type() == wm::SHOW_TYPE_LEFT_SNAPPED) |
| + bounds->set_x(maximized_bounds.x()); |
| + else if (window_show_type() == wm::SHOW_TYPE_RIGHT_SNAPPED) |
| + bounds->set_x(maximized_bounds.right() - bounds->width()); |
| + bounds->set_y(maximized_bounds.y()); |
| + bounds->set_height(maximized_bounds.height()); |
| +} |
| + |
| void 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 +356,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 +371,40 @@ 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); |
| + base::AutoReset<bool> resetter(&ignore_property_change_, true); |
|
pkotwicz
2014/02/12 22:27:27
Can you move |resetter| within the if statement?
oshima
2014/02/13 14:52:34
Done.
|
| if (new_window_state != GetShowState()) |
| 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)); |
| - } |
| +} |
| + |
| +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() { |