diff options
-rw-r--r-- | ash/root_window_controller.cc | 10 | ||||
-rw-r--r-- | ash/root_window_controller.h | 4 | ||||
-rw-r--r-- | ash/root_window_controller_unittest.cc | 31 | ||||
-rw-r--r-- | ash/wm/shelf_layout_manager.cc | 5 | ||||
-rw-r--r-- | ash/wm/window_properties.cc | 1 | ||||
-rw-r--r-- | ash/wm/window_properties.h | 3 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_manager.cc | 4 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_manager.h | 3 | ||||
-rw-r--r-- | ash/wm/workspace_controller.cc | 5 | ||||
-rw-r--r-- | ash/wm/workspace_controller.h | 5 | ||||
-rw-r--r-- | chrome/browser/ui/ash/launcher/launcher_context_menu.cc | 11 | ||||
-rw-r--r-- | chrome/browser/ui/views/immersive_mode_controller.cc | 11 | ||||
-rw-r--r-- | chrome/browser/ui/views/immersive_mode_controller_browsertest.cc | 50 |
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) |