summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/root_window_controller.cc10
-rw-r--r--ash/root_window_controller.h4
-rw-r--r--ash/root_window_controller_unittest.cc31
-rw-r--r--ash/wm/shelf_layout_manager.cc5
-rw-r--r--ash/wm/window_properties.cc1
-rw-r--r--ash/wm/window_properties.h3
-rw-r--r--ash/wm/workspace/workspace_manager.cc4
-rw-r--r--ash/wm/workspace/workspace_manager.h3
-rw-r--r--ash/wm/workspace_controller.cc5
-rw-r--r--ash/wm/workspace_controller.h5
-rw-r--r--chrome/browser/ui/ash/launcher/launcher_context_menu.cc11
-rw-r--r--chrome/browser/ui/views/immersive_mode_controller.cc11
-rw-r--r--chrome/browser/ui/views/immersive_mode_controller_browsertest.cc50
13 files changed, 139 insertions, 4 deletions
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 1993e418..5ea37bb 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -512,6 +512,16 @@ ShelfAlignment RootWindowController::GetShelfAlignment() {
return shelf_->GetAlignment();
}
+bool RootWindowController::IsImmersiveMode() const {
+ aura::Window* container = workspace_controller_->GetActiveWorkspaceWindow();
+ for (size_t i = 0; i < container->children().size(); ++i) {
+ aura::Window* child = container->children()[i];
+ if (child->IsVisible() && child->GetProperty(kImmersiveModeKey))
+ return true;
+ }
+ return false;
+}
+
////////////////////////////////////////////////////////////////////////////////
// RootWindowController, private:
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h
index 92185a6..e5e85ef1 100644
--- a/ash/root_window_controller.h
+++ b/ash/root_window_controller.h
@@ -164,6 +164,10 @@ class ASH_EXPORT RootWindowController {
bool SetShelfAlignment(ShelfAlignment alignment);
ShelfAlignment GetShelfAlignment();
+ // Returns true if the active workspace is in immersive mode. Exposed here
+ // so clients of Ash don't need to know the details of workspace management.
+ bool IsImmersiveMode() const;
+
private:
// Creates each of the special window containers that holds windows of various
// types in the shell UI.
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc
index 8dac9d3..54aa82d 100644
--- a/ash/root_window_controller_unittest.cc
+++ b/ash/root_window_controller_unittest.cc
@@ -11,6 +11,7 @@
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/system_modal_container_layout_manager.h"
+#include "ash/wm/window_properties.h"
#include "ash/wm/window_util.h"
#include "ui/aura/client/focus_change_observer.h"
#include "ui/aura/client/focus_client.h"
@@ -25,6 +26,9 @@
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
+using aura::Window;
+using views::Widget;
+
namespace ash {
namespace {
@@ -319,5 +323,32 @@ TEST_F(RootWindowControllerTest, ModalContainerNotLoggedInLoggedIn) {
session_modal_widget->GetNativeView()));
}
+// Ensure a workspace with two windows reports immersive mode even if only
+// one has the property set.
+TEST_F(RootWindowControllerTest, ImmersiveMode) {
+ UpdateDisplay("600x600");
+ internal::RootWindowController* controller =
+ Shell::GetInstance()->GetPrimaryRootWindowController();
+
+ // Open a maximized window.
+ Widget* w1 = CreateTestWidget(gfx::Rect(0, 1, 250, 251));
+ w1->Maximize();
+
+ // Immersive mode off by default.
+ EXPECT_FALSE(controller->IsImmersiveMode());
+
+ // Enter immersive mode.
+ w1->GetNativeWindow()->SetProperty(ash::internal::kImmersiveModeKey, true);
+ EXPECT_TRUE(controller->IsImmersiveMode());
+
+ // Add a child, like a print window. Still in immersive mode.
+ Widget* w2 =
+ Widget::CreateWindowWithParentAndBounds(NULL,
+ w1->GetNativeWindow(),
+ gfx::Rect(0, 1, 150, 151));
+ w2->Show();
+ EXPECT_TRUE(controller->IsImmersiveMode());
+}
+
} // namespace test
} // namespace ash
diff --git a/ash/wm/shelf_layout_manager.cc b/ash/wm/shelf_layout_manager.cc
index a04a05f..85130c2 100644
--- a/ash/wm/shelf_layout_manager.cc
+++ b/ash/wm/shelf_layout_manager.cc
@@ -15,6 +15,7 @@
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
#include "ash/system/status_area_widget.h"
+#include "ash/wm/property_util.h"
#include "ash/wm/workspace_controller.h"
#include "ash/wm/workspace/workspace_animations.h"
#include "base/auto_reset.h"
@@ -257,6 +258,10 @@ void ShelfLayoutManager::UpdateVisibilityState() {
SetState(SHELF_VISIBLE);
} else if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS) {
SetState(SHELF_AUTO_HIDE);
+ } else if (GetRootWindowController(root_window_)->IsImmersiveMode()) {
+ // The user choosing immersive mode indicates he or she wants to maximize
+ // screen real-estate for content, so always auto-hide the shelf.
+ SetState(SHELF_AUTO_HIDE);
} else {
WorkspaceWindowState window_state(workspace_controller_->GetWindowState());
switch (window_state) {
diff --git a/ash/wm/window_properties.cc b/ash/wm/window_properties.cc
index 874f030..a9bc168 100644
--- a/ash/wm/window_properties.cc
+++ b/ash/wm/window_properties.cc
@@ -24,6 +24,7 @@ DEFINE_OWNED_WINDOW_PROPERTY_KEY(ash::internal::AlwaysOnTopController,
NULL);
DEFINE_WINDOW_PROPERTY_KEY(bool, kIgnoreSoloWindowFramePainterPolicy, false);
DEFINE_WINDOW_PROPERTY_KEY(bool, kIgnoredByShelfKey, false);
+DEFINE_WINDOW_PROPERTY_KEY(bool, kImmersiveModeKey, false);
DEFINE_WINDOW_PROPERTY_KEY(
ui::WindowShowState, kRestoreShowStateKey, ui::SHOW_STATE_DEFAULT);
DEFINE_WINDOW_PROPERTY_KEY(RootWindowController*,
diff --git a/ash/wm/window_properties.h b/ash/wm/window_properties.h
index 0136f86..026c72d 100644
--- a/ash/wm/window_properties.h
+++ b/ash/wm/window_properties.h
@@ -43,6 +43,9 @@ ASH_EXPORT extern const aura::WindowProperty<bool>* const
extern const aura::WindowProperty<bool>* const
kIgnoredByShelfKey;
+// True if this is a browser window in immersive mode.
+ASH_EXPORT extern const aura::WindowProperty<bool>* const kImmersiveModeKey;
+
// Used to remember the show state before the window was minimized.
extern const aura::WindowProperty<ui::WindowShowState>* const
kRestoreShowStateKey;
diff --git a/ash/wm/workspace/workspace_manager.cc b/ash/wm/workspace/workspace_manager.cc
index 0426d78..95c63f1 100644
--- a/ash/wm/workspace/workspace_manager.cc
+++ b/ash/wm/workspace/workspace_manager.cc
@@ -236,6 +236,10 @@ void WorkspaceManager::SetActiveWorkspaceByWindow(Window* window) {
}
}
+Window* WorkspaceManager::GetActiveWorkspaceWindow() {
+ return active_workspace_->window();
+}
+
Window* WorkspaceManager::GetParentForNewWindow(Window* window) {
// Try to put windows with transient parents in the same workspace as their
// transient parent.
diff --git a/ash/wm/workspace/workspace_manager.h b/ash/wm/workspace/workspace_manager.h
index 79bf0ac..08a50bbe 100644
--- a/ash/wm/workspace/workspace_manager.h
+++ b/ash/wm/workspace/workspace_manager.h
@@ -79,6 +79,9 @@ class ASH_EXPORT WorkspaceManager : public ash::ShellObserver {
// NULL or not contained in a workspace.
void SetActiveWorkspaceByWindow(aura::Window* window);
+ // Returns the container window for the active workspace, never NULL.
+ aura::Window* GetActiveWorkspaceWindow();
+
// Returns the parent for |window|. This is invoked from StackingController
// when a new Window is being added.
aura::Window* GetParentForNewWindow(aura::Window* window);
diff --git a/ash/wm/workspace_controller.cc b/ash/wm/workspace_controller.cc
index 3ca70d6..93099f9 100644
--- a/ash/wm/workspace_controller.cc
+++ b/ash/wm/workspace_controller.cc
@@ -46,11 +46,14 @@ void WorkspaceController::SetActiveWorkspaceByWindow(aura::Window* window) {
return workspace_manager_->SetActiveWorkspaceByWindow(window);
}
+aura::Window* WorkspaceController::GetActiveWorkspaceWindow() {
+ return workspace_manager_->GetActiveWorkspaceWindow();
+}
+
aura::Window* WorkspaceController::GetParentForNewWindow(aura::Window* window) {
return workspace_manager_->GetParentForNewWindow(window);
}
-
void WorkspaceController::DoInitialAnimation() {
workspace_manager_->DoInitialAnimation();
}
diff --git a/ash/wm/workspace_controller.h b/ash/wm/workspace_controller.h
index a77863a..ba82e09 100644
--- a/ash/wm/workspace_controller.h
+++ b/ash/wm/workspace_controller.h
@@ -40,7 +40,10 @@ class ASH_EXPORT WorkspaceController
// Sets the active workspace based on |window|.
void SetActiveWorkspaceByWindow(aura::Window* window);
- // See description in BaseWorkspaceManager::GetParentForNewWindow().
+ // Returns the container window for the active workspace, never NULL.
+ aura::Window* GetActiveWorkspaceWindow();
+
+ // See description in WorkspaceManager::GetParentForNewWindow().
aura::Window* GetParentForNewWindow(aura::Window* window);
// Starts the animation that occurs on first login.
diff --git a/chrome/browser/ui/ash/launcher/launcher_context_menu.cc b/chrome/browser/ui/ash/launcher/launcher_context_menu.cc
index 64317b7..9f28cb2 100644
--- a/chrome/browser/ui/ash/launcher/launcher_context_menu.cc
+++ b/chrome/browser/ui/ash/launcher/launcher_context_menu.cc
@@ -7,7 +7,9 @@
#include <string>
#include "ash/desktop_background/user_wallpaper_delegate.h"
+#include "ash/root_window_controller.h"
#include "ash/shell.h"
+#include "ash/wm/property_util.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "chrome/browser/extensions/context_menu_matcher.h"
@@ -126,8 +128,13 @@ void LauncherContextMenu::Init() {
}
}
}
- AddCheckItemWithStringId(
- MENU_AUTO_HIDE, IDS_AURA_LAUNCHER_CONTEXT_MENU_AUTO_HIDE);
+ // Don't show the auto-hide menu item while in immersive mode because the
+ // launcher always auto-hides in this mode and it's confusing when the
+ // preference appears not to apply.
+ if (!ash::GetRootWindowController(root_window_)->IsImmersiveMode()) {
+ AddCheckItemWithStringId(
+ MENU_AUTO_HIDE, IDS_AURA_LAUNCHER_CONTEXT_MENU_AUTO_HIDE);
+ }
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kShowLauncherAlignmentMenu)) {
AddSubMenuWithStringId(MENU_ALIGNMENT_MENU,
diff --git a/chrome/browser/ui/views/immersive_mode_controller.cc b/chrome/browser/ui/views/immersive_mode_controller.cc
index 93c0ff8..301dc25 100644
--- a/chrome/browser/ui/views/immersive_mode_controller.cc
+++ b/chrome/browser/ui/views/immersive_mode_controller.cc
@@ -17,6 +17,8 @@
#if defined(USE_ASH)
#include "ash/ash_switches.h"
+#include "ash/shell.h"
+#include "ash/wm/window_properties.h"
#include "base/command_line.h"
#endif
@@ -299,6 +301,15 @@ void ImmersiveModeController::SetEnabled(bool enabled) {
top_timer_.Stop();
}
+#if defined(USE_ASH)
+ native_window_->SetProperty(ash::internal::kImmersiveModeKey, enabled_);
+ // Ash on Windows may not have a shell.
+ if (ash::Shell::HasInstance()) {
+ // Shelf auto-hides in immersive mode.
+ ash::Shell::GetInstance()->UpdateShelfVisibility();
+ }
+#endif
+
// Always ensure tab strip is in correct state.
browser_view_->tabstrip()->SetImmersiveStyle(enabled_);
browser_view_->Layout();
diff --git a/chrome/browser/ui/views/immersive_mode_controller_browsertest.cc b/chrome/browser/ui/views/immersive_mode_controller_browsertest.cc
index 7eede6c..d24959a 100644
--- a/chrome/browser/ui/views/immersive_mode_controller_browsertest.cc
+++ b/chrome/browser/ui/views/immersive_mode_controller_browsertest.cc
@@ -12,6 +12,13 @@
#include "ui/gfx/rect.h"
#include "ui/views/view.h"
+#if defined(USE_ASH)
+#include "ash/root_window_controller.h"
+#include "ash/shelf_types.h"
+#include "ash/shell.h"
+#include "ash/wm/shelf_layout_manager.h"
+#endif
+
namespace {
// Returns the bounds of |view| in widget coordinates.
@@ -69,6 +76,9 @@ IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerTest, MAYBE_ImmersiveMode) {
EXPECT_FALSE(browser_view->tabstrip()->IsImmersiveStyle());
EXPECT_TRUE(browser_view->IsTabStripVisible());
EXPECT_TRUE(browser_view->IsToolbarVisible());
+ // Shelf hide triggered by enabling immersive mode eventually changes the
+ // widget bounds and causes a Layout(). Force it to happen early for test.
+ browser_view->parent()->Layout();
// Content area is still immediately below the tab indicators.
EXPECT_EQ(GetRectInWidget(browser_view).y() + Tab::GetImmersiveHeight(),
GetRectInWidget(contents_view).y());
@@ -113,6 +123,9 @@ IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerTest, MAYBE_ImmersiveMode) {
GetRectInWidget(contents_view).y());
controller->StartRevealForTest();
EXPECT_TRUE(browser_view->IsTabStripVisible());
+ // Shelf hide triggered by enabling immersive mode eventually changes the
+ // widget bounds and causes a Layout(). Force it to happen early for test.
+ browser_view->parent()->Layout();
EXPECT_EQ(GetRectInWidget(browser_view).y(),
GetRectInWidget(contents_view).y());
controller->SetEnabled(false);
@@ -167,3 +180,40 @@ IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerTest, MAYBE_ImmersiveMode) {
controller->SetEnabled(true);
controller->StartRevealForTest();
}
+
+#if defined(USE_ASH)
+// Test shelf auto-hide toggling behavior.
+IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerTest, ImmersiveShelf) {
+ ui::LayerAnimator::set_disable_animations_for_test(true);
+
+ BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
+ ImmersiveModeController* immersive_controller =
+ browser_view->immersive_mode_controller();
+ browser_view->GetWidget()->Maximize();
+
+ // Shelf is visible when the test starts.
+ ash::internal::ShelfLayoutManager* shelf =
+ ash::Shell::GetPrimaryRootWindowController()->shelf();
+ ASSERT_EQ(ash::SHELF_VISIBLE, shelf->visibility_state());
+
+ // Turning immersive mode on sets the shelf to auto-hide.
+ immersive_controller->SetEnabled(true);
+ EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
+
+ // Disabling immersive mode puts it back.
+ immersive_controller->SetEnabled(false);
+ EXPECT_EQ(ash::SHELF_VISIBLE, shelf->visibility_state());
+
+ // The user could toggle the launcher behavior.
+ shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
+ EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
+
+ // Enabling immersive mode keeps auto-hide.
+ immersive_controller->SetEnabled(true);
+ EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
+
+ // Disabling immersive mode maintains the user's auto-hide selection.
+ immersive_controller->SetEnabled(false);
+ EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
+}
+#endif // defined(OS_CHROMEOS)