diff options
Diffstat (limited to 'ash')
-rw-r--r-- | ash/root_window_controller.cc | 32 | ||||
-rw-r--r-- | ash/root_window_controller.h | 5 | ||||
-rw-r--r-- | ash/root_window_controller_unittest.cc | 38 | ||||
-rw-r--r-- | ash/switchable_windows.cc | 11 | ||||
-rw-r--r-- | ash/switchable_windows.h | 7 | ||||
-rw-r--r-- | ash/wm/mru_window_tracker.cc | 11 | ||||
-rw-r--r-- | ash/wm/overview/window_selector_controller.cc | 2 | ||||
-rw-r--r-- | ash/wm/overview/window_selector_unittest.cc | 10 | ||||
-rw-r--r-- | ash/wm/panels/panel_layout_manager.cc | 6 | ||||
-rw-r--r-- | ash/wm/panels/panel_window_resizer_unittest.cc | 35 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_layout_manager.cc | 37 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_layout_manager.h | 2 |
12 files changed, 168 insertions, 28 deletions
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 6b813f8..e0d4406 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc @@ -24,6 +24,7 @@ #include "ash/shell_delegate.h" #include "ash/shell_factory.h" #include "ash/shell_window_ids.h" +#include "ash/switchable_windows.h" #include "ash/system/status_area_widget.h" #include "ash/system/tray/system_tray_delegate.h" #include "ash/touch/touch_hud_debug.h" @@ -570,16 +571,29 @@ void RootWindowController::UpdateShelfVisibility() { } const aura::Window* RootWindowController::GetWindowForFullscreenMode() const { - const aura::Window::Windows& windows = - GetContainer(kShellWindowId_DefaultContainer)->children(); const aura::Window* topmost_window = NULL; - for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); - iter != windows.rend(); ++iter) { - if (((*iter)->type() == ui::wm::WINDOW_TYPE_NORMAL || - (*iter)->type() == ui::wm::WINDOW_TYPE_PANEL) && - (*iter)->layer()->GetTargetVisibility()) { - topmost_window = *iter; - break; + const aura::Window* active_window = wm::GetActiveWindow(); + if (active_window && active_window->GetRootWindow() == root_window() && + IsSwitchableContainer(active_window->parent())) { + // Use the active window when it is on the current root window to determine + // the fullscreen state to allow temporarily using a panel or docked window + // (which are always above the default container) while a fullscreen + // window is open. We only use the active window when in a switchable + // container as the launcher should not exit fullscreen mode. + topmost_window = active_window; + } else { + // Otherwise, use the topmost window on the root window's default container + // when there is no active window on this root window. + const aura::Window::Windows& windows = + GetContainer(kShellWindowId_DefaultContainer)->children(); + for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); + iter != windows.rend(); ++iter) { + if (((*iter)->type() == ui::wm::WINDOW_TYPE_NORMAL || + (*iter)->type() == ui::wm::WINDOW_TYPE_PANEL) && + (*iter)->layer()->GetTargetVisibility()) { + topmost_window = *iter; + break; + } } } while (topmost_window) { diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h index b6a1a29..8ec271d 100644 --- a/ash/root_window_controller.h +++ b/ash/root_window_controller.h @@ -112,7 +112,12 @@ class ASH_EXPORT RootWindowController : public ShellObserver { virtual ~RootWindowController(); aura::Window* root_window() { return dispatcher()->window(); } + const aura::Window* root_window() const { return dispatcher()->window(); } + aura::WindowEventDispatcher* dispatcher() { return dispatcher_.get(); } + const aura::WindowEventDispatcher* dispatcher() const { + return dispatcher_.get(); + } RootWindowLayoutManager* root_window_layout() { return root_window_layout_; } diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc index 9835cc5..407f9b9 100644 --- a/ash/root_window_controller_unittest.cc +++ b/ash/root_window_controller_unittest.cc @@ -458,6 +458,44 @@ TEST_F(RootWindowControllerTest, GetWindowForFullscreenMode) { EXPECT_EQ(NULL, controller->GetWindowForFullscreenMode()); } +TEST_F(RootWindowControllerTest, MultipleDisplaysGetWindowForFullscreenMode) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("600x600,600x600"); + Shell::RootWindowControllerList controllers = + Shell::GetInstance()->GetAllRootWindowControllers(); + + Widget* w1 = CreateTestWidget(gfx::Rect(0, 0, 100, 100)); + w1->Maximize(); + Widget* w2 = CreateTestWidget(gfx::Rect(0, 0, 100, 100)); + w2->SetFullscreen(true); + Widget* w3 = CreateTestWidget(gfx::Rect(600, 0, 100, 100)); + + EXPECT_EQ(w1->GetNativeWindow()->GetRootWindow(), + controllers[0]->root_window()); + EXPECT_EQ(w2->GetNativeWindow()->GetRootWindow(), + controllers[0]->root_window()); + EXPECT_EQ(w3->GetNativeWindow()->GetRootWindow(), + controllers[1]->root_window()); + + w1->Activate(); + EXPECT_EQ(NULL, controllers[0]->GetWindowForFullscreenMode()); + EXPECT_EQ(NULL, controllers[1]->GetWindowForFullscreenMode()); + + w2->Activate(); + EXPECT_EQ(w2->GetNativeWindow(), + controllers[0]->GetWindowForFullscreenMode()); + EXPECT_EQ(NULL, controllers[1]->GetWindowForFullscreenMode()); + + // Verify that the first root window controller remains in fullscreen mode + // when a window on the other display is activated. + w3->Activate(); + EXPECT_EQ(w2->GetNativeWindow(), + controllers[0]->GetWindowForFullscreenMode()); + EXPECT_EQ(NULL, controllers[1]->GetWindowForFullscreenMode()); +} + // Test that user session window can't be focused if user session blocked by // some overlapping UI. TEST_F(RootWindowControllerTest, FocusBlockedWindow) { diff --git a/ash/switchable_windows.cc b/ash/switchable_windows.cc index 86c31f6..352599b 100644 --- a/ash/switchable_windows.cc +++ b/ash/switchable_windows.cc @@ -5,6 +5,7 @@ #include "ash/switchable_windows.h" #include "ash/shell_window_ids.h" +#include "ui/aura/window.h" namespace ash { @@ -17,4 +18,14 @@ const int kSwitchableWindowContainerIds[] = { const size_t kSwitchableWindowContainerIdsLength = arraysize(kSwitchableWindowContainerIds); +bool IsSwitchableContainer(const aura::Window* window) { + if (!window) + return false; + for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { + if (window->id() == kSwitchableWindowContainerIds[i]) + return true; + } + return false; +} + } // namespace ash diff --git a/ash/switchable_windows.h b/ash/switchable_windows.h index 305921b..b0b4ee0 100644 --- a/ash/switchable_windows.h +++ b/ash/switchable_windows.h @@ -8,6 +8,10 @@ #include "ash/ash_export.h" #include "base/macros.h" +namespace aura { + class Window; +} + namespace ash { // List of containers which contain windows that can be switched via Alt+Tab to. @@ -16,6 +20,9 @@ ASH_EXPORT extern const int kSwitchableWindowContainerIds[]; // The number of elements in kSwitchableWindowContainerIds. ASH_EXPORT extern const size_t kSwitchableWindowContainerIdsLength; +// Returns true if |window| is a container for windows which can be switched to. +ASH_EXPORT bool IsSwitchableContainer(const aura::Window* window); + } // namespace ash #endif // ASH_SWITCHABLE_WINDOWS_H_ diff --git a/ash/wm/mru_window_tracker.cc b/ash/wm/mru_window_tracker.cc index 3049517..c0fe9eb 100644 --- a/ash/wm/mru_window_tracker.cc +++ b/ash/wm/mru_window_tracker.cc @@ -46,17 +46,6 @@ void AddDraggedWindows(aura::Window* root, } } -// Returns true if |window| is a container whose windows can be cycled to. -bool IsSwitchableContainer(aura::Window* window) { - if (!window) - return false; - for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { - if (window->id() == kSwitchableWindowContainerIds[i]) - return true; - } - return false; -} - // Returns whether |w1| should be considered less recently used than |w2|. This // is used for a stable sort to move minimized windows to the LRU end of the // list. diff --git a/ash/wm/overview/window_selector_controller.cc b/ash/wm/overview/window_selector_controller.cc index e80490e..25419c4 100644 --- a/ash/wm/overview/window_selector_controller.cc +++ b/ash/wm/overview/window_selector_controller.cc @@ -71,8 +71,8 @@ bool WindowSelectorController::IsSelecting() { } void WindowSelectorController::OnWindowSelected(aura::Window* window) { - window_selector_.reset(); wm::ActivateWindow(window); + window_selector_.reset(); last_selection_time_ = base::Time::Now(); Shell::GetInstance()->mru_window_tracker()->SetIgnoreActivations(false); } diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index 0bdeb82..c200c38 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc @@ -315,6 +315,16 @@ TEST_F(WindowSelectorTest, FullscreenWindow) { ToggleOverview(); ClickWindow(window2.get()); EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen()); + + // Verify that selecting the panel will make it visible. + // TODO(flackr): Click on panel rather than cycle to it when + // clicking on panels is fixed, see http://crbug.com/339834. + Cycle(WindowSelector::FORWARD); + Cycle(WindowSelector::FORWARD); + StopCycling(); + EXPECT_TRUE(wm::GetWindowState(panel1.get())->IsActive()); + EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen()); + EXPECT_TRUE(panel1->IsVisible()); } // Tests that the shelf dimming state is removed while in overview and restored diff --git a/ash/wm/panels/panel_layout_manager.cc b/ash/wm/panels/panel_layout_manager.cc index f4b0bde..274c8f2 100644 --- a/ash/wm/panels/panel_layout_manager.cc +++ b/ash/wm/panels/panel_layout_manager.cc @@ -608,8 +608,10 @@ void PanelLayoutManager::Relayout() { } // If the shelf is currently hidden (full-screen mode), minimize panel until - // full-screen mode is exited. - if (restore_windows_on_shelf_visible_) { + // full-screen mode is exited. When a panel is dragged from another display + // the shelf state does not update before the panel is added so we exclude + // the dragged panel. + if (panel != dragged_panel_ && restore_windows_on_shelf_visible_) { wm::GetWindowState(panel)->Minimize(); restore_windows_on_shelf_visible_->Add(panel); continue; diff --git a/ash/wm/panels/panel_window_resizer_unittest.cc b/ash/wm/panels/panel_window_resizer_unittest.cc index 213708d..69e149e 100644 --- a/ash/wm/panels/panel_window_resizer_unittest.cc +++ b/ash/wm/panels/panel_window_resizer_unittest.cc @@ -400,6 +400,41 @@ TEST_F(PanelWindowResizerTest, AttachToSecondDisplay) { EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id()); } +TEST_F(PanelWindowResizerTest, AttachToSecondFullscreenDisplay) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("600x400,600x600"); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + scoped_ptr<aura::Window> window( + CreatePanelWindow(gfx::Point(0, 0))); + scoped_ptr<aura::Window> fullscreen( + CreateTestWindowInShellWithBounds(gfx::Rect(600, 0, 101, 101))); + wm::GetWindowState(fullscreen.get())->Activate(); + wm::GetWindowState(fullscreen.get())->ToggleFullscreen(); + EXPECT_TRUE(wm::GetWindowState(fullscreen.get())->IsFullscreen()); + + gfx::Rect initial_bounds = window->GetBoundsInScreen(); + EXPECT_EQ(root_windows[0], window->GetRootWindow()); + + // Activate and drag the window to the other display's launcher. + wm::GetWindowState(window.get())->Activate(); + DragStart(window.get()); + DragMove(500, 250); + EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x()); + EXPECT_GT(window->GetBoundsInScreen().y(), + initial_bounds.y() + 200); + DragEnd(); + + // When dropped should move to second display's panel container. + EXPECT_EQ(root_windows[1], window->GetRootWindow()); + EXPECT_TRUE(wm::GetWindowState(window.get())->panel_attached()); + EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id()); + EXPECT_TRUE(window->IsVisible()); + EXPECT_TRUE(wm::GetWindowState(window.get())->IsActive()); + EXPECT_EQ(initial_bounds.y() + 200, window->GetBoundsInScreen().y()); +} + TEST_F(PanelWindowResizerTest, RevertDragRestoresAttachment) { scoped_ptr<aura::Window> window( CreatePanelWindow(gfx::Point(0, 0))); diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc index a5ca0a0..7308b33 100644 --- a/ash/wm/workspace/workspace_layout_manager.cc +++ b/ash/wm/workspace/workspace_layout_manager.cc @@ -94,13 +94,11 @@ void WorkspaceLayoutManager::OnChildWindowVisibilityChanged(Window* child, if (visible && window_state->IsMinimized()) window_state->Unminimize(); - if (child->TargetVisibility()) { + if (child->TargetVisibility()) WindowPositioner::RearrangeVisibleWindowOnShow(child); - } else { - if (wm::GetWindowState(child)->IsFullscreen()) - UpdateFullscreenState(); + else WindowPositioner::RearrangeVisibleWindowOnHideOrRemove(child); - } + UpdateFullscreenState(); UpdateShelfVisibility(); } @@ -126,6 +124,26 @@ void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() { ////////////////////////////////////////////////////////////////////////////// // WorkspaceLayoutManager, aura::WindowObserver implementation: +void WorkspaceLayoutManager::OnWindowHierarchyChanged( + const WindowObserver::HierarchyChangeParams& params) { + if (!wm::GetWindowState(params.target)->IsActive()) + return; + // If the window is already tracked by the workspace this update would be + // redundant as the fullscreen and shelf state would have been handled in + // OnWindowAddedToLayout. + if (windows_.find(params.target) != windows_.end()) + return; + + // If the active window has moved to this root window then update the + // fullscreen state. + // TODO(flackr): Track the active window leaving this root window and update + // the fullscreen state accordingly. + if (params.new_parent && params.new_parent->GetRootWindow() == root_window_) { + UpdateFullscreenState(); + UpdateShelfVisibility(); + } +} + void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window, const void* key, intptr_t old) { @@ -167,6 +185,8 @@ void WorkspaceLayoutManager::OnWindowActivated(aura::Window* gained_active, window_state->Unminimize(); DCHECK(!window_state->IsMinimized()); } + UpdateFullscreenState(); + UpdateShelfVisibility(); } ////////////////////////////////////////////////////////////////////////////// @@ -220,6 +240,13 @@ void WorkspaceLayoutManager::UpdateShelfVisibility() { } void WorkspaceLayoutManager::UpdateFullscreenState() { + // TODO(flackr): The fullscreen state is currently tracked per workspace + // but the shell notification implies a per root window state. Currently + // only windows in the default workspace container will go fullscreen but + // this should really be tracked by the RootWindowController since + // technically any container could get a fullscreen window. + if (!shelf_) + return; bool is_fullscreen = GetRootWindowController( window_->GetRootWindow())->GetWindowForFullscreenMode() != NULL; if (is_fullscreen != is_fullscreen_) { diff --git a/ash/wm/workspace/workspace_layout_manager.h b/ash/wm/workspace/workspace_layout_manager.h index ffaa10a..45a8e95 100644 --- a/ash/wm/workspace/workspace_layout_manager.h +++ b/ash/wm/workspace/workspace_layout_manager.h @@ -63,6 +63,8 @@ class ASH_EXPORT WorkspaceLayoutManager virtual void OnDisplayWorkAreaInsetsChanged() OVERRIDE; // Overriden from WindowObserver: + virtual void OnWindowHierarchyChanged( + const WindowObserver::HierarchyChangeParams& params) OVERRIDE; virtual void OnWindowPropertyChanged(aura::Window* window, const void* key, intptr_t old) OVERRIDE; |