Index: ash/wm/window_state.cc |
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc |
index 9223ff90421d19aa34b14197532608e30402d207..7e7fe222951e7e6b6a72201bd86e56f3489671fe 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 |
+// manager with proper friendship. |
pkotwicz
2014/02/12 05:44:48
Can you move adding this class as part of a differ
oshima
2014/02/12 14:08:33
Sorry, I didn't understand. Can you elaborate?
pkotwicz
2014/02/12 18:20:18
Can you remove this class from this CL?
oshima
2014/02/12 19:56:16
Sorry I still didn't understand. This is used in 4
pkotwicz
2014/02/12 22:27:27
I see now
|
+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 |
@@ -272,12 +323,26 @@ 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() == 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()); |
+ // TODO(varkha): Set width to 50% here for snapped windows. |
+ 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, |
@@ -298,7 +363,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 |
@@ -311,21 +378,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); |
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() { |