Commit e55b7345 authored by skuhne@chromium.org's avatar skuhne@chromium.org

Adding new always maximized mode

This is (at this time) not complete. There are some outstanding issues to be resolved marked with TODO(skuhne) which I will address before submitting. This is meant to be a "preview".

What does it do?

It tracks the creation of all browsers / V1 / V2 applications and maximizes them automatically. Non maximizable windows will get centered and a layer will be put behind them. Note that not all windows can be maximized. Dialogs, tray, .. will remain in their window state.

The missing things:
- Background cover layer
- Removing of the restore button from the caption (different CL)
- Suppression of restore / fullscreen request events of any of the tracked windows.

BUG=337563
TEST=unit tests

Review URL: https://codereview.chromium.org/167503002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252211 0039d316-1c4b-4281-b951-d872f2087c98
parent 9b0d66b6
......@@ -270,6 +270,8 @@
'sticky_keys/sticky_keys_controller.h',
'sticky_keys/sticky_keys_overlay.cc',
'sticky_keys/sticky_keys_overlay.h',
'switchable_windows.cc',
'switchable_windows.h',
'system/audio/audio_observer.h',
'system/audio/tray_audio.cc',
'system/audio/tray_audio.h',
......@@ -532,6 +534,8 @@
'wm/lock_state_controller.cc',
'wm/lock_state_controller.h',
'wm/lock_state_observer.h',
'wm/maximize_mode/maximize_mode_window_manager.cc',
'wm/maximize_mode/maximize_mode_window_manager.h',
'wm/mru_window_tracker.cc',
'wm/mru_window_tracker.h',
'wm/overlay_event_filter.cc',
......@@ -942,6 +946,7 @@
'wm/header_painter_unittest.cc',
'wm/immersive_fullscreen_controller_unittest.cc',
'wm/lock_state_controller_unittest.cc',
'wm/maximize_mode/maximize_mode_window_manager_unittest.cc',
'wm/mru_window_tracker_unittest.cc',
'wm/overview/window_selector_unittest.cc',
'wm/panels/panel_layout_manager_unittest.cc',
......
......@@ -59,6 +59,7 @@
#include "ash/wm/custom_frame_view_ash.h"
#include "ash/wm/event_client_impl.h"
#include "ash/wm/lock_state_controller.h"
#include "ash/wm/maximize_mode/maximize_mode_window_manager.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overlay_event_filter.h"
#include "ash/wm/overview/window_selector_controller.h"
......@@ -427,6 +428,15 @@ void Shell::RemoveShellObserver(ShellObserver* observer) {
observers_.RemoveObserver(observer);
}
void Shell::EnableMaximizeModeWindowManager(bool enable) {
if (enable && !maximize_mode_window_manager_.get()) {
maximize_mode_window_manager_.reset(
new internal::MaximizeModeWindowManager());
} else if (!enable && maximize_mode_window_manager_.get()) {
maximize_mode_window_manager_.reset();
}
}
void Shell::UpdateShelfVisibility() {
RootWindowControllerList controllers = GetAllRootWindowControllers();
for (RootWindowControllerList::iterator iter = controllers.begin();
......
......@@ -129,6 +129,7 @@ class EventTransformationHandler;
class FocusCycler;
class KeyboardUMAEventFilter;
class LocaleNotificationController;
class MaximizeModeWindowManager;
class MouseCursorEventFilter;
class OutputConfiguratorAnimation;
class OverlayEventFilter;
......@@ -307,6 +308,9 @@ class ASH_EXPORT Shell
void AddShellObserver(ShellObserver* observer);
void RemoveShellObserver(ShellObserver* observer);
// Turn the always maximize mode window manager on or off.
void EnableMaximizeModeWindowManager(bool enable);
keyboard::KeyboardController* keyboard_controller() {
return keyboard_controller_.get();
}
......@@ -681,6 +685,9 @@ class ASH_EXPORT Shell
scoped_ptr<internal::LocaleNotificationController>
locale_notification_controller_;
// The maximized window manager (if enabled).
scoped_ptr<internal::MaximizeModeWindowManager> maximize_mode_window_manager_;
#if defined(OS_CHROMEOS)
scoped_ptr<internal::PowerEventObserver> power_event_observer_;
scoped_ptr<internal::UserActivityNotifier> user_activity_notifier_;
......
// Copyright 2014 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/switchable_windows.h"
#include "ash/shell_window_ids.h"
namespace ash {
const int kSwitchableWindowContainerIds[] = {
internal::kShellWindowId_DefaultContainer,
internal::kShellWindowId_AlwaysOnTopContainer,
internal::kShellWindowId_PanelContainer
};
const size_t kSwitchableWindowContainerIdsLength =
arraysize(kSwitchableWindowContainerIds);
} // namespace ash
// Copyright 2014 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_SWITCHABLE_WINDOWS_H_
#define ASH_SWITCHABLE_WINDOWS_H_
#include "ash/ash_export.h"
#include "base/macros.h"
namespace ash {
// List of containers which contain windows that can be switched via Alt+Tab to.
ASH_EXPORT extern const int kSwitchableWindowContainerIds[];
// The number of elements in kSwitchableWindowContainerIds.
ASH_EXPORT extern const size_t kSwitchableWindowContainerIdsLength;
} // namespace ash
#endif // ASH_SWITCHABLE_WINDOWS_H_
......@@ -57,6 +57,11 @@ internal::AppListController* ShellTestApi::app_list_controller() {
return shell_->app_list_controller_.get();
}
internal::MaximizeModeWindowManager*
ShellTestApi::maximize_mode_window_manager() {
return shell_->maximize_mode_window_manager_.get();
}
void ShellTestApi::DisableOutputConfiguratorAnimation() {
#if defined(OS_CHROMEOS)
if (shell_->output_configurator_animation_) {
......
......@@ -22,6 +22,7 @@ class Shell;
namespace internal {
class AppListController;
class DragDropController;
class MaximizeModeWindowManager;
class RootWindowLayoutManager;
class ScreenPositionController;
class SystemGestureEventFilter;
......@@ -44,7 +45,7 @@ public:
ShelfModel* shelf_model();
internal::DragDropController* drag_drop_controller();
internal::AppListController* app_list_controller();
internal::MaximizeModeWindowManager* maximize_mode_window_manager();
void DisableOutputConfiguratorAnimation();
// Set ShelfDelegate.
......
// Copyright 2014 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/maximize_mode/maximize_mode_window_manager.h"
#include "ash/shell.h"
#include "ash/switchable_windows.h"
#include "ash/wm/mru_window_tracker.h"
#include "ui/aura/window.h"
#include "ui/gfx/screen.h"
namespace ash {
namespace internal {
MaximizeModeWindowManager::~MaximizeModeWindowManager() {
Shell::GetScreen()->RemoveObserver(this);
RemoveWindowCreationObservers();
RestoreAllWindows();
}
int MaximizeModeWindowManager::GetNumberOfManagedWindows() {
return initial_show_state_.size();
}
void MaximizeModeWindowManager::OnWindowDestroying(aura::Window* window) {
// If a known window gets destroyed we need to remove all knowledge about it.
if (!IsContainerWindow(window))
ForgetWindow(window);
}
void MaximizeModeWindowManager::OnWindowAdded(
aura::Window* window) {
// A window can get removed and then re-added by a drag and drop operation.
if (IsContainerWindow(window->parent()) &&
initial_show_state_.find(window) == initial_show_state_.end())
MaximizeAndTrackWindow(window);
}
void MaximizeModeWindowManager::OnWindowBoundsChanged(
aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
if (!IsContainerWindow(window))
return;
// Reposition all non maximizeable windows.
for (WindowToShowState::iterator it = initial_show_state_.begin();
it != initial_show_state_.end();
++it) {
if (!CanMaximize(it->first))
CenterWindow(it->first);
}
}
void MaximizeModeWindowManager::OnDisplayBoundsChanged(
const gfx::Display& display) {
// Nothing to do here.
}
void MaximizeModeWindowManager::OnDisplayAdded(const gfx::Display& display) {
RemoveWindowCreationObservers();
AddWindowCreationObservers();
}
void MaximizeModeWindowManager::OnDisplayRemoved(const gfx::Display& display) {
RemoveWindowCreationObservers();
AddWindowCreationObservers();
}
MaximizeModeWindowManager::MaximizeModeWindowManager() {
MaximizeAllWindows();
AddWindowCreationObservers();
Shell::GetScreen()->AddObserver(this);
}
void MaximizeModeWindowManager::MaximizeAllWindows() {
MruWindowTracker::WindowList windows =
MruWindowTracker::BuildWindowList(false);
// Add all existing Mru windows.
for (MruWindowTracker::WindowList::iterator window = windows.begin();
window != windows.end(); ++window) {
MaximizeAndTrackWindow(*window);
}
}
void MaximizeModeWindowManager::RestoreAllWindows() {
WindowToShowState::iterator it = initial_show_state_.begin();
while (it != initial_show_state_.end()) {
RestoreAndForgetWindow(it->first);
// |RestoreAndForgetWindow| will change the |initial_show_state_| list.
it = initial_show_state_.begin();
}
}
void MaximizeModeWindowManager::MaximizeAndTrackWindow(
aura::Window* window) {
if (!ShouldHandleWindow(window))
return;
DCHECK(initial_show_state_.find(window) == initial_show_state_.end());
window->AddObserver(this);
// Remember the state at the creation.
ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
ui::WindowShowState state = window_state->GetShowState();
initial_show_state_[window] = state;
// If it is not maximized yet we may need to maximize it now.
if (state != ui::SHOW_STATE_MAXIMIZED) {
if (!CanMaximize(window)) {
// This window type should not be able to have a restore state set (since
// it cannot maximize).
DCHECK(!window_state->HasRestoreBounds());
// Store the coordinates as restore coordinates.
gfx::Rect initial_rect = window->bounds();
if (window->parent())
window_state->SetRestoreBoundsInParent(initial_rect);
else
window_state->SetRestoreBoundsInScreen(initial_rect);
CenterWindow(window);
// TODO(skuhne): Add a background cover layer.
} else {
// Minimized windows can remain as they are.
if (state != ui::SHOW_STATE_MINIMIZED)
ash::wm::GetWindowState(window)->Maximize();
}
}
}
void MaximizeModeWindowManager::RestoreAndForgetWindow(
aura::Window* window) {
ui::WindowShowState state = ForgetWindow(window);
// Restore window if it can be restored.
if (state != ui::SHOW_STATE_MAXIMIZED) {
if (!CanMaximize(window)) {
// TODO(skuhne): Remove the background cover layer.
ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
DCHECK(window_state->HasRestoreBounds());
gfx::Rect initial_bounds =
window->parent() ? window_state->GetRestoreBoundsInParent() :
window_state->GetRestoreBoundsInScreen();
window_state->ClearRestoreBounds();
// TODO(skuhne): The screen might have changed and we should make it
// visible area again.
window->SetBounds(initial_bounds);
} else {
// If the window neither was minimized or maximized and it is currently
// not minimized, we restore it.
if (state != ui::SHOW_STATE_MINIMIZED &&
!ash::wm::GetWindowState(window)->IsMinimized()) {
ash::wm::GetWindowState(window)->Restore();
}
}
}
}
ui::WindowShowState MaximizeModeWindowManager::ForgetWindow(
aura::Window* window) {
WindowToShowState::iterator it = initial_show_state_.find(window);
DCHECK(it != initial_show_state_.end());
window->RemoveObserver(this);
ui::WindowShowState state = it->second;
initial_show_state_.erase(it);
return state;
}
bool MaximizeModeWindowManager::ShouldHandleWindow(aura::Window* window) {
DCHECK(window);
return window->type() == ui::wm::WINDOW_TYPE_NORMAL;
}
bool MaximizeModeWindowManager::CanMaximize(aura::Window* window) {
DCHECK(window);
return ash::wm::GetWindowState(window)->CanMaximize();
}
void MaximizeModeWindowManager::CenterWindow(aura::Window* window) {
gfx::Size window_size = window->bounds().size();
gfx::Rect work_area = gfx::Screen::GetScreenFor(window)->
GetDisplayNearestWindow(window).work_area();
gfx::Rect window_bounds(
work_area.x() + (work_area.width() - window_size.width()) / 2,
work_area.y() + (work_area.height() - window_size.height()) / 2,
window_size.width(),
window_size.height());
window->SetBounds(window_bounds);
}
void MaximizeModeWindowManager::AddWindowCreationObservers() {
DCHECK(observed_container_windows_.empty());
// Observe window activations and switchable containers on all root windows
// for newly created windows during overview.
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
for (aura::Window::Windows::const_iterator iter = root_windows.begin();
iter != root_windows.end(); ++iter) {
for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) {
aura::Window* container = Shell::GetContainer(*iter,
kSwitchableWindowContainerIds[i]);
DCHECK(observed_container_windows_.find(container) ==
observed_container_windows_.end());
container->AddObserver(this);
observed_container_windows_.insert(container);
}
}
}
void MaximizeModeWindowManager::RemoveWindowCreationObservers() {
for (std::set<aura::Window*>::iterator iter =
observed_container_windows_.begin();
iter != observed_container_windows_.end(); ++iter) {
(*iter)->RemoveObserver(this);
}
observed_container_windows_.clear();
}
bool MaximizeModeWindowManager::IsContainerWindow(aura::Window* window) {
return observed_container_windows_.find(window) !=
observed_container_windows_.end();
}
} // namespace internal
} // namespace ash
// Copyright 2014 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_MAXIMIZE_MODE_MAXIMIZE_MODE_WINDOW_MANAGER_H_
#define ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_WINDOW_MANAGER_H_
#include <map>
#include <set>
#include "ash/ash_export.h"
#include "ash/wm/window_state.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "ui/aura/window_observer.h"
#include "ui/gfx/display_observer.h"
namespace ash {
class Shell;
namespace internal{
// A window manager which - when created - will force all windows into maximized
// mode. Exception are panels and windows which cannot be maximized.
// Windows which cannot be maximized / resized are centered with a layer placed
// behind the window so that no other windows are visible and/or obscured.
// With the destruction of the manager all windows will be restored to their
// original state.
class ASH_EXPORT MaximizeModeWindowManager : public aura::WindowObserver,
public gfx::DisplayObserver {
public:
// This should only be deleted by the creator (ash::Shell).
virtual ~MaximizeModeWindowManager();
// Returns the number of maximized & tracked windows by this manager.
int GetNumberOfManagedWindows();
// Overridden from WindowObserver:
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
virtual void OnWindowAdded(aura::Window* window) OVERRIDE;
virtual void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE;
// aura::DisplayObserver overrides:
virtual void OnDisplayBoundsChanged(
const gfx::Display& display) OVERRIDE;
virtual void OnDisplayAdded(const gfx::Display& display) OVERRIDE;
virtual void OnDisplayRemoved(const gfx::Display& display) OVERRIDE;
protected:
friend class ash::Shell;
// The object should only be created by the ash::Shell.
MaximizeModeWindowManager();
private:
typedef std::map<aura::Window*, ui::WindowShowState> WindowToShowState;
// Maximize all windows and restore their current state.
void MaximizeAllWindows();
// Restore all windows to their previous state.
void RestoreAllWindows();
// If the given window should be handled by us, this function will maximize it
// and add it to the list of known windows (remembering the initial show
// state).
// Note: If the given window cannot be handled by us the function will return
// immediately.
void MaximizeAndTrackWindow(aura::Window* window);
// Restore the window to its original state and remove it from our tracking.
void RestoreAndForgetWindow(aura::Window* window);
// Remove a window from our tracking list.
ui::WindowShowState ForgetWindow(aura::Window* window);
// Returns true when the given window should be modified in any way by us.
bool ShouldHandleWindow(aura::Window* window);
// Returns true when the given window can be maximized.
bool CanMaximize(aura::Window* window);
// Maximize the window on the screen's workspace.
void CenterWindow(aura::Window* window);
// Add window creation observers to track creation of new windows.
void AddWindowCreationObservers();
// Remove Window creation observers.
void RemoveWindowCreationObservers();
// Returns true when the |window| is a container window.
bool IsContainerWindow(aura::Window* window);
// Every window which got touched by our window manager gets added here.
WindowToShowState initial_show_state_;
// All container windows which have to be tracked.
std::set<aura::Window*> observed_container_windows_;
DISALLOW_COPY_AND_ASSIGN(MaximizeModeWindowManager);
};
} // namespace internal
} // namespace ash
#endif // ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_WINDOW_MANAGER_H_
This diff is collapsed.
......@@ -9,6 +9,7 @@
#include "ash/session_state_delegate.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/switchable_windows.h"
#include "ash/wm/window_cycle_list.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
......@@ -134,15 +135,6 @@ MruWindowTracker::WindowList BuildWindowListInternal(
} // namespace
const int kSwitchableWindowContainerIds[] = {
internal::kShellWindowId_DefaultContainer,
internal::kShellWindowId_AlwaysOnTopContainer,
internal::kShellWindowId_PanelContainer
};
const size_t kSwitchableWindowContainerIdsLength =
arraysize(kSwitchableWindowContainerIds);
//////////////////////////////////////////////////////////////////////////////
// MruWindowTracker, public:
......
......@@ -24,12 +24,6 @@ class ActivationClient;
namespace ash {
// List of containers which contain windows that can be switched to.
ASH_EXPORT extern const int kSwitchableWindowContainerIds[];
// The number of elements in kSwitchableWindowContainerIds.
ASH_EXPORT extern const size_t kSwitchableWindowContainerIdsLength;
// Maintains a most recently used list of windows. This is used for window
// cycling using Alt+Tab and overview mode.
class ASH_EXPORT MruWindowTracker
......
......@@ -10,7 +10,7 @@
#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/switchable_windows.h"
#include "ash/wm/overview/scoped_transform_overview_window.h"
#include "ash/wm/overview/window_selector.h"
#include "ash/wm/overview/window_selector_item.h"
......
......@@ -9,7 +9,7 @@
#include "ash/ash_switches.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/switchable_windows.h"
#include "ash/wm/overview/window_overview.h"
#include "ash/wm/overview/window_selector_delegate.h"
#include "ash/wm/overview/window_selector_panels.h"
......
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