diff options
author | dtapuska <dtapuska@chromium.org> | 2014-10-03 13:10:04 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-03 20:10:21 +0000 |
commit | c6e5e38c6843add6e7aa5d427958164d0550f20b (patch) | |
tree | 706bfbd4c053bad09df4099f37aaceadb7c407c7 /ash/wm | |
parent | 3a8252cdcdf60ad0a6a5ed2ba573801a13117ef0 (diff) | |
download | chromium_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.cc | 108 | ||||
-rw-r--r-- | ash/wm/dock/dock_types.h | 1 | ||||
-rw-r--r-- | ash/wm/dock/docked_window_layout_manager.cc | 27 | ||||
-rw-r--r-- | ash/wm/dock/docked_window_layout_manager.h | 14 | ||||
-rw-r--r-- | ash/wm/lock_window_state.cc | 2 | ||||
-rw-r--r-- | ash/wm/maximize_mode/maximize_mode_window_state.cc | 2 | ||||
-rw-r--r-- | ash/wm/panels/panel_layout_manager.h | 1 | ||||
-rw-r--r-- | ash/wm/wm_event.h | 13 |
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, |