Commit 95058572 authored by sky@chromium.org's avatar sky@chromium.org

Initial crack at new workspace behavior. Each workspace now has its

own window. This complicates usage of shell window ids a bit.

I need to sort out animations (I've disabled them for the moment when
this is enabled).

BUG=137342
TEST=none
R=ben@chromium.org

Review URL: https://chromiumcodereview.appspot.com/10830365

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152322 0039d316-1c4b-4281-b951-d872f2087c98
parent 103c6801
...@@ -346,12 +346,16 @@ ...@@ -346,12 +346,16 @@
'wm/workspace/snap_types.h', 'wm/workspace/snap_types.h',
'wm/workspace/workspace.cc', 'wm/workspace/workspace.cc',
'wm/workspace/workspace.h', 'wm/workspace/workspace.h',
'wm/workspace/workspace2.cc',
'wm/workspace/workspace2.h',
'wm/workspace/workspace_event_filter.cc', 'wm/workspace/workspace_event_filter.cc',
'wm/workspace/workspace_event_filter.h', 'wm/workspace/workspace_event_filter.h',
'wm/workspace/workspace_layout_manager.cc', 'wm/workspace/workspace_layout_manager.cc',
'wm/workspace/workspace_layout_manager.h', 'wm/workspace/workspace_layout_manager.h',
'wm/workspace/workspace_manager.cc', 'wm/workspace/workspace_manager.cc',
'wm/workspace/workspace_manager.h', 'wm/workspace/workspace_manager.h',
'wm/workspace/workspace_manager2.cc',
'wm/workspace/workspace_manager2.h',
'wm/workspace/workspace_types.h', 'wm/workspace/workspace_types.h',
'wm/workspace/workspace_window_resizer.cc', 'wm/workspace/workspace_window_resizer.cc',
'wm/workspace/workspace_window_resizer.h', 'wm/workspace/workspace_window_resizer.h',
...@@ -489,6 +493,7 @@ ...@@ -489,6 +493,7 @@
'wm/workspace/workspace_event_filter_test_helper.h', 'wm/workspace/workspace_event_filter_test_helper.h',
'wm/workspace/workspace_event_filter_unittest.cc', 'wm/workspace/workspace_event_filter_unittest.cc',
'wm/workspace/workspace_manager_unittest.cc', 'wm/workspace/workspace_manager_unittest.cc',
'wm/workspace/workspace_manager2_unittest.cc',
'wm/workspace/workspace_window_resizer_unittest.cc', 'wm/workspace/workspace_window_resizer_unittest.cc',
], ],
'conditions': [ 'conditions': [
......
...@@ -13,7 +13,9 @@ const char kAshDebugShortcuts[] = "ash-debug-shortcuts"; ...@@ -13,7 +13,9 @@ const char kAshDebugShortcuts[] = "ash-debug-shortcuts";
// Enables the Oak tree viewer. // Enables the Oak tree viewer.
const char kAshEnableOak[] = "ash-enable-oak"; const char kAshEnableOak[] = "ash-enable-oak";
// Disables extended desktop. // Enables Workspace2.
const char kAshEnableWorkspace2[] = "ash-enable-workspace2";
const char kAshExtendedDesktopDisabled[] = "ash-extended-desktop-disabled"; const char kAshExtendedDesktopDisabled[] = "ash-extended-desktop-disabled";
// Disable using Ash notifications. // Disable using Ash notifications.
......
...@@ -17,6 +17,7 @@ namespace switches { ...@@ -17,6 +17,7 @@ namespace switches {
// Please keep alphabetized. // Please keep alphabetized.
ASH_EXPORT extern const char kAshDebugShortcuts[]; ASH_EXPORT extern const char kAshDebugShortcuts[];
ASH_EXPORT extern const char kAshEnableOak[]; ASH_EXPORT extern const char kAshEnableOak[];
ASH_EXPORT extern const char kAshEnableWorkspace2[];
ASH_EXPORT extern const char kAshExtendedDesktopDisabled[]; ASH_EXPORT extern const char kAshExtendedDesktopDisabled[];
ASH_EXPORT extern const char kAshNotifyDisabled[]; ASH_EXPORT extern const char kAshNotifyDisabled[];
ASH_EXPORT extern const char kAshTouchHud[]; ASH_EXPORT extern const char kAshTouchHud[];
......
...@@ -5,10 +5,12 @@ ...@@ -5,10 +5,12 @@
#include "ash/display/screen_position_controller.h" #include "ash/display/screen_position_controller.h"
#include "ash/display/display_controller.h" #include "ash/display/display_controller.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/shell_window_ids.h" #include "ash/shell_window_ids.h"
#include "ash/wm/system_modal_container_layout_manager.h" #include "ash/wm/system_modal_container_layout_manager.h"
#include "ash/wm/window_properties.h" #include "ash/wm/window_properties.h"
#include "ash/wm/workspace_controller.h"
#include "ui/aura/client/activation_client.h" #include "ui/aura/client/activation_client.h"
#include "ui/aura/client/capture_client.h" #include "ui/aura/client/capture_client.h"
#include "ui/aura/client/stacking_client.h" #include "ui/aura/client/stacking_client.h"
...@@ -97,8 +99,7 @@ void ScreenPositionController::SetBounds(aura::Window* window, ...@@ -97,8 +99,7 @@ void ScreenPositionController::SetBounds(aura::Window* window,
aura::Window* dst_container = NULL; aura::Window* dst_container = NULL;
if (dst_root != window->GetRootWindow()) { if (dst_root != window->GetRootWindow()) {
int container_id = window->parent()->id(); int container_id = window->parent()->id();
// All containers that uses screen coordinates must have valid // All containers that uses screen coordinates must have valid window ids.
// window ids.
DCHECK_GE(container_id, 0); DCHECK_GE(container_id, 0);
// Don't move modal screen. // Don't move modal screen.
if (!SystemModalContainerLayoutManager::IsModalScreen(window)) if (!SystemModalContainerLayoutManager::IsModalScreen(window))
...@@ -117,6 +118,12 @@ void ScreenPositionController::SetBounds(aura::Window* window, ...@@ -117,6 +118,12 @@ void ScreenPositionController::SetBounds(aura::Window* window,
if (active && focused != active) if (active && focused != active)
tracker.Add(active); tracker.Add(active);
if (dst_container->id() == kShellWindowId_WorkspaceContainer) {
dst_container =
GetRootWindowController(dst_root)->workspace_controller()->
GetParentForNewWindow(window);
}
dst_container->AddChild(window); dst_container->AddChild(window);
MoveAllTransientChildrenToNewRoot(display, window); MoveAllTransientChildrenToNewRoot(display, window);
......
...@@ -50,19 +50,62 @@ aura::Window* CreateContainer(int window_id, ...@@ -50,19 +50,62 @@ aura::Window* CreateContainer(int window_id,
return container; return container;
} }
void MoveAllWindows(aura::RootWindow* src, // Returns all the children of the workspace windows, eg the standard top-level
aura::RootWindow* dst) { // windows.
// Windows move only from secondary displays to the primary std::vector<aura::Window*> GetWorkspaceWindows(aura::RootWindow* root) {
// display, so no need to move windows in the containers that are using aura::Window;
// available only in the primary display (launcher, panels etc)
std::vector<Window*> windows;
Window* container = Shell::GetContainer(
root, internal::kShellWindowId_DefaultContainer);
for (Window::Windows::const_reverse_iterator i =
container->children().rbegin();
i != container->children().rend(); ++i) {
Window* workspace_window = *i;
if (workspace_window->id() == internal::kShellWindowId_WorkspaceContainer) {
windows.insert(windows.end(), workspace_window->children().begin(),
workspace_window->children().end());
}
}
return windows;
}
// Reparents |window| to |new_parent|.
void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
// Update the restore bounds to make it relative to the display.
gfx::Rect restore_bounds(GetRestoreBoundsInParent(window));
new_parent->AddChild(window);
if (!restore_bounds.IsEmpty())
SetRestoreBoundsInParent(window, restore_bounds);
}
// Reparents the appropriate set of windows from |src| to |dst|.
void ReparentAllWindows(aura::RootWindow* src, aura::RootWindow* dst) {
// Set of windows to move.
const int kContainerIdsToMove[] = { const int kContainerIdsToMove[] = {
internal::kShellWindowId_DefaultContainer, internal::kShellWindowId_DefaultContainer,
internal::kShellWindowId_AlwaysOnTopContainer, internal::kShellWindowId_AlwaysOnTopContainer,
internal::kShellWindowId_SystemModalContainer, internal::kShellWindowId_SystemModalContainer,
internal::kShellWindowId_LockSystemModalContainer, internal::kShellWindowId_LockSystemModalContainer,
}; };
// For Workspace2 we need to manually reparent the windows. This way
// Workspace2 can move the windows to the appropriate workspace.
if (internal::WorkspaceController::IsWorkspace2Enabled()) {
std::vector<aura::Window*> windows(GetWorkspaceWindows(src));
internal::WorkspaceController* workspace_controller =
GetRootWindowController(dst)->workspace_controller();
for (size_t i = 0; i < windows.size(); ++i) {
aura::Window* new_parent =
workspace_controller->GetParentForNewWindow(windows[i]);
ReparentWindow(windows[i], new_parent);
}
}
for (size_t i = 0; i < arraysize(kContainerIdsToMove); i++) { for (size_t i = 0; i < arraysize(kContainerIdsToMove); i++) {
int id = kContainerIdsToMove[i]; int id = kContainerIdsToMove[i];
if (id == internal::kShellWindowId_DefaultContainer &&
internal::WorkspaceController::IsWorkspace2Enabled())
continue;
aura::Window* src_container = Shell::GetContainer(src, id); aura::Window* src_container = Shell::GetContainer(src, id);
aura::Window* dst_container = Shell::GetContainer(dst, id); aura::Window* dst_container = Shell::GetContainer(dst, id);
aura::Window::Windows children = src_container->children(); aura::Window::Windows children = src_container->children();
...@@ -73,11 +116,7 @@ void MoveAllWindows(aura::RootWindow* src, ...@@ -73,11 +116,7 @@ void MoveAllWindows(aura::RootWindow* src,
if (internal::SystemModalContainerLayoutManager::IsModalScreen(window)) if (internal::SystemModalContainerLayoutManager::IsModalScreen(window))
continue; continue;
// Update the restore bounds to make it relative to the display. ReparentWindow(window, dst_container);
gfx::Rect restore_bounds(GetRestoreBoundsInParent(window));
dst_container->AddChild(window);
if (!restore_bounds.IsEmpty())
SetRestoreBoundsInParent(window, restore_bounds);
} }
} }
} }
...@@ -319,7 +358,7 @@ void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) { ...@@ -319,7 +358,7 @@ void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
if (active && focused != active) if (active && focused != active)
tracker.Add(active); tracker.Add(active);
MoveAllWindows(root_window_.get(), dst); ReparentAllWindows(root_window_.get(), dst);
// Restore focused or active window if it's still alive. // Restore focused or active window if it's still alive.
if (focused && tracker.Contains(focused) && dst->Contains(focused)) { if (focused && tracker.Contains(focused) && dst->Contains(focused)) {
......
...@@ -13,17 +13,45 @@ ...@@ -13,17 +13,45 @@
namespace ash { namespace ash {
namespace shell { namespace shell {
class WindowWatcher::WorkspaceWindowWatcher : public aura::WindowObserver {
public:
explicit WorkspaceWindowWatcher(WindowWatcher* watcher) : watcher_(watcher) {
watcher_->window_->AddObserver(this);
for (size_t i = 0; i < watcher_->window_->children().size(); ++i)
watcher_->window_->children()[i]->AddObserver(watcher_);
}
virtual ~WorkspaceWindowWatcher() {
watcher_->window_->RemoveObserver(this);
for (size_t i = 0; i < watcher_->window_->children().size(); ++i)
watcher_->window_->children()[i]->RemoveObserver(watcher_);
}
virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE {
new_window->AddObserver(watcher_);
}
virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE {
DCHECK(window->children().empty());
window->RemoveObserver(watcher_);
}
private:
WindowWatcher* watcher_;
DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowWatcher);
};
WindowWatcher::WindowWatcher() WindowWatcher::WindowWatcher()
: window_(ash::Shell::GetInstance()->launcher()->window_container()), : window_(ash::Shell::GetInstance()->launcher()->window_container()),
panel_container_(ash::Shell::GetContainer( panel_container_(ash::Shell::GetContainer(
Shell::GetPrimaryRootWindow(), Shell::GetPrimaryRootWindow(),
internal::kShellWindowId_PanelContainer)) { internal::kShellWindowId_PanelContainer)) {
window_->AddObserver(this); workspace_window_watcher_.reset(new WorkspaceWindowWatcher(this));
panel_container_->AddObserver(this); panel_container_->AddObserver(this);
} }
WindowWatcher::~WindowWatcher() { WindowWatcher::~WindowWatcher() {
window_->RemoveObserver(this);
panel_container_->RemoveObserver(this); panel_container_->RemoveObserver(this);
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "ash/launcher/launcher_types.h" #include "ash/launcher/launcher_types.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
namespace aura { namespace aura {
...@@ -19,6 +20,8 @@ class Window; ...@@ -19,6 +20,8 @@ class Window;
namespace ash { namespace ash {
namespace shell { namespace shell {
// TODO(sky): fix this class, its a bit broke with workspace2.
// WindowWatcher is responsible for listening for newly created windows and // WindowWatcher is responsible for listening for newly created windows and
// creating items on the Launcher for them. // creating items on the Launcher for them.
class WindowWatcher : public aura::WindowObserver { class WindowWatcher : public aura::WindowObserver {
...@@ -34,6 +37,8 @@ class WindowWatcher : public aura::WindowObserver { ...@@ -34,6 +37,8 @@ class WindowWatcher : public aura::WindowObserver {
virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE; virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE;
private: private:
class WorkspaceWindowWatcher;
typedef std::map<ash::LauncherID, aura::Window*> IDToWindow; typedef std::map<ash::LauncherID, aura::Window*> IDToWindow;
// Window watching for newly created windows to be added to. // Window watching for newly created windows to be added to.
...@@ -44,6 +49,8 @@ class WindowWatcher : public aura::WindowObserver { ...@@ -44,6 +49,8 @@ class WindowWatcher : public aura::WindowObserver {
// Maps from window to the id we gave it. // Maps from window to the id we gave it.
IDToWindow id_to_window_; IDToWindow id_to_window_;
scoped_ptr<WorkspaceWindowWatcher> workspace_window_watcher_;
DISALLOW_COPY_AND_ASSIGN(WindowWatcher); DISALLOW_COPY_AND_ASSIGN(WindowWatcher);
}; };
......
...@@ -34,54 +34,63 @@ const int kShellWindowId_UnparentedControlContainer = 3; ...@@ -34,54 +34,63 @@ const int kShellWindowId_UnparentedControlContainer = 3;
// The desktop background window. // The desktop background window.
const int kShellWindowId_DesktopBackgroundContainer = 4; const int kShellWindowId_DesktopBackgroundContainer = 4;
// TODO(sky): rename kShellWindowId_DefaultContainer when Workspace2 is the
// default.
// The container for standard top-level windows. // The container for standard top-level windows.
// WARNING: when Workspace2 is enabled the only children of
// kShellWindowId_DefaultContainer are kShellWindowId_WorkspaceContainer.
const int kShellWindowId_DefaultContainer = 5; const int kShellWindowId_DefaultContainer = 5;
// Used by Worskpace2 for each workspace. Contains standard top-level windows.
// WARNING: there may be more than one container with this id.
const int kShellWindowId_WorkspaceContainer = 6;
// The container for top-level windows with the 'always-on-top' flag set. // The container for top-level windows with the 'always-on-top' flag set.
const int kShellWindowId_AlwaysOnTopContainer = 6; const int kShellWindowId_AlwaysOnTopContainer = 7;
// The container for panel windows. // The container for panel windows.
const int kShellWindowId_PanelContainer = 7; const int kShellWindowId_PanelContainer = 8;
// The container for the launcher. // The container for the launcher.
const int kShellWindowId_LauncherContainer = 8; const int kShellWindowId_LauncherContainer = 9;
// The container for the app list. // The container for the app list.
const int kShellWindowId_AppListContainer = 9; const int kShellWindowId_AppListContainer = 10;
// The container for user-specific modal windows. // The container for user-specific modal windows.
const int kShellWindowId_SystemModalContainer = 10; const int kShellWindowId_SystemModalContainer = 11;
// The container for input method components such like candidate windows. They // The container for input method components such like candidate windows. They
// are almost panels but have no activations/focus, and they should appear over // are almost panels but have no activations/focus, and they should appear over
// the AppList and SystemModal dialogs. // the AppList and SystemModal dialogs.
const int kShellWindowId_InputMethodContainer = 11; const int kShellWindowId_InputMethodContainer = 12;
// The container for the lock screen background. // The container for the lock screen background.
const int kShellWindowId_LockScreenBackgroundContainer = 12; const int kShellWindowId_LockScreenBackgroundContainer = 13;
// The container for the lock screen. // The container for the lock screen.
const int kShellWindowId_LockScreenContainer = 13; const int kShellWindowId_LockScreenContainer = 14;
// The container for the lock screen modal windows. // The container for the lock screen modal windows.
const int kShellWindowId_LockSystemModalContainer = 14; const int kShellWindowId_LockSystemModalContainer = 15;
// The container for the status area. // The container for the status area.
const int kShellWindowId_StatusContainer = 15; const int kShellWindowId_StatusContainer = 16;
// The container for menus. // The container for menus.
const int kShellWindowId_MenuContainer = 16; const int kShellWindowId_MenuContainer = 17;
// The container for drag/drop images and tooltips. // The container for drag/drop images and tooltips.
const int kShellWindowId_DragImageAndTooltipContainer = 17; const int kShellWindowId_DragImageAndTooltipContainer = 18;
// The container for bubbles briefly overlaid onscreen to show settings changes // The container for bubbles briefly overlaid onscreen to show settings changes
// (volume, brightness, etc.). // (volume, brightness, etc.).
const int kShellWindowId_SettingBubbleContainer = 18; const int kShellWindowId_SettingBubbleContainer = 19;
// The container for special components overlaid onscreen, such as the // The container for special components overlaid onscreen, such as the
// region selector for partial screenshots. // region selector for partial screenshots.
const int kShellWindowId_OverlayContainer = 19; const int kShellWindowId_OverlayContainer = 20;
} // namespace internal } // namespace internal
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
#include "ash/wm/activation_controller.h" #include "ash/wm/activation_controller.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/shell_window_ids.h" #include "ash/shell_window_ids.h"
#include "ash/wm/property_util.h"
#include "ash/wm/window_modality_controller.h" #include "ash/wm/window_modality_controller.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
#include "ash/wm/workspace_controller.h"
#include "base/auto_reset.h" #include "base/auto_reset.h"
#include "ui/aura/client/activation_change_observer.h" #include "ui/aura/client/activation_change_observer.h"
#include "ui/aura/client/activation_delegate.h" #include "ui/aura/client/activation_delegate.h"
...@@ -33,6 +36,7 @@ const int kWindowContainerIds[] = { ...@@ -33,6 +36,7 @@ const int kWindowContainerIds[] = {
kShellWindowId_SystemModalContainer, kShellWindowId_SystemModalContainer,
kShellWindowId_AlwaysOnTopContainer, kShellWindowId_AlwaysOnTopContainer,
kShellWindowId_AppListContainer, kShellWindowId_AppListContainer,
// TODO(sky): defaultcontainer shouldn't be in the list with workspace2.
kShellWindowId_DefaultContainer, kShellWindowId_DefaultContainer,
// Panel, launcher and status are intentionally checked after other // Panel, launcher and status are intentionally checked after other
...@@ -46,9 +50,18 @@ const int kWindowContainerIds[] = { ...@@ -46,9 +50,18 @@ const int kWindowContainerIds[] = {
// Returns true if children of |window| can be activated. // Returns true if children of |window| can be activated.
// These are the only containers in which windows can receive focus. // These are the only containers in which windows can receive focus.
bool SupportsChildActivation(aura::Window* window) { bool SupportsChildActivation(aura::Window* window) {
// TODO(sky): straighten this out when workspace2 is the default.
// kShellWindowId_WorkspaceContainer isn't in |kWindowContainerIds| since it
// needs to be special cased in GetTopmostWindowToActivate().
if (window->id() == kShellWindowId_WorkspaceContainer)
return true;
for (size_t i = 0; i < arraysize(kWindowContainerIds); i++) { for (size_t i = 0; i < arraysize(kWindowContainerIds); i++) {
if (window->id() == kWindowContainerIds[i]) if (window->id() == kWindowContainerIds[i] &&
(window->id() != kShellWindowId_DefaultContainer ||
!WorkspaceController::IsWorkspace2Enabled())) {
return true; return true;
}
} }
return false; return false;
} }
...@@ -78,7 +91,9 @@ enum ActivateVisibilityType { ...@@ -78,7 +91,9 @@ enum ActivateVisibilityType {
bool VisibilityMatches(aura::Window* window, ActivateVisibilityType type) { bool VisibilityMatches(aura::Window* window, ActivateVisibilityType type) {
bool visible = (type == CURRENT_VISIBILITY) ? window->IsVisible() : bool visible = (type == CURRENT_VISIBILITY) ? window->IsVisible() :
window->TargetVisibility(); window->TargetVisibility();
return visible || wm::IsWindowMinimized(window); return visible || wm::IsWindowMinimized(window) ||
(window->TargetVisibility() &&
window->parent()->id() == kShellWindowId_WorkspaceContainer);
} }
// Returns true if |window| can be activated or deactivated. // Returns true if |window| can be activated or deactivated.
...@@ -250,6 +265,19 @@ void ActivationController::ActivateWindowWithEvent(aura::Window* window, ...@@ -250,6 +265,19 @@ void ActivationController::ActivateWindowWithEvent(aura::Window* window,
if (window && !CanActivateWindowWithEvent(window, event, CURRENT_VISIBILITY)) if (window && !CanActivateWindowWithEvent(window, event, CURRENT_VISIBILITY))
return; return;
// Make sure the workspace manager switches to the workspace for window.
// Without this CanReceiveEvents() below returns false and activation never
// changes. CanReceiveEvents() returns false if |window| isn't in the active
// workspace, in which case its parent is not visible.
// TODO(sky): if I instead change the opacity of the parent this isn't an
// issue, but will make animations trickier... Consider which one is better.
if (window) {
internal::RootWindowController* root_window_controller =
GetRootWindowController(window->GetRootWindow());
root_window_controller->workspace_controller()->
SetActiveWorkspaceByWindow(window);
}
// Restore minimized window. This needs to be done before CanReceiveEvents() // Restore minimized window. This needs to be done before CanReceiveEvents()
// is called as that function checks window visibility. // is called as that function checks window visibility.
if (window && wm::IsWindowMinimized(window)) if (window && wm::IsWindowMinimized(window))
...@@ -321,12 +349,10 @@ aura::Window* ActivationController::GetTopmostWindowToActivate( ...@@ -321,12 +349,10 @@ aura::Window* ActivationController::GetTopmostWindowToActivate(
aura::Window* window = NULL; aura::Window* window = NULL;
for (; !window && current_container_index < arraysize(kWindowContainerIds); for (; !window && current_container_index < arraysize(kWindowContainerIds);
current_container_index++) { current_container_index++) {
aura::Window::Windows containers = aura::Window::Windows containers =
Shell::GetAllContainers(kWindowContainerIds[current_container_index]); Shell::GetAllContainers(kWindowContainerIds[current_container_index]);
for (aura::Window::Windows::const_iterator iter = containers.begin(); for (aura::Window::Windows::const_iterator iter = containers.begin();
iter != containers.end(); iter != containers.end() && !window; ++iter) {
++iter) {
window = GetTopmostWindowToActivateInContainer((*iter), ignore); window = GetTopmostWindowToActivateInContainer((*iter), ignore);
} }
} }
...@@ -336,6 +362,21 @@ aura::Window* ActivationController::GetTopmostWindowToActivate( ...@@ -336,6 +362,21 @@ aura::Window* ActivationController::GetTopmostWindowToActivate(
aura::Window* ActivationController::GetTopmostWindowToActivateInContainer( aura::Window* ActivationController::GetTopmostWindowToActivateInContainer(
aura::Window* container, aura::Window* container,
aura::Window* ignore) const { aura::Window* ignore) const {
// Workspace2 has an extra level of windows that needs to be special cased.
if (container->id() == kShellWindowId_DefaultContainer &&
WorkspaceController::IsWorkspace2Enabled()) {
for (aura::Window::Windows::const_reverse_iterator i =
container->children().rbegin();
i != container->children().rend(); ++i) {
if ((*i)->IsVisible()) {
aura::Window* window = GetTopmostWindowToActivateInContainer(
*i, ignore);
if (window)
return window;
}
}
return NULL;
}
for (aura::Window::Windows::const_reverse_iterator i = for (aura::Window::Windows::const_reverse_iterator i =
container->children().rbegin(); container->children().rbegin();
i != container->children().rend(); i != container->children().rend();
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
#include "ash/wm/always_on_top_controller.h" #include "ash/wm/always_on_top_controller.h"
#include "ash/root_window_controller.h"
#include "ash/wm/property_util.h"
#include "ash/wm/workspace_controller.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
...@@ -22,31 +25,40 @@ AlwaysOnTopController::~AlwaysOnTopController() { ...@@ -22,31 +25,40 @@ AlwaysOnTopController::~AlwaysOnTopController() {
always_on_top_container_->RemoveObserver(this); always_on_top_container_->RemoveObserver(this);
} }
void AlwaysOnTopController::SetContainers(aura::Window* default_container, void AlwaysOnTopController::SetContainers(
aura::Window* default_container,
aura::Window* always_on_top_container) { aura::Window* always_on_top_container) {
if (WorkspaceController::IsWorkspace2Enabled())
default_container = NULL;
// Both containers should have no children. // Both containers should have no children.
DCHECK(default_container->children().empty());
DCHECK(always_on_top_container->children().empty()); DCHECK(always_on_top_container->children().empty());
// We are not handling any containers yet. // We are not handling any containers yet.
DCHECK(default_container_ == NULL && always_on_top_container_ == NULL); DCHECK(default_container_ == NULL && always_on_top_container_ == NULL);
default_container_ = default_container; default_container_ = default_container;
default_container_->AddObserver(this); if (default_container_)
default_container_->AddObserver(this);
always_on_top_container_ = always_on_top_container; always_on_top_container_ = always_on_top_container;
always_on_top_container_->AddObserver(this); always_on_top_container_->AddObserver(this);
} }
aura::Window* AlwaysOnTopController::GetContainer(aura::Window* window) const { aura::Window* AlwaysOnTopController::GetContainer(aura::Window* window) const {
DCHECK(default_container_ && always_on_top_container_); DCHECK(always_on_top_container_ &&
return !window->GetProperty(aura::client::kAlwaysOnTopKey) ? (default_container_ || WorkspaceController::IsWorkspace2Enabled()));
default_container_ : always_on_top_container_; if (window->GetProperty(aura::client::kAlwaysOnTopKey))
return always_on_top_container_;
if (default_container_)
return default_container_;
return GetRootWindowController(always_on_top_container_->GetRootWindow())->
workspace_controller()->GetParentForNewWindow(window);
} }
void AlwaysOnTopController::OnWindowAdded(aura::Window* child) { void AlwaysOnTopController::OnWindowAdded(aura::Window* child) {
// Observe direct child of the containers. // Observe direct child of the containers.
if (child->parent() == default_container_ || if ((default_container_ && child->parent() == default_container_) ||
child->parent() == always_on_top_container_) { child->parent() == always_on_top_container_) {
child->AddObserver(this); child->AddObserver(this);
} }
......
...@@ -41,6 +41,8 @@ class AlwaysOnTopController : public aura::WindowObserver { ...@@ -41,6 +41,8 @@ class AlwaysOnTopController : public aura::WindowObserver {
intptr_t old) OVERRIDE; intptr_t old) OVERRIDE;
virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE; virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
// TODO(sky): remove this after workspace2 is the default.
// Is NULL if workspace2 is enabled.
aura::Window* default_container_; aura::Window* default_container_;
aura::Window* always_on_top_container_; aura::Window* always_on_top_container_;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ash/wm/window_animations.h" #include "ash/wm/window_animations.h"
#include "ash/wm/window_properties.h" #include "ash/wm/window_properties.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
#include "ash/wm/workspace_controller.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
#include "ui/aura/root_window.h" #include "ui/aura/root_window.h"
...@@ -143,7 +144,9 @@ void BaseLayoutManager::OnWindowPropertyChanged(aura::Window* window, ...@@ -143,7 +144,9 @@ void BaseLayoutManager::OnWindowPropertyChanged(aura::Window* window,
SetRestoreBoundsInParent(window, window->bounds()); SetRestoreBoundsInParent(window, window->bounds());
} }
// Minimized state handles its own animations. // Minimized state handles its own animations.
bool animate = (old_state != ui::SHOW_STATE_MINIMIZED); // TODO(sky): get animations to work with Workspace2.
bool animate = (old_state != ui::SHOW_STATE_MINIMIZED) &&
!WorkspaceController::IsWorkspace2Enabled();
UpdateBoundsFromShowState(window, animate); UpdateBoundsFromShowState(window, animate);
ShowStateChanged(window, old_state); ShowStateChanged(window, old_state);
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ash/wm/activation_controller.h" #include "ash/wm/activation_controller.h"
#include "ash/wm/window_cycle_list.h" #include "ash/wm/window_cycle_list.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
#include "ash/wm/workspace_controller.h"
#include "ui/aura/event_filter.h" #include "ui/aura/event_filter.h"
#include "ui/aura/root_window.h" #include "ui/aura/root_window.h"
#include "ui/base/event.h" #include "ui/base/event.h"
...@@ -84,6 +85,34 @@ ui::GestureStatus WindowCycleEventFilter::PreHandleGestureEvent( ...@@ -84,6 +85,34 @@ ui::GestureStatus WindowCycleEventFilter::PreHandleGestureEvent(
return ui::GESTURE_STATUS_UNKNOWN; // Not handled. return ui::GESTURE_STATUS_UNKNOWN; // Not handled.
} }
// Adds all the children of |window| to |windows|.
void AddAllChildren(aura::Window* window,
WindowCycleList::WindowList* windows) {
const WindowCycleList::WindowList& children(window->children());
windows->insert(windows->end(), children.begin(), children.end());
}
// Adds all the children of all of |window|s children to |windows|.
void AddWorkspace2Children(aura::Window* window,
WindowCycleList::WindowList* windows) {
for (size_t i = 0; i < window->children().size(); ++i)
AddAllChildren(window->children()[i], windows);
}
// Adds the windows that can be cycled through for the specified window id to
// |windows|.
void AddCycleWindows(aura::RootWindow* root,
int container_id,
WindowCycleList::WindowList* windows) {
aura::Window* container = Shell::GetContainer(root, container_id);
if (container_id == internal::kShellWindowId_DefaultContainer &&
internal::WorkspaceController::IsWorkspace2Enabled()) {
AddWorkspace2Children(container, windows);
} else {
AddAllChildren(container, windows);
}
}
} // namespace } // namespace
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
...@@ -91,7 +120,7 @@ ui::GestureStatus WindowCycleEventFilter::PreHandleGestureEvent( ...@@ -91,7 +120,7 @@ ui::GestureStatus WindowCycleEventFilter::PreHandleGestureEvent(
WindowCycleController::WindowCycleController( WindowCycleController::WindowCycleController(
internal::ActivationController* activation_controller) internal::ActivationController* activation_controller)
: activation_controller_(activation_controller) { : activation_controller_(activation_controller) {
activation_controller_->AddObserver(this); activation_controller_->AddObserver(this);
} }
...@@ -104,6 +133,16 @@ WindowCycleController::~WindowCycleController() { ...@@ -104,6 +133,16 @@ WindowCycleController::~WindowCycleController() {
if (container) if (container)
container->RemoveObserver(this); container->RemoveObserver(this);
} }
aura::Window* default_container =
Shell::GetContainer(*iter, internal::kShellWindowId_DefaultContainer);
if (default_container) {
for (size_t i = 0; i < default_container->children().size(); ++i) {
aura::Window* workspace_window = default_container->children()[i];
DCHECK_EQ(internal::kShellWindowId_WorkspaceContainer,
workspace_window->id());
workspace_window->RemoveObserver(this);
}
}
} }
activation_controller_->RemoveObserver(this); activation_controller_->RemoveObserver(this);
...@@ -152,26 +191,19 @@ std::vector<aura::Window*> WindowCycleController::BuildWindowList( ...@@ -152,26 +191,19 @@ std::vector<aura::Window*> WindowCycleController::BuildWindowList(
WindowCycleList::WindowList windows; WindowCycleList::WindowList windows;
Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
aura::RootWindow* active_root = Shell::GetActiveRootWindow();
for (Shell::RootWindowList::const_iterator iter = root_windows.begin(); for (Shell::RootWindowList::const_iterator iter = root_windows.begin();
iter != root_windows.end(); ++iter) { iter != root_windows.end(); ++iter) {
if (*iter == Shell::GetActiveRootWindow()) if (*iter == active_root)
continue; continue;
for (size_t i = 0; i < arraysize(kContainerIds); ++i) { for (size_t i = 0; i < arraysize(kContainerIds); ++i)
aura::Window* container = Shell::GetContainer(*iter, kContainerIds[i]); AddCycleWindows(*iter, kContainerIds[i], &windows);
WindowCycleList::WindowList children = container->children();
windows.insert(windows.end(), children.begin(), children.end());
}
} }
// Add windows in the active root windows last so that the topmost window // Add windows in the active root windows last so that the topmost window
// in the active root window becomes the front of the list. // in the active root window becomes the front of the list.
for (size_t i = 0; i < arraysize(kContainerIds); ++i) { for (size_t i = 0; i < arraysize(kContainerIds); ++i)
aura::Window* container = AddCycleWindows(active_root, kContainerIds[i], &windows);
Shell::GetContainer(Shell::GetActiveRootWindow(), kContainerIds[i]);
WindowCycleList::WindowList children = container->children();
windows.insert(windows.end(), children.begin(), children.end());
}
// Removes unfocusable windows. // Removes unfocusable windows.
WindowCycleList::WindowList::iterator last = WindowCycleList::WindowList::iterator last =
...@@ -209,6 +241,16 @@ void WindowCycleController::OnRootWindowAdded(aura::RootWindow* root_window) { ...@@ -209,6 +241,16 @@ void WindowCycleController::OnRootWindowAdded(aura::RootWindow* root_window) {
Shell::GetContainer(root_window, kContainerIds[i]); Shell::GetContainer(root_window, kContainerIds[i]);
container->AddObserver(this); container->AddObserver(this);
} }
aura::Window* default_container =
Shell::GetContainer(root_window,
internal::kShellWindowId_DefaultContainer);
for (size_t i = 0; i < default_container->children().size(); ++i) {
aura::Window* workspace_window = default_container->children()[i];
DCHECK_EQ(internal::kShellWindowId_WorkspaceContainer,
workspace_window->id());
workspace_window->AddObserver(this);
}
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
...@@ -247,7 +289,7 @@ bool WindowCycleController::IsTrackedContainer(aura::Window* window) { ...@@ -247,7 +289,7 @@ bool WindowCycleController::IsTrackedContainer(aura::Window* window) {
return true; return true;
} }
} }
return false; return window->id() == internal::kShellWindowId_WorkspaceContainer;
} }
void WindowCycleController::InstallEventFilter() { void WindowCycleController::InstallEventFilter() {
...@@ -263,8 +305,15 @@ void WindowCycleController::OnWindowActivated(aura::Window* active, ...@@ -263,8 +305,15 @@ void WindowCycleController::OnWindowActivated(aura::Window* active,
} }
} }
void WindowCycleController::OnWindowAdded(aura::Window* window) {
if (window->id() == internal::kShellWindowId_WorkspaceContainer)
window->AddObserver(this);
}
void WindowCycleController::OnWillRemoveWindow(aura::Window* window) { void WindowCycleController::OnWillRemoveWindow(aura::Window* window) {
mru_windows_.remove(window); mru_windows_.remove(window);
if (window->id() == internal::kShellWindowId_WorkspaceContainer)
window->RemoveObserver(this);
} }
void WindowCycleController::OnWindowDestroying(aura::Window* window) { void WindowCycleController::OnWindowDestroying(aura::Window* window) {
......
...@@ -100,6 +100,7 @@ class ASH_EXPORT WindowCycleController ...@@ -100,6 +100,7 @@ class ASH_EXPORT WindowCycleController
aura::Window* old_active) OVERRIDE; aura::Window* old_active) OVERRIDE;
// Overridden from WindowObserver: // Overridden from WindowObserver:
virtual void OnWindowAdded(aura::Window* window) OVERRIDE;
virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE; virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE;
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
......
...@@ -17,9 +17,6 @@ class Layer; ...@@ -17,9 +17,6 @@ class Layer;
} }
namespace ash { namespace ash {
namespace internal {
class RootWindowController;
}
namespace wm { namespace wm {
// Convenience setters/getters for |aura::client::kRootWindowActiveWindow|. // Convenience setters/getters for |aura::client::kRootWindowActiveWindow|.
......
// Copyright (c) 2012 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/workspace/workspace2.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/property_util.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_util.h"
#include "ash/wm/workspace/workspace_event_filter.h"
#include "ash/wm/workspace/workspace_manager2.h"
#include "ui/aura/window.h"
namespace ash {
namespace internal {
Workspace2::Workspace2(WorkspaceManager2* manager,
aura::Window* parent,
bool is_maximized)
: is_maximized_(is_maximized),
workspace_manager_(manager),
window_(new aura::Window(NULL)),
event_filter_(new WorkspaceEventFilter(window_)) {
window_->set_id(kShellWindowId_WorkspaceContainer);
window_->SetName("WorkspaceContainer");
window_->Init(ui::LAYER_NOT_DRAWN);
window_->Show();
window_->SetParent(parent);
window_->SetEventFilter(event_filter_);
window_->SetProperty(internal::kUsesScreenCoordinatesKey, true);
}
Workspace2::~Workspace2() {
// ReleaseWindow() should have been invoked before we're deleted.
DCHECK(!window_);
}
aura::Window* Workspace2::ReleaseWindow() {
// Remove the LayoutManager and EventFilter as they refer back to us and/or
// WorkspaceManager.
window_->SetLayoutManager(NULL);
window_->SetEventFilter(NULL);
aura::Window* window = window_;
window_ = NULL;
event_filter_ = NULL;
return window;
}
void Workspace2::SetGridSize(int grid_size) {
event_filter_->set_grid_size(grid_size);
}
bool Workspace2::ShouldMoveToPending() const {
if (!is_maximized_)
return false;
bool has_visible_non_maximized_window = false;
for (size_t i = 0; i < window_->children().size(); ++i) {
aura::Window* child(window_->children()[i]);
if (!child->TargetVisibility() || wm::IsWindowMinimized(child))
continue;
if (WorkspaceManager2::IsMaximized(child))
return false;
if (GetTrackedByWorkspace(child) && !GetPersistsAcrossAllWorkspaces(child))
has_visible_non_maximized_window = true;
}
return !has_visible_non_maximized_window;
}
int Workspace2::GetNumMaximizedWindows() const {
int count = 0;
for (size_t i = 0; i < window_->children().size(); ++i) {
aura::Window* child = window_->children()[i];
if (WorkspaceManager2::IsMaximized(child) ||
WorkspaceManager2::WillRestoreMaximized(child)) {
if (++count == 2)
return count;
}
}
return count;
}
} // namespace internal
} // namespace ash
// Copyright (c) 2012 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_WORKSPACE_WORKSPACE2_H_
#define ASH_WM_WORKSPACE_WORKSPACE_H_
#include <vector>
#include "ash/ash_export.h"
#include "base/basictypes.h"
namespace aura {
class Window;
}
namespace gfx {
class Rect;
}
namespace ash {
namespace internal {
class WorkspaceEventFilter;
class WorkspaceManager2;
// Workspace is used to maintain either a single maximized windows (including
// transients and other windows) or any number of windows (for the
// desktop). Workspace is used by WorkspaceManager to manage a set of windows.
class ASH_EXPORT Workspace2 {
public:
Workspace2(WorkspaceManager2* manager,
aura::Window* parent,
bool is_maximized);
~Workspace2();
// Resets state. This should be used before destroying the Workspace.
aura::Window* ReleaseWindow();
bool is_maximized() const { return is_maximized_; }
aura::Window* window() { return window_; }
WorkspaceManager2* workspace_manager() { return workspace_manager_; }
void SetGridSize(int grid_size);
// Returns true if the Workspace should be moved to pending. This is true
// if there are no visible maximized windows.
bool ShouldMoveToPending() const;
// Returns the number of maximized windows (including minimized windows that
// would be maximized on restore). This does not consider visibility.
int GetNumMaximizedWindows() const;
private:
// Is this a workspace for maximized windows?
const bool is_maximized_;
WorkspaceManager2* workspace_manager_;
// Our Window, owned by |parent| passed to the constructor.
aura::Window* window_;
// Owned by |window_|.
WorkspaceEventFilter* event_filter_;
DISALLOW_COPY_AND_ASSIGN(Workspace2);
};
} // namespace internal
} // namespace ash
#endif // ASH_WM_WORKSPACE_WORKSPACE2_H_
This diff is collapsed.
// Copyright (c) 2012 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_WORKSPACE_WORKSPACE_MANAGER2_H_
#define ASH_WM_WORKSPACE_WORKSPACE_MANAGER2_H_
#include <set>
#include <string>
#include <vector>
#include "ash/ash_export.h"
#include "ash/wm/workspace/base_workspace_manager.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "ui/base/ui_base_types.h"
namespace aura {
class Window;
}
namespace gfx {
class Point;
class Rect;
}
namespace ash {
namespace internal {
class ShelfLayoutManager;
class WorkspaceManagerTest2;
class Workspace2;
// WorkspaceManager manages multiple workspaces in the desktop. Workspaces are
// implicitly created as windows are maximized (or made fullscreen), and
// destroyed when maximized windows are closed or restored. There is always one
// workspace for the desktop.
// Internally WorkspaceManager2 creates a Window for each Workspace. As windows
// are maximized and restored they are reparented to the right Window.
class ASH_EXPORT WorkspaceManager2 : public BaseWorkspaceManager {
public:
explicit WorkspaceManager2(aura::Window* viewport);
virtual ~WorkspaceManager2();
// Returns true if |window| is considered maximized and should exist in its
// own workspace.
static bool IsMaximized(aura::Window* window);
// Returns true if |window| is minimized and will restore to a maximized
// window.
static bool WillRestoreMaximized(aura::Window* window);
// BaseWorkspaceManager2 overrides:
virtual bool IsInMaximizedMode() const OVERRIDE;
virtual void SetGridSize(int size) OVERRIDE;
virtual int GetGridSize() const OVERRIDE;
virtual WorkspaceWindowState GetWindowState() const OVERRIDE;
virtual void SetShelf(ShelfLayoutManager* shelf) OVERRIDE;
virtual void SetActiveWorkspaceByWindow(aura::Window* window) OVERRIDE;
virtual aura::Window* GetParentForNewWindow(aura::Window* window) OVERRIDE;
private:
friend class WorkspaceManager2Test;
class LayoutManager;
class WorkspaceLayoutManager;
typedef std::vector<Workspace2*> Workspaces;
// Updates the visibility and whether any windows overlap the shelf.
void UpdateShelfVisibility();
// Returns the workspace that contains |window|.
Workspace2* FindBy(aura::Window* window) const;
// Sets the active workspace.
void SetActiveWorkspace(Workspace2* workspace);
// Returns the bounds of the work area.
gfx::Rect GetWorkAreaBounds() const;
// Returns an iterator into |workspaces_| for |workspace|.
Workspaces::iterator FindWorkspace(Workspace2* workspace);
Workspace2* desktop_workspace() { return workspaces_[0]; }
const Workspace2* desktop_workspace() const { return workspaces_[0]; }
// Creates a new workspace. The Workspace is not added to anything and is
// owned by the caller.
Workspace2* CreateWorkspace(bool maximized);
// Moves all the non-maximized child windows of |workspace| to the desktop
// stacked beneath |stack_beneath| (if non-NULL). After moving child windows
// if |workspace| contains no children it is deleted, otherwise it it moved to
// |pending_workspaces_|.
void MoveWorkspaceToPendingOrDelete(Workspace2* workspace,
aura::Window* stack_beneath);
// Selects the next workspace.
void SelectNextWorkspace();
// These methods are forwarded from the LayoutManager installed on the
// Workspace's window.
void OnWindowAddedToWorkspace(Workspace2* workspace, aura::Window* child);
void OnWindowRemovedFromWorkspace(Workspace2* workspace, aura::Window* child);
void OnWorkspaceChildWindowVisibilityChanged(Workspace2* workspace,
aura::Window* child);
void OnWorkspaceWindowChildBoundsChanged(Workspace2* workspace,
aura::Window* child);
void OnWorkspaceWindowShowStateChanged(Workspace2* workspace,
aura::Window* child,
ui::WindowShowState last_show_state);
aura::Window* contents_view_;
Workspace2* active_workspace_;
// The set of active workspaces. There is always at least one in this stack,
// which identifies the desktop.
Workspaces workspaces_;
// The set of workspaces not currently active. Workspaces ended up here in
// two scenarios:
// . Prior to adding a window a new worskpace is created for it. The
// Workspace is added to this set.
// . When the maximized window is minimized the workspace is added here.
// Once any window in the workspace is activated the workspace is moved to
// |workspaces_|.
std::set<Workspace2*> pending_workspaces_;
// See description above setter.
int grid_size_;
// Owned by the Shell. May be NULL.
ShelfLayoutManager* shelf_;
// Whether or not we're in MoveWorkspaceToPendingOrDelete(). As
// MoveWorkspaceToPendingOrDelete() may trigger another call to
// MoveWorkspaceToPendingOrDelete() we use this to avoid doing anything if
// already in MoveWorkspaceToPendingOrDelete().
bool in_move_;
DISALLOW_COPY_AND_ASSIGN(WorkspaceManager2);
};
} // namespace internal
} // namespace ash
#endif // ASH_WM_WORKSPACE_WORKSPACE_MANAGER2_H_
This diff is collapsed.
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
#include "ash/wm/workspace_controller.h" #include "ash/wm/workspace_controller.h"
#include "ash/ash_switches.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
#include "ash/wm/workspace/workspace_event_filter.h" #include "ash/wm/workspace/workspace_event_filter.h"
#include "ash/wm/workspace/workspace_layout_manager.h" #include "ash/wm/workspace/workspace_layout_manager.h"
#include "ash/wm/workspace/workspace_manager.h" #include "ash/wm/workspace/workspace_manager.h"
#include "ash/wm/workspace/workspace_manager2.h"
#include "base/command_line.h"
#include "ui/aura/client/activation_client.h" #include "ui/aura/client/activation_client.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
#include "ui/aura/root_window.h" #include "ui/aura/root_window.h"
...@@ -28,12 +31,18 @@ WorkspaceController::WorkspaceController(aura::Window* viewport) ...@@ -28,12 +31,18 @@ WorkspaceController::WorkspaceController(aura::Window* viewport)
layout_manager_(NULL), layout_manager_(NULL),
event_filter_(NULL) { event_filter_(NULL) {
aura::RootWindow* root_window = viewport->GetRootWindow(); aura::RootWindow* root_window = viewport->GetRootWindow();
event_filter_ = new WorkspaceEventFilter(viewport); if (IsWorkspace2Enabled()) {
viewport->SetEventFilter(event_filter_); WorkspaceManager2* workspace_manager = new WorkspaceManager2(viewport);
WorkspaceManager* workspace_manager = new WorkspaceManager(viewport); workspace_manager_.reset(workspace_manager);
workspace_manager_.reset(workspace_manager); } else {
layout_manager_ = new WorkspaceLayoutManager(root_window, workspace_manager); WorkspaceManager* workspace_manager = new WorkspaceManager(viewport);
viewport->SetLayoutManager(layout_manager_); workspace_manager_.reset(workspace_manager);
layout_manager_ = new WorkspaceLayoutManager(
root_window, workspace_manager);
viewport->SetLayoutManager(layout_manager_);
event_filter_ = new WorkspaceEventFilter(viewport);
viewport->SetEventFilter(event_filter_);
}
aura::client::GetActivationClient(root_window)->AddObserver(this); aura::client::GetActivationClient(root_window)->AddObserver(this);
SetGridSize(kGridSize); SetGridSize(kGridSize);
} }
...@@ -42,10 +51,16 @@ WorkspaceController::~WorkspaceController() { ...@@ -42,10 +51,16 @@ WorkspaceController::~WorkspaceController() {
aura::client::GetActivationClient(viewport_->GetRootWindow())-> aura::client::GetActivationClient(viewport_->GetRootWindow())->
RemoveObserver(this); RemoveObserver(this);
// WorkspaceLayoutManager may attempt to access state from us. Destroy it now. // WorkspaceLayoutManager may attempt to access state from us. Destroy it now.
if (viewport_->layout_manager() == layout_manager_) if (layout_manager_ && viewport_->layout_manager() == layout_manager_)
viewport_->SetLayoutManager(NULL); viewport_->SetLayoutManager(NULL);
} }
// static
bool WorkspaceController::IsWorkspace2Enabled() {
return CommandLine::ForCurrentProcess()->HasSwitch(
switches::kAshEnableWorkspace2);
}
bool WorkspaceController::IsInMaximizedMode() const { bool WorkspaceController::IsInMaximizedMode() const {
return workspace_manager_->IsInMaximizedMode(); return workspace_manager_->IsInMaximizedMode();
} }
......
...@@ -33,6 +33,9 @@ class ASH_EXPORT WorkspaceController ...@@ -33,6 +33,9 @@ class ASH_EXPORT WorkspaceController
explicit WorkspaceController(aura::Window* viewport); explicit WorkspaceController(aura::Window* viewport);
virtual ~WorkspaceController(); virtual ~WorkspaceController();
// Returns true if Workspace2 is enabled.
static bool IsWorkspace2Enabled();
// Returns true if in maximized or fullscreen mode. // Returns true if in maximized or fullscreen mode.
bool IsInMaximizedMode() const; bool IsInMaximizedMode() const;
...@@ -62,6 +65,9 @@ class ASH_EXPORT WorkspaceController ...@@ -62,6 +65,9 @@ class ASH_EXPORT WorkspaceController
scoped_ptr<BaseWorkspaceManager> workspace_manager_; scoped_ptr<BaseWorkspaceManager> workspace_manager_;
// TODO(sky): remove |layout_manager_| and |event_filter_| when Workspace2
// is the default.
// Owned by the window its attached to. // Owned by the window its attached to.
WorkspaceLayoutManager* layout_manager_; WorkspaceLayoutManager* layout_manager_;
......
...@@ -20,6 +20,9 @@ WorkspaceControllerTestHelper::~WorkspaceControllerTestHelper() { ...@@ -20,6 +20,9 @@ WorkspaceControllerTestHelper::~WorkspaceControllerTestHelper() {
} }
WorkspaceEventFilter* WorkspaceControllerTestHelper::GetFilter() { WorkspaceEventFilter* WorkspaceControllerTestHelper::GetFilter() {
if (WorkspaceController::IsWorkspace2Enabled())
return static_cast<WorkspaceEventFilter*>(
controller_->viewport_->children()[0]->event_filter());
return controller_->event_filter_; return controller_->event_filter_;
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "ash/wm/workspace_controller.h" #include "ash/wm/workspace_controller.h"
#include "ash/wm/workspace/workspace_manager.h" #include "ash/wm/workspace/workspace_manager.h"
#include "ash/wm/workspace/workspace_manager2.h"
namespace ash { namespace ash {
namespace internal { namespace internal {
...@@ -25,6 +26,10 @@ class WorkspaceControllerTestHelper { ...@@ -25,6 +26,10 @@ class WorkspaceControllerTestHelper {
return static_cast<WorkspaceManager*>( return static_cast<WorkspaceManager*>(
controller_->workspace_manager_.get()); controller_->workspace_manager_.get());
} }
WorkspaceManager2* workspace_manager2() {
return static_cast<WorkspaceManager2*>(
controller_->workspace_manager_.get());
}
private: private:
WorkspaceController* controller_; WorkspaceController* controller_;
......
...@@ -6033,6 +6033,12 @@ Keep your key file in a safe place. You will need it to create new versions of y ...@@ -6033,6 +6033,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_FLAGS_DISABLE_BOOT_ANIMATION_DESCRIPTION" desc="Description for the flag to disable wallpaper boot animation (except for OOBE)."> <message name="IDS_FLAGS_DISABLE_BOOT_ANIMATION_DESCRIPTION" desc="Description for the flag to disable wallpaper boot animation (except for OOBE).">
Disables wallpaper boot animation (except for OOBE case). Disables wallpaper boot animation (except for OOBE case).
</message> </message>
<message name="IDS_FLAGS_ENABLE_WORKSPACE2" desc="Description for the flag to turn on workspace2.">
Enable new window stacking.
</message>
<message name="IDS_FLAGS_ENABLE_WORKSPACE2_DESCRIPTION" desc="Description for the flag to turn on workspace2.">
Enable new window stacking.
</message>
</if> </if>
<message name="IDS_FLAGS_OLD_CHECKBOX_STYLE" desc="Name of the flag to turn off the new checkbox style."> <message name="IDS_FLAGS_OLD_CHECKBOX_STYLE" desc="Name of the flag to turn off the new checkbox style.">
...@@ -852,6 +852,13 @@ const Experiment kExperiments[] = { ...@@ -852,6 +852,13 @@ const Experiment kExperiments[] = {
kOsCrOS, kOsCrOS,
SINGLE_VALUE_TYPE(switches::kDisableBootAnimation), SINGLE_VALUE_TYPE(switches::kDisableBootAnimation),
}, },
{
"enable-workspace2",
IDS_FLAGS_ENABLE_WORKSPACE2,
IDS_FLAGS_ENABLE_WORKSPACE2_DESCRIPTION,
kOsCrOS,
SINGLE_VALUE_TYPE(ash::switches::kAshEnableWorkspace2),
},
#endif #endif
{ {
"enable-views-textfield", "enable-views-textfield",
......
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