summaryrefslogtreecommitdiffstats
path: root/ash/wm
diff options
context:
space:
mode:
authordtapuska <dtapuska@chromium.org>2014-10-03 13:10:04 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-03 20:10:21 +0000
commitc6e5e38c6843add6e7aa5d427958164d0550f20b (patch)
tree706bfbd4c053bad09df4099f37aaceadb7c407c7 /ash/wm
parent3a8252cdcdf60ad0a6a5ed2ba573801a13117ef0 (diff)
downloadchromium_src-c6e5e38c6843add6e7aa5d427958164d0550f20b.zip
chromium_src-c6e5e38c6843add6e7aa5d427958164d0550f20b.tar.gz
chromium_src-c6e5e38c6843add6e7aa5d427958164d0550f20b.tar.bz2
Change behaviour of the Alt-] and Alt-[ keys so that it cycles through SnapLeft/SnapRight to DockLeft/DockRight to Restore.
BUG=344597 Review URL: https://codereview.chromium.org/594383002 Cr-Commit-Position: refs/heads/master@{#298084}
Diffstat (limited to 'ash/wm')
-rw-r--r--ash/wm/default_state.cc108
-rw-r--r--ash/wm/dock/dock_types.h1
-rw-r--r--ash/wm/dock/docked_window_layout_manager.cc27
-rw-r--r--ash/wm/dock/docked_window_layout_manager.h14
-rw-r--r--ash/wm/lock_window_state.cc2
-rw-r--r--ash/wm/maximize_mode/maximize_mode_window_state.cc2
-rw-r--r--ash/wm/panels/panel_layout_manager.h1
-rw-r--r--ash/wm/wm_event.h13
8 files changed, 161 insertions, 7 deletions
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc
index 86d9565..46a8545 100644
--- a/ash/wm/default_state.cc
+++ b/ash/wm/default_state.cc
@@ -9,6 +9,7 @@
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/coordinate_conversion.h"
+#include "ash/wm/dock/docked_window_layout_manager.h"
#include "ash/wm/window_animations.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_state_delegate.h"
@@ -64,6 +65,105 @@ void MoveToDisplayForRestore(WindowState* window_state) {
}
}
+DockedWindowLayoutManager* GetDockedWindowLayoutManager() {
+ aura::Window* active_window = ash::wm::GetActiveWindow();
+ if (active_window) {
+ aura::Window* dock_container = Shell::GetContainer(
+ active_window->GetRootWindow(), kShellWindowId_DockedContainer);
+ DockedWindowLayoutManager* dock_layout =
+ static_cast<DockedWindowLayoutManager*>(
+ dock_container->layout_manager());
+ return dock_layout;
+ }
+ return NULL;
+}
+
+class ScopedPreferredAlignmentResetter {
+ public:
+ ScopedPreferredAlignmentResetter(DockedAlignment dock_alignment,
+ DockedWindowLayoutManager* dock_layout)
+ : docked_window_layout_manager_(dock_layout) {
+ docked_window_layout_manager_->set_preferred_alignment(dock_alignment);
+ }
+ ~ScopedPreferredAlignmentResetter() {
+ docked_window_layout_manager_->set_preferred_alignment(
+ DOCKED_ALIGNMENT_NONE);
+ }
+
+ private:
+ DockedWindowLayoutManager* docked_window_layout_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedPreferredAlignmentResetter);
+};
+
+class ScopedDockedLayoutEventSourceResetter {
+ public:
+ ScopedDockedLayoutEventSourceResetter(DockedWindowLayoutManager* dock_layout)
+ : docked_window_layout_manager_(dock_layout) {
+ docked_window_layout_manager_->set_event_source(
+ DOCKED_ACTION_SOURCE_KEYBOARD);
+ }
+ ~ScopedDockedLayoutEventSourceResetter() {
+ docked_window_layout_manager_->set_event_source(
+ DOCKED_ACTION_SOURCE_UNKNOWN);
+ }
+
+ private:
+ DockedWindowLayoutManager* docked_window_layout_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedDockedLayoutEventSourceResetter);
+};
+
+void CycleSnapDock(WindowState* window_state, WMEventType event) {
+ DockedWindowLayoutManager* dock_layout = GetDockedWindowLayoutManager();
+ wm::WindowStateType desired_snap_state = event ==
+ WM_EVENT_CYCLE_SNAP_DOCK_LEFT ? wm::WINDOW_STATE_TYPE_LEFT_SNAPPED :
+ wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED;
+ DockedAlignment desired_dock_alignment = event ==
+ WM_EVENT_CYCLE_SNAP_DOCK_LEFT ?
+ DOCKED_ALIGNMENT_LEFT : DOCKED_ALIGNMENT_RIGHT;
+ DockedAlignment current_dock_alignment = dock_layout ?
+ dock_layout->CalculateAlignment() : DOCKED_ALIGNMENT_NONE;
+
+ if (!window_state->IsDocked() ||
+ (current_dock_alignment != DOCKED_ALIGNMENT_NONE &&
+ current_dock_alignment != desired_dock_alignment)) {
+ if (window_state->CanSnap() &&
+ window_state->GetStateType() != desired_snap_state &&
+ window_state->window()->type() != ui::wm::WINDOW_TYPE_PANEL) {
+ const wm::WMEvent event(desired_snap_state ==
+ wm::WINDOW_STATE_TYPE_LEFT_SNAPPED ?
+ wm::WM_EVENT_SNAP_LEFT : wm::WM_EVENT_SNAP_RIGHT);
+ window_state->OnWMEvent(&event);
+ return;
+ }
+
+ if (dock_layout &&
+ dock_layout->CanDockWindow(window_state->window(),
+ desired_dock_alignment)) {
+ if (window_state->IsDocked()) {
+ dock_layout->MaybeSetDesiredDockedAlignment(desired_dock_alignment);
+ return;
+ }
+
+ ScopedDockedLayoutEventSourceResetter event_source_resetter(dock_layout);
+ ScopedPreferredAlignmentResetter alignmentResetter(desired_dock_alignment,
+ dock_layout);
+ const wm::WMEvent event(wm::WM_EVENT_DOCK);
+ window_state->OnWMEvent(&event);
+ return;
+ }
+ }
+
+ if (window_state->IsDocked() || window_state->IsSnapped()) {
+ ScopedDockedLayoutEventSourceResetter event_source_resetter(dock_layout);
+ window_state->Restore();
+ return;
+ }
+ ::wm::AnimateWindow(window_state->window(),
+ ::wm::WINDOW_ANIMATION_TYPE_BOUNCE);
+}
+
} // namespace;
DefaultState::DefaultState(WindowStateType initial_state_type)
@@ -117,6 +217,8 @@ void DefaultState::OnWMEvent(WindowState* window_state,
case WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE:
case WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE:
case WM_EVENT_TOGGLE_FULLSCREEN:
+ case WM_EVENT_CYCLE_SNAP_DOCK_LEFT:
+ case WM_EVENT_CYCLE_SNAP_DOCK_RIGHT:
case WM_EVENT_CENTER:
NOTREACHED() << "Compound event should not reach here:" << event;
return;
@@ -268,6 +370,10 @@ bool DefaultState::ProcessCompoundEvents(WindowState* window_state,
case WM_EVENT_TOGGLE_FULLSCREEN:
ToggleFullScreen(window_state, window_state->delegate());
return true;
+ case WM_EVENT_CYCLE_SNAP_DOCK_LEFT:
+ case WM_EVENT_CYCLE_SNAP_DOCK_RIGHT:
+ CycleSnapDock(window_state, event->type());
+ return true;
case WM_EVENT_CENTER:
CenterWindow(window_state);
return true;
@@ -370,6 +476,8 @@ bool DefaultState::ProcessWorkspaceEvents(WindowState* window_state,
case WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE:
case WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE:
case WM_EVENT_TOGGLE_FULLSCREEN:
+ case WM_EVENT_CYCLE_SNAP_DOCK_LEFT:
+ case WM_EVENT_CYCLE_SNAP_DOCK_RIGHT:
case WM_EVENT_CENTER:
case WM_EVENT_NORMAL:
case WM_EVENT_MAXIMIZE:
diff --git a/ash/wm/dock/dock_types.h b/ash/wm/dock/dock_types.h
index c203a67..7db37c3 100644
--- a/ash/wm/dock/dock_types.h
+++ b/ash/wm/dock/dock_types.h
@@ -42,6 +42,7 @@ enum DockedActionSource {
DOCKED_ACTION_SOURCE_UNKNOWN,
DOCKED_ACTION_SOURCE_MOUSE,
DOCKED_ACTION_SOURCE_TOUCH,
+ DOCKED_ACTION_SOURCE_KEYBOARD,
// Maximum value of this enum for histograms use.
DOCKED_ACTION_SOURCE_COUNT,
diff --git a/ash/wm/dock/docked_window_layout_manager.cc b/ash/wm/dock/docked_window_layout_manager.cc
index bd082f5..b12d221 100644
--- a/ash/wm/dock/docked_window_layout_manager.cc
+++ b/ash/wm/dock/docked_window_layout_manager.cc
@@ -416,6 +416,8 @@ DockedWindowLayoutManager::DockedWindowLayoutManager(
WORKSPACE_WINDOW_STATE_FULL_SCREEN),
docked_width_(0),
alignment_(DOCKED_ALIGNMENT_NONE),
+ preferred_alignment_(DOCKED_ALIGNMENT_NONE),
+ event_source_(DOCKED_ACTION_SOURCE_UNKNOWN),
last_active_window_(NULL),
last_action_time_(base::Time::Now()),
background_widget_(new DockedBackgroundWidget(dock_container_)) {
@@ -692,13 +694,20 @@ void DockedWindowLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
// A window can be added without proper bounds when window is moved to another
// display via API or due to display configuration change, so the alignment
// is set based on which edge is closer in the new display.
- if (alignment_ == DOCKED_ALIGNMENT_NONE)
- alignment_ = GetEdgeNearestWindow(child);
+ if (alignment_ == DOCKED_ALIGNMENT_NONE) {
+ alignment_ = preferred_alignment_ != DOCKED_ALIGNMENT_NONE ?
+ preferred_alignment_ : GetEdgeNearestWindow(child);
+ }
MaybeMinimizeChildrenExcept(child);
child->AddObserver(this);
wm::GetWindowState(child)->AddObserver(this);
Relayout();
UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED);
+
+ // Only keyboard-initiated actions are recorded here. Dragging cases
+ // are handled in FinishDragging.
+ if (event_source_ != DOCKED_ACTION_SOURCE_UNKNOWN)
+ RecordUmaAction(DOCKED_ACTION_DOCK, event_source_);
}
void DockedWindowLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) {
@@ -848,12 +857,16 @@ void DockedWindowLayoutManager::OnPreWindowStateTypeChange(
if (window != dragged_window_) {
UndockWindow(window);
if (window_state->IsMaximizedOrFullscreen())
- RecordUmaAction(DOCKED_ACTION_MAXIMIZE, DOCKED_ACTION_SOURCE_UNKNOWN);
+ RecordUmaAction(DOCKED_ACTION_MAXIMIZE, event_source_);
+ else
+ RecordUmaAction(DOCKED_ACTION_UNDOCK, event_source_);
}
} else if (window_state->IsMinimized()) {
MinimizeDockedWindow(window_state);
} else if (old_type == wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED) {
RestoreDockedWindow(window_state);
+ } else if (old_type == wm::WINDOW_STATE_TYPE_MINIMIZED) {
+ NOTREACHED() << "Minimized window in docked layout manager";
}
}
@@ -892,7 +905,7 @@ void DockedWindowLayoutManager::OnWindowDestroying(aura::Window* window) {
}
if (window == last_active_window_)
last_active_window_ = NULL;
- RecordUmaAction(DOCKED_ACTION_CLOSE, DOCKED_ACTION_SOURCE_UNKNOWN);
+ RecordUmaAction(DOCKED_ACTION_CLOSE, event_source_);
}
@@ -959,7 +972,7 @@ void DockedWindowLayoutManager::MinimizeDockedWindow(
window_state->window()->Hide();
if (window_state->IsActive())
window_state->Deactivate();
- RecordUmaAction(DOCKED_ACTION_MINIMIZE, DOCKED_ACTION_SOURCE_UNKNOWN);
+ RecordUmaAction(DOCKED_ACTION_MINIMIZE, event_source_);
}
void DockedWindowLayoutManager::RestoreDockedWindow(
@@ -976,7 +989,7 @@ void DockedWindowLayoutManager::RestoreDockedWindow(
// Evict the window if it can no longer be docked because of its height.
if (!CanDockWindow(window, DOCKED_ALIGNMENT_NONE)) {
window_state->Restore();
- RecordUmaAction(DOCKED_ACTION_EVICT, DOCKED_ACTION_SOURCE_UNKNOWN);
+ RecordUmaAction(DOCKED_ACTION_EVICT, event_source_);
return;
}
gfx::Rect bounds(window->bounds());
@@ -984,7 +997,7 @@ void DockedWindowLayoutManager::RestoreDockedWindow(
window->SetBounds(bounds);
window->Show();
MaybeMinimizeChildrenExcept(window);
- RecordUmaAction(DOCKED_ACTION_RESTORE, DOCKED_ACTION_SOURCE_UNKNOWN);
+ RecordUmaAction(DOCKED_ACTION_RESTORE, event_source_);
}
void DockedWindowLayoutManager::RecordUmaAction(DockedAction action,
diff --git a/ash/wm/dock/docked_window_layout_manager.h b/ash/wm/dock/docked_window_layout_manager.h
index 4a918c6..a7b59d4 100644
--- a/ash/wm/dock/docked_window_layout_manager.h
+++ b/ash/wm/dock/docked_window_layout_manager.h
@@ -121,6 +121,14 @@ class ASH_EXPORT DockedWindowLayoutManager
// Used to snap docked windows to the side of screen during drag.
DockedAlignment CalculateAlignment() const;
+ void set_preferred_alignment(DockedAlignment preferred_alignment) {
+ preferred_alignment_ = preferred_alignment;
+ }
+
+ void set_event_source(DockedActionSource event_source) {
+ event_source_ = event_source;
+ }
+
// Returns true when a window can be docked. Windows cannot be docked at the
// edge used by the shelf or the edge opposite from existing dock.
bool CanDockWindow(aura::Window* window, DockedAlignment desired_alignment);
@@ -299,6 +307,12 @@ class ASH_EXPORT DockedWindowLayoutManager
// Side of the screen that the dock is positioned at.
DockedAlignment alignment_;
+ // The preferred alignment of the next window to be added to docked layout.
+ DockedAlignment preferred_alignment_;
+
+ // The current event source
+ DockedActionSource event_source_;
+
// The last active window. Used to maintain stacking order even if no windows
// are currently focused.
aura::Window* last_active_window_;
diff --git a/ash/wm/lock_window_state.cc b/ash/wm/lock_window_state.cc
index 3b8299d..35f1986 100644
--- a/ash/wm/lock_window_state.cc
+++ b/ash/wm/lock_window_state.cc
@@ -45,6 +45,8 @@ void LockWindowState::OnWMEvent(wm::WindowState* window_state,
case wm::WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE:
case wm::WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE:
case wm::WM_EVENT_TOGGLE_MAXIMIZE:
+ case wm::WM_EVENT_CYCLE_SNAP_DOCK_LEFT:
+ case wm::WM_EVENT_CYCLE_SNAP_DOCK_RIGHT:
case wm::WM_EVENT_CENTER:
case wm::WM_EVENT_SNAP_LEFT:
case wm::WM_EVENT_SNAP_RIGHT:
diff --git a/ash/wm/maximize_mode/maximize_mode_window_state.cc b/ash/wm/maximize_mode/maximize_mode_window_state.cc
index 6dafcf8..46345ba 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_state.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_state.cc
@@ -138,6 +138,8 @@ void MaximizeModeWindowState::OnWMEvent(wm::WindowState* window_state,
case wm::WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE:
case wm::WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE:
case wm::WM_EVENT_TOGGLE_MAXIMIZE:
+ case wm::WM_EVENT_CYCLE_SNAP_DOCK_LEFT:
+ case wm::WM_EVENT_CYCLE_SNAP_DOCK_RIGHT:
case wm::WM_EVENT_CENTER:
case wm::WM_EVENT_SNAP_LEFT:
case wm::WM_EVENT_SNAP_RIGHT:
diff --git a/ash/wm/panels/panel_layout_manager.h b/ash/wm/panels/panel_layout_manager.h
index c3ad998..38ff918 100644
--- a/ash/wm/panels/panel_layout_manager.h
+++ b/ash/wm/panels/panel_layout_manager.h
@@ -124,6 +124,7 @@ class ASH_EXPORT PanelLayoutManager
friend class DockedWindowResizerTest;
friend class DockedWindowLayoutManagerTest;
friend class WorkspaceControllerTest;
+ friend class AcceleratorControllerTest;
views::Widget* CreateCalloutWidget();
diff --git a/ash/wm/wm_event.h b/ash/wm/wm_event.h
index c4fade4..ad64a21 100644
--- a/ash/wm/wm_event.h
+++ b/ash/wm/wm_event.h
@@ -54,6 +54,19 @@ enum WMEventType {
// A user requested to toggle fullscreen state.
WM_EVENT_TOGGLE_FULLSCREEN,
+ // A user requested a cycle of dock and snap left.
+ // The way this event is processed is the current window state is used as
+ // the starting state. Assuming normal window start state; if the window can
+ // be snapped left, snap it; otherwise progress to next state. If the window
+ // can be docked left, dock it; otherwise progress to next state. If the
+ // window can be restored; and this isn't the entry condition restore it;
+ // otherwise apply the bounce animation to the window.
+ WM_EVENT_CYCLE_SNAP_DOCK_LEFT,
+
+ // A user requested a cycle of dock and snap right.
+ // See decription of WM_EVENT_CYCLE_SNAP_DOCK_LEFT.
+ WM_EVENT_CYCLE_SNAP_DOCK_RIGHT,
+
// A user requested to center a window.
WM_EVENT_CENTER,