Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1607)

Unified Diff: ash/wm/overview/window_selector.cc

Issue 251103005: Added arrow key navigation to Overview Mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added reposition animation, shortened movement time, fixed what Terry commented. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ash/wm/overview/window_selector.cc
diff --git a/ash/wm/overview/window_selector.cc b/ash/wm/overview/window_selector.cc
index 04fbccb4283a9010e31878dcca72e0f254e9e2c1..66f1d02895b66998220169ab48fe21ee0fa817b3 100644
--- a/ash/wm/overview/window_selector.cc
+++ b/ash/wm/overview/window_selector.cc
@@ -10,11 +10,11 @@
#include "ash/ash_switches.h"
#include "ash/metrics/user_metrics_recorder.h"
#include "ash/root_window_controller.h"
-#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/switchable_windows.h"
#include "ash/wm/overview/scoped_transform_overview_window.h"
+#include "ash/wm/overview/window_grid.h"
#include "ash/wm/overview/window_selector_delegate.h"
#include "ash/wm/overview/window_selector_item.h"
#include "ash/wm/overview/window_selector_panels.h"
@@ -30,7 +30,6 @@
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_observer.h"
-#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event.h"
#include "ui/gfx/screen.h"
@@ -43,81 +42,20 @@ namespace ash {
namespace {
-// Conceptually the window overview is a table or grid of cells having this
-// fixed aspect ratio. The number of columns is determined by maximizing the
-// area of them based on the number of windows.
-const float kCardAspectRatio = 4.0f / 3.0f;
-
-// In the conceptual overview table, the window margin is the space reserved
-// around the window within the cell. This margin does not overlap so the
-// closest distance between adjacent windows will be twice this amount.
-const int kWindowMargin = 30;
-
-// The minimum number of cards along the major axis (i.e. horizontally on a
-// landscape orientation).
-const int kMinCardsMajor = 3;
-
-// A comparator for locating a given target window.
-struct WindowSelectorItemComparator
- : public std::unary_function<WindowSelectorItem*, bool> {
- explicit WindowSelectorItemComparator(const aura::Window* target_window)
- : target(target_window) {
+// A comparator for locating a grid with a given root window.
+struct RootWindowGridComparator
+ : public std::unary_function<WindowGrid*, bool> {
+ explicit RootWindowGridComparator(const aura::Window* root_window)
+ : root_window_(root_window) {
}
- bool operator()(WindowSelectorItem* window) const {
- return window->HasSelectableWindow(target);
+ bool operator()(WindowGrid* grid) const {
+ return (grid->root_window() == root_window_);
}
- const aura::Window* target;
-};
-
-// An observer which holds onto the passed widget until the animation is
-// complete.
-class CleanupWidgetAfterAnimationObserver : public ui::LayerAnimationObserver {
- public:
- explicit CleanupWidgetAfterAnimationObserver(
- scoped_ptr<views::Widget> widget);
-
- // ui::LayerAnimationObserver:
- virtual void OnLayerAnimationEnded(
- ui::LayerAnimationSequence* sequence) OVERRIDE;
- virtual void OnLayerAnimationAborted(
- ui::LayerAnimationSequence* sequence) OVERRIDE;
- virtual void OnLayerAnimationScheduled(
- ui::LayerAnimationSequence* sequence) OVERRIDE;
-
- private:
- virtual ~CleanupWidgetAfterAnimationObserver();
-
- scoped_ptr<views::Widget> widget_;
-
- DISALLOW_COPY_AND_ASSIGN(CleanupWidgetAfterAnimationObserver);
+ const aura::Window* root_window_;
};
-CleanupWidgetAfterAnimationObserver::CleanupWidgetAfterAnimationObserver(
- scoped_ptr<views::Widget> widget)
- : widget_(widget.Pass()) {
- widget_->GetNativeWindow()->layer()->GetAnimator()->AddObserver(this);
-}
-
-CleanupWidgetAfterAnimationObserver::~CleanupWidgetAfterAnimationObserver() {
- widget_->GetNativeWindow()->layer()->GetAnimator()->RemoveObserver(this);
-}
-
-void CleanupWidgetAfterAnimationObserver::OnLayerAnimationEnded(
- ui::LayerAnimationSequence* sequence) {
- delete this;
-}
-
-void CleanupWidgetAfterAnimationObserver::OnLayerAnimationAborted(
- ui::LayerAnimationSequence* sequence) {
- delete this;
-}
-
-void CleanupWidgetAfterAnimationObserver::OnLayerAnimationScheduled(
- ui::LayerAnimationSequence* sequence) {
-}
-
// A comparator for locating a selectable window given a targeted window.
struct WindowSelectorItemTargetComparator
: public std::unary_function<WindowSelectorItem*, bool> {
@@ -164,7 +102,8 @@ WindowSelector::WindowSelector(const WindowList& windows,
: delegate_(delegate),
restore_focus_window_(aura::client::GetFocusClient(
Shell::GetPrimaryRootWindow())->GetFocusedWindow()),
- ignore_activations_(false) {
+ ignore_activations_(false),
+ root_index_(0) {
DCHECK(delegate_);
if (restore_focus_window_)
@@ -283,8 +222,30 @@ void WindowSelector::OnKeyEvent(ui::KeyEvent* event) {
if (event->type() != ui::ET_KEY_PRESSED)
return;
- if (event->key_code() == ui::VKEY_ESCAPE)
- CancelSelection();
+ switch (event->key_code()) {
+ case ui::VKEY_ESCAPE:
+ CancelSelection();
+ break;
+ case ui::VKEY_UP:
+ Move(WindowSelector::UP);
flackr 2014/05/29 20:04:25 I think any of these handled events should set han
Nina 2014/06/02 22:04:38 Done.
+ break;
+ case ui::VKEY_DOWN:
+ Move(WindowSelector::DOWN);
+ break;
+ case ui::VKEY_RIGHT:
+ Move(WindowSelector::RIGHT);
+ break;
+ case ui::VKEY_LEFT:
+ Move(WindowSelector::LEFT);
+ break;
+ case ui::VKEY_RETURN:
+ SelectWindow(
+ grid_list_[root_index_]->SelectedWindow()->SelectionWindow());
+ break;
+ default:
+ // Not a key we are interested in.
+ break;
+ }
}
void WindowSelector::OnMouseEvent(ui::MouseEvent* event) {
@@ -353,30 +314,33 @@ void WindowSelector::OnWindowAdded(aura::Window* new_window) {
}
void WindowSelector::OnWindowDestroying(aura::Window* window) {
- // window is one of a container, the restore_focus_window and/or
- // one of the selectable windows in overview.
- ScopedVector<WindowSelectorItem>::iterator iter =
- std::find_if(windows_.begin(), windows_.end(),
- WindowSelectorItemComparator(window));
+ WindowSelectorItem* removed_item = NULL;
+
+ // Find the grid corresponding to the window's root window.
+ ScopedVector<WindowGrid>::iterator grid_iter =
+ std::find_if(grid_list_.begin(), grid_list_.end(),
+ RootWindowGridComparator(window->GetRootWindow()));
+
+ DCHECK(grid_iter != grid_list_.end());
+ removed_item = (*grid_iter)->RemoveWindow(window);
+
window->RemoveObserver(this);
observed_windows_.erase(window);
if (window == restore_focus_window_)
restore_focus_window_ = NULL;
- if (iter == windows_.end())
- return;
- (*iter)->RemoveWindow(window);
- // If there are still windows in this selector entry then the overview is
- // still active and the active selection remains the same.
- if (!(*iter)->empty())
+ // If removing the window doesn't cause the removal of an item, we are done.
+ if (!removed_item)
return;
- windows_.erase(iter);
- if (windows_.empty()) {
- CancelSelection();
- return;
+ windows_.erase(std::find(windows_.begin(), windows_.end(), removed_item));
flackr 2014/05/29 20:04:25 So we have two vectors of WindowSelectorItem point
Nina 2014/06/02 22:04:38 I refactored the code so that the WindowGrid owns
+
+ if (grid_iter != grid_list_.end() && (*grid_iter)->empty()) {
flackr 2014/05/29 20:04:25 if we have a removed item, it must have come from
Nina 2014/06/02 22:04:38 Done.
+ grid_list_.erase(grid_iter);
+ root_index_ = 0;
+ if (grid_list_.size() == 0)
+ CancelSelection();
}
- PositionWindows(true);
}
void WindowSelector::OnWindowBoundsChanged(aura::Window* window,
@@ -426,7 +390,7 @@ void WindowSelector::StartOverview() {
iter != windows_.end(); ++iter) {
(*iter)->PrepareForOverview();
}
- PositionWindows(/* animate */ true);
+ PositionWindows(true);
flackr 2014/05/29 20:04:25 Why remove the animate comment?
Nina 2014/06/02 22:04:38 Hmmm that slipped. Restored.
DCHECK(!windows_.empty());
cursor_client_ = aura::client::GetCursorClient(
windows_.front()->GetRootWindow());
@@ -451,57 +415,17 @@ void WindowSelector::StartOverview() {
}
void WindowSelector::PositionWindows(bool animate) {
+ grid_list_.clear();
flackr 2014/05/29 20:04:25 Instead of rebuilding grid_list_, can we construct
Nina 2014/06/02 22:04:38 I believe it is still better to handle window acti
aura::Window::Windows root_window_list = Shell::GetAllRootWindows();
- for (size_t i = 0; i < root_window_list.size(); ++i)
- PositionWindowsFromRoot(root_window_list[i], animate);
-}
-
-void WindowSelector::PositionWindowsFromRoot(aura::Window* root_window,
- bool animate) {
- std::vector<WindowSelectorItem*> windows;
- for (WindowSelectorItemList::iterator iter = windows_.begin();
- iter != windows_.end(); ++iter) {
- if ((*iter)->GetRootWindow() == root_window)
- windows.push_back(*iter);
- }
-
- if (windows.empty())
- return;
-
- gfx::Size window_size;
- gfx::Rect total_bounds = ScreenUtil::ConvertRectToScreen(
- root_window,
- ScreenUtil::GetDisplayWorkAreaBoundsInParent(
- Shell::GetContainer(root_window, kShellWindowId_DefaultContainer)));
-
- // Find the minimum number of windows per row that will fit all of the
- // windows on screen.
- size_t columns = std::max(
- total_bounds.width() > total_bounds.height() ? kMinCardsMajor : 1,
- static_cast<int>(ceil(sqrt(total_bounds.width() * windows.size() /
- (kCardAspectRatio * total_bounds.height())))));
- size_t rows = ((windows.size() + columns - 1) / columns);
- window_size.set_width(std::min(
- static_cast<int>(total_bounds.width() / columns),
- static_cast<int>(total_bounds.height() * kCardAspectRatio / rows)));
- window_size.set_height(window_size.width() / kCardAspectRatio);
-
- // Calculate the X and Y offsets necessary to center the grid.
- int x_offset = total_bounds.x() + ((windows.size() >= columns ? 0 :
- (columns - windows.size()) * window_size.width()) +
- (total_bounds.width() - columns * window_size.width())) / 2;
- int y_offset = total_bounds.y() + (total_bounds.height() -
- rows * window_size.height()) / 2;
- for (size_t i = 0; i < windows.size(); ++i) {
- gfx::Transform transform;
- int column = i % columns;
- int row = i / columns;
- gfx::Rect target_bounds(window_size.width() * column + x_offset,
- window_size.height() * row + y_offset,
- window_size.width(),
- window_size.height());
- target_bounds.Inset(kWindowMargin, kWindowMargin);
- windows[i]->SetBounds(root_window, target_bounds, animate);
+ for (size_t i = 0; i < root_window_list.size(); ++i) {
+ std::vector<WindowSelectorItem*> windows;
+ for (WindowSelectorItemList::iterator iter = windows_.begin();
+ iter != windows_.end(); ++iter) {
+ if ((*iter)->GetRootWindow() == root_window_list[i])
+ windows.push_back(*iter);
+ }
+ if (!windows.empty())
+ grid_list_.push_back(new WindowGrid(root_window_list[i], windows));
}
}
@@ -581,4 +505,21 @@ aura::Window* WindowSelector::GetTargetedWindow(aura::Window* window) {
return NULL;
}
+void WindowSelector::Move(Direction direction) {
+ if (!grid_list_[root_index_]->is_selecting()) {
+ grid_list_[root_index_]->CreateSelectionWidget(direction);
flackr 2014/05/29 20:04:25 This seems like something calling GridList::Move c
Nina 2014/06/02 22:04:38 Done.
+ return;
+ }
+ if (grid_list_[root_index_]->Move(direction)) {
+ // The grid reported that the movement command corresponds to the next
+ // root window, identify it and call Move() on it to initialize the
+ // selection widget.
+ if (root_index_ >= grid_list_.size() - 1)
+ root_index_ = 0;
+ else
+ root_index_++;
flackr 2014/05/29 20:04:25 root_index_ = (root_index + 1) % grid_list_.size()
Nina 2014/06/02 22:04:38 Done.
+ grid_list_[root_index_]->CreateSelectionWidget(direction);
+ }
+}
+
} // namespace ash

Powered by Google App Engine
This is Rietveld 408576698