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() { |