Commit a4b3d6b5 authored by skuhne@chromium.org's avatar skuhne@chromium.org

Fullscreen/immersive mode is allowed in touch view mode, the shelf gets hidden...

Fullscreen/immersive mode is allowed in touch view mode, the shelf gets hidden and an edge swipe brings the shelf back.


Allowing immersive / full screen mode in maximize mode

BUG=359606
TEST=ash tests and visual

Review URL: https://codereview.chromium.org/247363005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266350 0039d316-1c4b-4281-b951-d872f2087c98
parent 5ba3b6cf
...@@ -658,6 +658,8 @@ ...@@ -658,6 +658,8 @@
'wm/window_state_delegate.cc', 'wm/window_state_delegate.cc',
'wm/window_state_delegate.h', 'wm/window_state_delegate.h',
'wm/window_state_observer.h', 'wm/window_state_observer.h',
'wm/window_state_util.cc',
'wm/window_state_util.h',
'wm/window_properties.cc', 'wm/window_properties.cc',
'wm/window_properties.h', 'wm/window_properties.h',
'wm/window_resizer.cc', 'wm/window_resizer.cc',
......
...@@ -314,7 +314,7 @@ void ShelfLayoutManager::UpdateVisibilityState() { ...@@ -314,7 +314,7 @@ void ShelfLayoutManager::UpdateVisibilityState() {
return; return;
if (Shell::GetInstance()->session_state_delegate()->IsScreenLocked() || if (Shell::GetInstance()->session_state_delegate()->IsScreenLocked() ||
force_shelf_always_visibile_) { IsShelfForcedToBeVisible()) {
SetState(SHELF_VISIBLE); SetState(SHELF_VISIBLE);
} else { } else {
// TODO(zelidrag): Verify shelf drag animation still shows on the device // TODO(zelidrag): Verify shelf drag animation still shows on the device
...@@ -389,7 +389,7 @@ void ShelfLayoutManager::RemoveObserver(ShelfLayoutManagerObserver* observer) { ...@@ -389,7 +389,7 @@ void ShelfLayoutManager::RemoveObserver(ShelfLayoutManagerObserver* observer) {
// ShelfLayoutManager, Gesture functions: // ShelfLayoutManager, Gesture functions:
void ShelfLayoutManager::OnGestureEdgeSwipe(const ui::GestureEvent& gesture) { void ShelfLayoutManager::OnGestureEdgeSwipe(const ui::GestureEvent& gesture) {
if (force_shelf_always_visibile_) if (IsShelfForcedToBeVisible())
return; return;
if (visibility_state() == SHELF_AUTO_HIDE) { if (visibility_state() == SHELF_AUTO_HIDE) {
...@@ -401,7 +401,7 @@ void ShelfLayoutManager::OnGestureEdgeSwipe(const ui::GestureEvent& gesture) { ...@@ -401,7 +401,7 @@ void ShelfLayoutManager::OnGestureEdgeSwipe(const ui::GestureEvent& gesture) {
} }
void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) { void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) {
if (force_shelf_always_visibile_) if (IsShelfForcedToBeVisible())
return; return;
gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS; gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS;
gesture_drag_amount_ = 0.f; gesture_drag_amount_ = 0.f;
...@@ -412,7 +412,7 @@ void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) { ...@@ -412,7 +412,7 @@ void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) {
ShelfLayoutManager::DragState ShelfLayoutManager::UpdateGestureDrag( ShelfLayoutManager::DragState ShelfLayoutManager::UpdateGestureDrag(
const ui::GestureEvent& gesture) { const ui::GestureEvent& gesture) {
if (force_shelf_always_visibile_) if (IsShelfForcedToBeVisible())
return DRAG_SHELF; return DRAG_SHELF;
bool horizontal = IsHorizontalAlignment(); bool horizontal = IsHorizontalAlignment();
gesture_drag_amount_ += horizontal ? gesture.details().scroll_y() : gesture_drag_amount_ += horizontal ? gesture.details().scroll_y() :
...@@ -438,7 +438,7 @@ ShelfLayoutManager::DragState ShelfLayoutManager::UpdateGestureDrag( ...@@ -438,7 +438,7 @@ ShelfLayoutManager::DragState ShelfLayoutManager::UpdateGestureDrag(
} }
void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) { void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) {
if (force_shelf_always_visibile_) if (IsShelfForcedToBeVisible())
return; return;
bool horizontal = IsHorizontalAlignment(); bool horizontal = IsHorizontalAlignment();
bool should_change = false; bool should_change = false;
...@@ -1008,7 +1008,7 @@ gfx::Rect ShelfLayoutManager::GetAutoHideShowShelfRegionInScreen() const { ...@@ -1008,7 +1008,7 @@ gfx::Rect ShelfLayoutManager::GetAutoHideShowShelfRegionInScreen() const {
ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState( ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
ShelfVisibilityState visibility_state) const { ShelfVisibilityState visibility_state) const {
if (force_shelf_always_visibile_) if (IsShelfForcedToBeVisible())
return SHELF_AUTO_HIDE_SHOWN; return SHELF_AUTO_HIDE_SHOWN;
if (visibility_state != SHELF_AUTO_HIDE || !shelf_) if (visibility_state != SHELF_AUTO_HIDE || !shelf_)
...@@ -1123,6 +1123,17 @@ int ShelfLayoutManager::GetWorkAreaSize(const State& state, int size) const { ...@@ -1123,6 +1123,17 @@ int ShelfLayoutManager::GetWorkAreaSize(const State& state, int size) const {
return 0; return 0;
} }
bool ShelfLayoutManager::IsShelfForcedToBeVisible() const {
// Bail out early when there is no |workspace_controller_|, which happens
// during shutdown after PrepareForShutdown.
if (!workspace_controller_)
return force_shelf_always_visibile_;
return force_shelf_always_visibile_ &&
workspace_controller_->GetWindowState() !=
WORKSPACE_WINDOW_STATE_FULL_SCREEN;
}
gfx::Rect ShelfLayoutManager::GetAvailableBounds() const { gfx::Rect ShelfLayoutManager::GetAvailableBounds() const {
gfx::Rect bounds(root_window_->bounds()); gfx::Rect bounds(root_window_->bounds());
bounds.set_height(bounds.height() - keyboard_bounds_.height()); bounds.set_height(bounds.height() - keyboard_bounds_.height());
......
...@@ -321,6 +321,9 @@ class ASH_EXPORT ShelfLayoutManager : ...@@ -321,6 +321,9 @@ class ASH_EXPORT ShelfLayoutManager :
int GetWorkAreaSize(const State& state, int size) const; int GetWorkAreaSize(const State& state, int size) const;
// Returns true if the shelf should be forced to be visible.
bool IsShelfForcedToBeVisible() const;
// Return the bounds available in the parent, taking into account the bounds // Return the bounds available in the parent, taking into account the bounds
// of the keyboard if necessary. // of the keyboard if necessary.
gfx::Rect GetAvailableBounds() const; gfx::Rect GetAvailableBounds() const;
......
...@@ -1570,6 +1570,39 @@ TEST_F(ShelfLayoutManagerTest, GestureEdgeSwipe) { ...@@ -1570,6 +1570,39 @@ TEST_F(ShelfLayoutManagerTest, GestureEdgeSwipe) {
EXPECT_TRUE(widget->IsFullscreen()); EXPECT_TRUE(widget->IsFullscreen());
} }
// Test that starting the maximize mode does still allow the shelf to be made
// visible when an (immersive mode) full screen app is running.
TEST_F(ShelfLayoutManagerTest, GestureEdgeSwipeInMaximizeMode) {
ShelfLayoutManager* shelf = GetShelfLayoutManager();
shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
views::Widget* widget = new views::Widget;
views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
params.bounds = gfx::Rect(0, 0, 200, 200);
params.context = CurrentContext();
widget->Init(params);
widget->Show();
aura::Window* window = widget->GetNativeWindow();
wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false);
widget->SetFullscreen(true);
aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
// The maximize mode gets started.
shelf->OnMaximizeModeStarted();
shelf->LayoutShelf();
shelf->UpdateVisibilityState();
// Edge swipe in fullscreen + AUTO_HIDE_HIDDEN should show the shelf and
// remain fullscreen.
EXPECT_TRUE(widget->IsFullscreen());
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
generator.GestureEdgeSwipe();
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
EXPECT_TRUE(widget->IsFullscreen());
}
// Check that in maximize mode gesture swipes on the shelf have no effect. // Check that in maximize mode gesture swipes on the shelf have no effect.
TEST_F(ShelfLayoutManagerTest, MaximizeModeGestureEdgeSwipe) { TEST_F(ShelfLayoutManagerTest, MaximizeModeGestureEdgeSwipe) {
ShelfLayoutManager* shelf = GetShelfLayoutManager(); ShelfLayoutManager* shelf = GetShelfLayoutManager();
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "ash/wm/window_animations.h" #include "ash/wm/window_animations.h"
#include "ash/wm/window_state.h" #include "ash/wm/window_state.h"
#include "ash/wm/window_state_delegate.h" #include "ash/wm/window_state_delegate.h"
#include "ash/wm/window_state_util.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h" #include "ash/wm/wm_event.h"
#include "ash/wm/workspace/workspace_window_resizer.h" #include "ash/wm/workspace/workspace_window_resizer.h"
...@@ -258,25 +259,9 @@ bool DefaultState::ProcessCompoundEvents(WindowState* window_state, ...@@ -258,25 +259,9 @@ bool DefaultState::ProcessCompoundEvents(WindowState* window_state,
} }
return true; return true;
} }
case WM_EVENT_TOGGLE_FULLSCREEN: { case WM_EVENT_TOGGLE_FULLSCREEN:
// Window which cannot be maximized should not be fullscreened. ToggleFullScreen(window_state, window_state->delegate());
// It can, however, be restored if it was fullscreened.
bool is_fullscreen = window_state->IsFullscreen();
if (!is_fullscreen && !window_state->CanMaximize())
return true;
if (window_state->delegate() &&
window_state->delegate()->ToggleFullscreen(window_state)) {
return true;
}
if (is_fullscreen) {
window_state->Restore();
} else {
//
window_state->window()->SetProperty(aura::client::kShowStateKey,
ui::SHOW_STATE_FULLSCREEN);
}
return true; return true;
}
case WM_EVENT_CENTER: case WM_EVENT_CENTER:
CenterWindow(window_state); CenterWindow(window_state);
return true; return true;
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
#include "ash/wm/maximize_mode/maximize_mode_window_manager.h" #include "ash/wm/maximize_mode/maximize_mode_window_manager.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h" #include "ash/screen_util.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/switchable_windows.h" #include "ash/switchable_windows.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
...@@ -673,29 +675,84 @@ TEST_F(MaximizeModeWindowManagerTest, TestMinimize) { ...@@ -673,29 +675,84 @@ TEST_F(MaximizeModeWindowManagerTest, TestMinimize) {
EXPECT_TRUE(window->IsVisible()); EXPECT_TRUE(window->IsVisible());
} }
// Check that a full screen window is changing to maximized in maximize mode, // Check that a full screen window is staying full screen in maximize mode,
// cannot go to fullscreen and goes back to fullscreen thereafter. // and that it returns to full screen thereafter (if left).
TEST_F(MaximizeModeWindowManagerTest, FullScreenModeTests) { TEST_F(MaximizeModeWindowManagerTest, KeepFullScreenModeOn) {
gfx::Rect rect(20, 140, 100, 100); gfx::Rect rect(20, 140, 100, 100);
scoped_ptr<aura::Window> w1(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect)); scoped_ptr<aura::Window> w1(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
wm::WindowState* window_state = wm::GetWindowState(w1.get()); wm::WindowState* window_state = wm::GetWindowState(w1.get());
ShelfLayoutManager* shelf =
Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
// Allow the shelf to hide.
shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN); wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
window_state->OnWMEvent(&event); window_state->OnWMEvent(&event);
// With full screen, the shelf should get hidden.
EXPECT_TRUE(window_state->IsFullscreen()); EXPECT_TRUE(window_state->IsFullscreen());
EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
CreateMaximizeModeWindowManager(); CreateMaximizeModeWindowManager();
// Fullscreen mode should now be off and it should not come back while in // The Full screen mode should continue to be on.
// maximize mode. EXPECT_TRUE(window_state->IsFullscreen());
EXPECT_FALSE(window_state->IsFullscreen()); EXPECT_FALSE(window_state->IsMaximized());
EXPECT_TRUE(window_state->IsMaximized()); EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
// With leaving the fullscreen mode, the maximized mode should return and the
// shelf should become visible.
window_state->OnWMEvent(&event); window_state->OnWMEvent(&event);
EXPECT_FALSE(window_state->IsFullscreen()); EXPECT_FALSE(window_state->IsFullscreen());
EXPECT_TRUE(window_state->IsMaximized()); EXPECT_TRUE(window_state->IsMaximized());
EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
// Ending the maximize mode should return to full screen and the shelf should
// be hidden again.
DestroyMaximizeModeWindowManager(); DestroyMaximizeModeWindowManager();
EXPECT_TRUE(window_state->IsFullscreen()); EXPECT_TRUE(window_state->IsFullscreen());
EXPECT_FALSE(window_state->IsMaximized()); EXPECT_FALSE(window_state->IsMaximized());
EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
}
// Check that full screen mode can be turned on in maximized mode.
TEST_F(MaximizeModeWindowManagerTest, AllowFullScreenMode) {
gfx::Rect rect(20, 140, 100, 100);
scoped_ptr<aura::Window> w1(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
wm::WindowState* window_state = wm::GetWindowState(w1.get());
ShelfLayoutManager* shelf =
Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
// Allow the shelf to hide.
shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
EXPECT_FALSE(window_state->IsFullscreen());
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
CreateMaximizeModeWindowManager();
// Fullscreen mode should still be off and the shelf should be visible.
EXPECT_FALSE(window_state->IsFullscreen());
EXPECT_TRUE(window_state->IsMaximized());
EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
// After going into fullscreen mode, the shelf should be hidden.
wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
window_state->OnWMEvent(&event);
EXPECT_TRUE(window_state->IsFullscreen());
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
// With the destruction of the manager we should fall back to the old state.
DestroyMaximizeModeWindowManager();
EXPECT_FALSE(window_state->IsFullscreen());
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
} }
// Check that snapping operations get ignored. // Check that snapping operations get ignored.
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "ash/wm/window_animations.h" #include "ash/wm/window_animations.h"
#include "ash/wm/window_state.h" #include "ash/wm/window_state.h"
#include "ash/wm/window_state_delegate.h" #include "ash/wm/window_state_delegate.h"
#include "ash/wm/window_state_util.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h" #include "ash/wm/wm_event.h"
#include "ash/wm/workspace/workspace_window_resizer.h" #include "ash/wm/workspace/workspace_window_resizer.h"
...@@ -54,8 +55,11 @@ gfx::Rect GetCenteredBounds(const gfx::Rect& bounds_in_parent, ...@@ -54,8 +55,11 @@ gfx::Rect GetCenteredBounds(const gfx::Rect& bounds_in_parent,
return work_area_in_parent; return work_area_in_parent;
} }
// Returns the maximized and centered bounds of a window. // Returns the maximized/full screen and/or centered bounds of a window.
gfx::Rect GetMaximizedAndCenteredBounds(wm::WindowState* state_object) { gfx::Rect GetBoundsInMaximizedMode(wm::WindowState* state_object) {
if (state_object->IsFullscreen())
return ScreenUtil::GetDisplayBoundsInParent(state_object->window());
gfx::Rect bounds_in_parent; gfx::Rect bounds_in_parent;
// Make the window as big as possible. // Make the window as big as possible.
if (state_object->CanMaximize() || state_object->CanResize()) { if (state_object->CanMaximize() || state_object->CanResize()) {
...@@ -77,7 +81,7 @@ gfx::Rect GetMaximizedAndCenteredBounds(wm::WindowState* state_object) { ...@@ -77,7 +81,7 @@ gfx::Rect GetMaximizedAndCenteredBounds(wm::WindowState* state_object) {
// static // static
void MaximizeModeWindowState::UpdateWindowPosition( void MaximizeModeWindowState::UpdateWindowPosition(
wm::WindowState* window_state, bool animated) { wm::WindowState* window_state, bool animated) {
gfx::Rect bounds_in_parent = GetMaximizedAndCenteredBounds(window_state); gfx::Rect bounds_in_parent = GetBoundsInMaximizedMode(window_state);
if (bounds_in_parent == window_state->window()->bounds()) if (bounds_in_parent == window_state->window()->bounds())
return; return;
...@@ -111,34 +115,38 @@ void MaximizeModeWindowState::LeaveMaximizeMode(wm::WindowState* window_state) { ...@@ -111,34 +115,38 @@ void MaximizeModeWindowState::LeaveMaximizeMode(wm::WindowState* window_state) {
void MaximizeModeWindowState::OnWMEvent(wm::WindowState* window_state, void MaximizeModeWindowState::OnWMEvent(wm::WindowState* window_state,
const wm::WMEvent* event) { const wm::WMEvent* event) {
switch (event->type()) { switch (event->type()) {
case wm::WM_EVENT_TOGGLE_FULLSCREEN:
ToggleFullScreen(window_state, window_state->delegate());
break;
case wm::WM_EVENT_FULLSCREEN:
UpdateWindow(window_state, wm::WINDOW_STATE_TYPE_FULLSCREEN, true);
break;
case wm::WM_EVENT_TOGGLE_MAXIMIZE_CAPTION: case wm::WM_EVENT_TOGGLE_MAXIMIZE_CAPTION:
case wm::WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE: case wm::WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE:
case wm::WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE: case wm::WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE:
case wm::WM_EVENT_TOGGLE_FULLSCREEN:
case wm::WM_EVENT_TOGGLE_MAXIMIZE: case wm::WM_EVENT_TOGGLE_MAXIMIZE:
case wm::WM_EVENT_CENTER: case wm::WM_EVENT_CENTER:
case wm::WM_EVENT_FULLSCREEN:
case wm::WM_EVENT_SNAP_LEFT: case wm::WM_EVENT_SNAP_LEFT:
case wm::WM_EVENT_SNAP_RIGHT: case wm::WM_EVENT_SNAP_RIGHT:
case wm::WM_EVENT_NORMAL: case wm::WM_EVENT_NORMAL:
case wm::WM_EVENT_MAXIMIZE: case wm::WM_EVENT_MAXIMIZE:
MaximizeOrCenterWindow(window_state, true); UpdateWindow(window_state,
GetMaximizedOrCenteredWindowType(window_state),
true);
return; return;
case wm::WM_EVENT_MINIMIZE: case wm::WM_EVENT_MINIMIZE:
if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED) { UpdateWindow(window_state, wm::WINDOW_STATE_TYPE_MINIMIZED, true);
current_state_type_ = wm::WINDOW_STATE_TYPE_MINIMIZED;
Minimize(window_state);
}
return; return;
case wm::WM_EVENT_SHOW_INACTIVE: case wm::WM_EVENT_SHOW_INACTIVE:
return; return;
case wm::WM_EVENT_SET_BOUNDS: case wm::WM_EVENT_SET_BOUNDS:
if (current_state_type_ == wm::WINDOW_STATE_TYPE_MAXIMIZED || if (window_state->CanResize()) {
window_state->CanResize()) {
// In case the window is resizable and / or maximized we ignore the // In case the window is resizable and / or maximized we ignore the
// requested bounds change and resize to the biggest possible size. // requested bounds change and resize to the biggest possible size.
MaximizeOrCenterWindow(window_state, true); UpdateBounds(window_state, true);
} else if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED) { } else
if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED &&
current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED) {
// In all other cases (except for minimized windows) we respect the // In all other cases (except for minimized windows) we respect the
// requested bounds and center it to a fully visible area on the screen. // requested bounds and center it to a fully visible area on the screen.
gfx::Rect bounds_in_parent = gfx::Rect bounds_in_parent =
...@@ -153,12 +161,18 @@ void MaximizeModeWindowState::OnWMEvent(wm::WindowState* window_state, ...@@ -153,12 +161,18 @@ void MaximizeModeWindowState::OnWMEvent(wm::WindowState* window_state,
} }
break; break;
case wm::WM_EVENT_ADDED_TO_WORKSPACE: case wm::WM_EVENT_ADDED_TO_WORKSPACE:
MaximizeOrCenterWindow(window_state, true); if (current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED &&
current_state_type_ != wm::WINDOW_STATE_TYPE_FULLSCREEN &&
current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED) {
wm::WindowStateType new_state =
GetMaximizedOrCenteredWindowType(window_state);
UpdateWindow(window_state, new_state, true);
}
break; break;
case wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED: case wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED:
case wm::WM_EVENT_DISPLAY_BOUNDS_CHANGED: case wm::WM_EVENT_DISPLAY_BOUNDS_CHANGED:
if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED) if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED)
MaximizeOrCenterWindow(window_state, false); UpdateBounds(window_state, true);
break; break;
} }
} }
...@@ -174,8 +188,11 @@ void MaximizeModeWindowState::AttachState( ...@@ -174,8 +188,11 @@ void MaximizeModeWindowState::AttachState(
// Initialize the state to a good preset. // Initialize the state to a good preset.
if (current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED && if (current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED &&
current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED) { current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED &&
MaximizeOrCenterWindow(window_state, true); current_state_type_ != wm::WINDOW_STATE_TYPE_FULLSCREEN) {
UpdateWindow(window_state,
GetMaximizedOrCenteredWindowType(window_state),
true);
} }
window_state->set_can_be_dragged(false); window_state->set_can_be_dragged(false);
...@@ -185,38 +202,41 @@ void MaximizeModeWindowState::DetachState(wm::WindowState* window_state) { ...@@ -185,38 +202,41 @@ void MaximizeModeWindowState::DetachState(wm::WindowState* window_state) {
window_state->set_can_be_dragged(true); window_state->set_can_be_dragged(true);
} }
void MaximizeModeWindowState::MaximizeOrCenterWindow( void MaximizeModeWindowState::UpdateWindow(wm::WindowState* window_state,
wm::WindowState* window_state, wm::WindowStateType target_state,
bool animated) { bool animated) {
const wm::WindowStateType target_state = DCHECK(target_state == wm::WINDOW_STATE_TYPE_MINIMIZED ||
window_state->CanMaximize() ? wm::WINDOW_STATE_TYPE_MAXIMIZED : target_state == wm::WINDOW_STATE_TYPE_MAXIMIZED ||
wm::WINDOW_STATE_TYPE_NORMAL; (target_state == wm::WINDOW_STATE_TYPE_NORMAL &&
const wm::WindowStateType old_state_type = current_state_type_; !window_state->CanMaximize()) ||
gfx::Rect bounds_in_parent = GetMaximizedAndCenteredBounds(window_state); target_state == wm::WINDOW_STATE_TYPE_FULLSCREEN);
if (target_state == wm::WINDOW_STATE_TYPE_MINIMIZED) {
if (current_state_type_ == wm::WINDOW_STATE_TYPE_MINIMIZED)
return;
if (current_state_type_ != target_state) {
current_state_type_ = target_state; current_state_type_ = target_state;
window_state->UpdateWindowShowStateFromStateType(); ::wm::SetWindowVisibilityAnimationType(
window_state->NotifyPreStateTypeChange(old_state_type); window_state->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
// If we have a target bounds rectangle, we center it and set it window_state->window()->Hide();
// accordingly. if (window_state->IsActive())
if (!bounds_in_parent.IsEmpty()) { window_state->Deactivate();
if (current_state_type_ == wm::WINDOW_STATE_TYPE_MINIMIZED || !animated) return;
window_state->SetBoundsDirect(bounds_in_parent); }
else
window_state->SetBoundsDirectAnimated(bounds_in_parent); if (current_state_type_ == target_state) {
} // If the state type did not change, update it accordingly.
window_state->NotifyPostStateTypeChange(old_state_type); UpdateBounds(window_state, animated);
} else if (!bounds_in_parent.IsEmpty() && return;
bounds_in_parent != window_state->window()->bounds()) {
// Coming here, we were most probably called through a display change.
// Do not animate.
if (animated)
window_state->SetBoundsDirectAnimated(bounds_in_parent);
else
window_state->SetBoundsDirect(bounds_in_parent);
} }
const wm::WindowStateType old_state_type = current_state_type_;
current_state_type_ = target_state;
window_state->UpdateWindowShowStateFromStateType();
window_state->NotifyPreStateTypeChange(old_state_type);
UpdateBounds(window_state, animated);
window_state->NotifyPostStateTypeChange(old_state_type);
if ((window_state->window()->TargetVisibility() || if ((window_state->window()->TargetVisibility() ||
old_state_type == wm::WINDOW_STATE_TYPE_MINIMIZED) && old_state_type == wm::WINDOW_STATE_TYPE_MINIMIZED) &&
!window_state->window()->layer()->visible()) { !window_state->window()->layer()->visible()) {
...@@ -226,15 +246,27 @@ void MaximizeModeWindowState::MaximizeOrCenterWindow( ...@@ -226,15 +246,27 @@ void MaximizeModeWindowState::MaximizeOrCenterWindow(
} }
} }
void MaximizeModeWindowState::Minimize(wm::WindowState* window_state) { wm::WindowStateType MaximizeModeWindowState::GetMaximizedOrCenteredWindowType(
::wm::SetWindowVisibilityAnimationType( wm::WindowState* window_state) {
window_state->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE); return window_state->CanMaximize() ? wm::WINDOW_STATE_TYPE_MAXIMIZED :
wm::WINDOW_STATE_TYPE_NORMAL;
}
// Hide the window. void MaximizeModeWindowState::UpdateBounds(wm::WindowState* window_state,
window_state->window()->Hide(); bool animated) {
// Activate another window. gfx::Rect bounds_in_parent = GetBoundsInMaximizedMode(window_state);
if (window_state->IsActive()) // If we have a target bounds rectangle, we center it and set it
window_state->Deactivate(); // accordingly.
if (!bounds_in_parent.IsEmpty() &&
bounds_in_parent != window_state->window()->bounds()) {
if (current_state_type_ == wm::WINDOW_STATE_TYPE_MINIMIZED ||
!window_state->window()->IsVisible() ||
!animated) {
window_state->SetBoundsDirect(bounds_in_parent);
} else {
window_state->SetBoundsDirectAnimated(bounds_in_parent);
}
}
} }
} // namespace ash } // namespace ash
...@@ -41,12 +41,22 @@ class MaximizeModeWindowState : public wm::WindowState::State { ...@@ -41,12 +41,22 @@ class MaximizeModeWindowState : public wm::WindowState::State {
virtual void DetachState(wm::WindowState* window_state) OVERRIDE; virtual void DetachState(wm::WindowState* window_state) OVERRIDE;
private: private:
// Centers the window on top of the workspace or maximizes it. If |animate| is // Updates the window to |new_state_type| and resulting bounds:
// set to true, a bounds change will be animated - otherwise immediate. // Either full screen, maximized centered or minimized. If the state does not
void MaximizeOrCenterWindow(wm::WindowState* window_state, bool animate); // change, only the bounds will be changed. If |animate| is set, the bound
// change get animated.
// Minimize the window. void UpdateWindow(wm::WindowState* window_state,
void Minimize(wm::WindowState* window_state); wm::WindowStateType new_state_type,
bool animate);
// Depending on the capabilities of the window we either return
// |WINDOW_STATE_TYPE_MAXIMIZED| or |WINDOW_STATE_TYPE_NORMAL|.
wm::WindowStateType GetMaximizedOrCenteredWindowType(
wm::WindowState* window_state);
// Updates the bounds to the maximum possible bounds according to the current
// window state. If |animated| is set we animate the change.
void UpdateBounds(wm::WindowState* window_state, bool animated);
// The original state object of the window. // The original state object of the window.
scoped_ptr<wm::WindowState::State> old_state_; scoped_ptr<wm::WindowState::State> old_state_;
......
// Copyright 2014 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/window_state_util.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_state_delegate.h"
#include "ui/aura/client/aura_constants.h"
namespace ash {
namespace wm {
void ToggleFullScreen(wm::WindowState* window_state,
WindowStateDelegate* delegate) {
// Window which cannot be maximized should not be full screen'ed.
// It can, however, be restored if it was full screen'ed.
bool is_fullscreen = window_state->IsFullscreen();
if (!is_fullscreen && !window_state->CanMaximize())
return;
if (delegate && delegate->ToggleFullscreen(window_state))
return;
if (is_fullscreen) {
window_state->Restore();
} else {
// Set the property to activate full screen.
window_state->window()->SetProperty(aura::client::kShowStateKey,
ui::SHOW_STATE_FULLSCREEN);
}
}
} // namespace wm
} // namespace ash
// Copyright 2014 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_UTIL_H_
#define ASH_WM_WINDOW_STATE_UTIL_H_
namespace ash {
namespace wm {
class WindowState;
class WindowStateDelegate;
// Toggle the full screen from inside a WindowState::State handler.
void ToggleFullScreen(WindowState* window_state, WindowStateDelegate* delegate);
} // namespace wm
} // namespace ash
#endif // ASH_WM_WINDOW_STATE_UTIL_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment