summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
Diffstat (limited to 'ash')
-rw-r--r--ash/root_window_controller.cc32
-rw-r--r--ash/root_window_controller.h5
-rw-r--r--ash/root_window_controller_unittest.cc38
-rw-r--r--ash/switchable_windows.cc11
-rw-r--r--ash/switchable_windows.h7
-rw-r--r--ash/wm/mru_window_tracker.cc11
-rw-r--r--ash/wm/overview/window_selector_controller.cc2
-rw-r--r--ash/wm/overview/window_selector_unittest.cc10
-rw-r--r--ash/wm/panels/panel_layout_manager.cc6
-rw-r--r--ash/wm/panels/panel_window_resizer_unittest.cc35
-rw-r--r--ash/wm/workspace/workspace_layout_manager.cc37
-rw-r--r--ash/wm/workspace/workspace_layout_manager.h2
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;