Commit 2aa4ad9d authored by Danton Vu's avatar Danton Vu Committed by Commit Bot

overview: Add scrolling for new overview layout format in tablet mode.

In the new overview layout, scrolling is needed to be able to see each
available window past the sixth window.

R=sammiequon@chromium.org, xdai@chromium.org

Bug: 981174
Change-Id: Idc207bf155e8458231114344650837a5783c8854
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1709876Reviewed-by: default avatarSammie Quon <sammiequon@chromium.org>
Commit-Queue: Danton Vu <dantonvu@google.com>
Cr-Commit-Position: refs/heads/master@{#684035}
parent cef7fe70
...@@ -67,6 +67,10 @@ constexpr float kOverviewInsetRatio = 0.05f; ...@@ -67,6 +67,10 @@ constexpr float kOverviewInsetRatio = 0.05f;
// Additional vertical inset reserved for windows in overview mode. // Additional vertical inset reserved for windows in overview mode.
constexpr float kOverviewVerticalInset = 0.1f; constexpr float kOverviewVerticalInset = 0.1f;
// Number of columns and rows for windows in tablet overview mode.
constexpr int kTabletLayoutCol = 3;
constexpr int kTabletLayoutRow = 2;
// Histogram names for overview enter/exit smoothness in clamshell, // Histogram names for overview enter/exit smoothness in clamshell,
// tablet mode and splitview. // tablet mode and splitview.
constexpr char kOverviewEnterClamshellHistogram[] = constexpr char kOverviewEnterClamshellHistogram[] =
...@@ -1257,6 +1261,30 @@ bool OverviewGrid::MaybeDropItemOnDeskMiniView( ...@@ -1257,6 +1261,30 @@ bool OverviewGrid::MaybeDropItemOnDeskMiniView(
return false; return false;
} }
void OverviewGrid::PrepareScrollLimitMin() {
// Users are not allowed to scroll past the leftmost or rightmost bounds of
// the items on screen in the grid. |scroll_offset_min_| is the amount needed
// to fit the rightmost window into |total_bounds|. The max is zero which is
// default because windows are aligned to the left from the beginning.
gfx::Rect total_bounds = GetGridEffectiveBounds();
total_bounds.Inset(GetGridInsets(total_bounds));
float rightmost_window_right = 0;
for (const auto& window : window_list_) {
if (rightmost_window_right < window->target_bounds().right())
rightmost_window_right = window->target_bounds().right();
}
// |rightmost_window_right| may have been modified by an earlier scroll.
// |scroll_offset_| is added to adjust for that.
rightmost_window_right += scroll_offset_;
scroll_offset_min_ = total_bounds.right() - rightmost_window_right;
}
void OverviewGrid::UpdateScrollOffset(float delta) {
scroll_offset_ += delta;
scroll_offset_ = base::ClampToRange(scroll_offset_, scroll_offset_min_, 0.0f);
PositionWindows(false);
}
void OverviewGrid::MaybeInitDesksWidget() { void OverviewGrid::MaybeInitDesksWidget() {
if (!desks_util::ShouldDesksBarBeCreated() || desks_widget_) if (!desks_util::ShouldDesksBarBeCreated() || desks_widget_)
return; return;
...@@ -1404,8 +1432,8 @@ std::vector<gfx::RectF> OverviewGrid::GetWindowRectsForTabletModeLayout( ...@@ -1404,8 +1432,8 @@ std::vector<gfx::RectF> OverviewGrid::GetWindowRectsForTabletModeLayout(
// animation. // animation.
// Since the number of rows is limited, windows are laid out column-wise so // Since the number of rows is limited, windows are laid out column-wise so
// that the most recently used windows are displayed first. // that the most recently used windows are displayed first.
const int width = total_bounds.width() / 3; const int width = total_bounds.width() / kTabletLayoutCol;
const int height = total_bounds.height() / 2; const int height = total_bounds.height() / kTabletLayoutRow;
size_t window_position = 0u; size_t window_position = 0u;
std::vector<gfx::RectF> rects; std::vector<gfx::RectF> rects;
...@@ -1414,12 +1442,14 @@ std::vector<gfx::RectF> OverviewGrid::GetWindowRectsForTabletModeLayout( ...@@ -1414,12 +1442,14 @@ std::vector<gfx::RectF> OverviewGrid::GetWindowRectsForTabletModeLayout(
rects.push_back(gfx::RectF()); rects.push_back(gfx::RectF());
continue; continue;
} }
const int x = width * (window_position / 2) + total_bounds.x(); const int x =
width * (window_position / 2) + total_bounds.x() + scroll_offset_;
const int y = height * (window_position % 2) + total_bounds.y(); const int y = height * (window_position % 2) + total_bounds.y();
const gfx::RectF bounds(x, y, width, height); const gfx::RectF bounds(x, y, width, height);
rects.push_back(bounds); rects.push_back(bounds);
++window_position; ++window_position;
} }
return rects; return rects;
} }
......
...@@ -265,6 +265,14 @@ class ASH_EXPORT OverviewGrid : public aura::WindowObserver, ...@@ -265,6 +265,14 @@ class ASH_EXPORT OverviewGrid : public aura::WindowObserver,
bool MaybeDropItemOnDeskMiniView(const gfx::Point& screen_location, bool MaybeDropItemOnDeskMiniView(const gfx::Point& screen_location,
OverviewItem* drag_item); OverviewItem* drag_item);
// Prepares the |scroll_offset_min_| as a limit for |scroll_offset| from
// scrolling or positioning windows too far offscreen.
void PrepareScrollLimitMin();
// |delta| is used for updating |scroll_offset_| with new scroll values so
// that windows in tablet overview mode get positioned accordingly.
void UpdateScrollOffset(float delta);
// Returns true if the grid has no more windows. // Returns true if the grid has no more windows.
bool empty() const { return window_list_.empty(); } bool empty() const { return window_list_.empty(); }
...@@ -415,6 +423,14 @@ class ASH_EXPORT OverviewGrid : public aura::WindowObserver, ...@@ -415,6 +423,14 @@ class ASH_EXPORT OverviewGrid : public aura::WindowObserver,
// when reposition windows in tablet overview mode. // when reposition windows in tablet overview mode.
bool suspend_reposition_ = false; bool suspend_reposition_ = false;
// Used by |GetWindowRectsForTabletModeLayout| to shift the x position of the
// overview items.
float scroll_offset_ = 0;
// Value to clamp |scroll_offset| so scrolling stays limited to windows that
// are visible in tablet overview mode.
float scroll_offset_min_ = 0;
DISALLOW_COPY_AND_ASSIGN(OverviewGrid); DISALLOW_COPY_AND_ASSIGN(OverviewGrid);
}; };
......
...@@ -3,10 +3,11 @@ ...@@ -3,10 +3,11 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "ash/wm/overview/overview_grid_pre_event_handler.h" #include "ash/wm/overview/overview_grid_pre_event_handler.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_grid.h"
#include "ash/wm/overview/overview_utils.h" #include "ash/wm/overview/overview_utils.h"
#include "ash/wm/window_util.h"
#include "ui/events/event.h" #include "ui/events/event.h"
namespace ash { namespace ash {
...@@ -21,13 +22,38 @@ void OverviewGridPreEventHandler::OnMouseEvent(ui::MouseEvent* event) { ...@@ -21,13 +22,38 @@ void OverviewGridPreEventHandler::OnMouseEvent(ui::MouseEvent* event) {
} }
void OverviewGridPreEventHandler::OnGestureEvent(ui::GestureEvent* event) { void OverviewGridPreEventHandler::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() == ui::ET_GESTURE_TAP) // TODO(sammiequon): Investigate why scrolling on the bottom of the grid exits
HandleClickOrTap(event); // overview.
switch (event->type()) {
case ui::ET_GESTURE_TAP:
HandleClickOrTap(event);
break;
case ui::ET_GESTURE_SCROLL_BEGIN: {
if (!ShouldUseTabletModeGridLayout())
return;
StartDrag(event->location());
event->SetHandled();
break;
}
case ui::ET_GESTURE_SCROLL_UPDATE: {
if (!ShouldUseTabletModeGridLayout())
return;
UpdateDrag(event->details().scroll_x());
event->SetHandled();
break;
}
case ui::ET_GESTURE_SCROLL_END: {
event->SetHandled();
break;
}
default:
break;
}
} }
void OverviewGridPreEventHandler::HandleClickOrTap(ui::Event* event) { void OverviewGridPreEventHandler::HandleClickOrTap(ui::Event* event) {
CHECK_EQ(ui::EP_PRETARGET, event->phase()); CHECK_EQ(ui::EP_PRETARGET, event->phase());
OverviewController* controller = Shell::Get()->overview_controller(); auto* controller = Shell::Get()->overview_controller();
if (!controller->InOverviewSession()) if (!controller->InOverviewSession())
return; return;
// Events that happen while app list is sliding out during overview should // Events that happen while app list is sliding out during overview should
...@@ -37,4 +63,20 @@ void OverviewGridPreEventHandler::HandleClickOrTap(ui::Event* event) { ...@@ -37,4 +63,20 @@ void OverviewGridPreEventHandler::HandleClickOrTap(ui::Event* event) {
event->StopPropagation(); event->StopPropagation();
} }
void OverviewGridPreEventHandler::StartDrag(const gfx::Point& location) {
// TODO(sammiequon): Investigate if this can be passed in the constructor.
auto* controller = Shell::Get()->overview_controller();
if (!controller->InOverviewSession())
return;
grid_ = controller->overview_session()->GetGridWithRootWindow(
window_util::GetRootWindowAt(location));
grid_->PrepareScrollLimitMin();
}
void OverviewGridPreEventHandler::UpdateDrag(float scroll) {
// Pass new scroll values to update the offset which will also update overview
// mode to position windows according to the scroll values.
grid_->UpdateScrollOffset(scroll);
}
} // namespace ash } // namespace ash
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "ui/events/event_handler.h" #include "ui/events/event_handler.h"
#include "ui/gfx/geometry/point.h"
namespace ui { namespace ui {
class Event; class Event;
...@@ -15,11 +16,13 @@ class MouseEvent; ...@@ -15,11 +16,13 @@ class MouseEvent;
} // namespace ui } // namespace ui
namespace ash { namespace ash {
class OverviewGrid;
// This event handler receives events in the pre-target phase and takes care of // This event handler receives events in the pre-target phase and takes care of
// the following: // the following:
// - Disabling overview mode on touch release. // - Disabling overview mode on touch release.
// - Disabling overview mode on mouse release. // - Disabling overview mode on mouse release.
// - Scrolling through tablet overview mode on scrolling.
class OverviewGridPreEventHandler : public ui::EventHandler { class OverviewGridPreEventHandler : public ui::EventHandler {
public: public:
OverviewGridPreEventHandler(); OverviewGridPreEventHandler();
...@@ -32,6 +35,13 @@ class OverviewGridPreEventHandler : public ui::EventHandler { ...@@ -32,6 +35,13 @@ class OverviewGridPreEventHandler : public ui::EventHandler {
void HandleClickOrTap(ui::Event* event); void HandleClickOrTap(ui::Event* event);
void StartDrag(const gfx::Point& location);
void UpdateDrag(float scroll);
// Cached value of the OverviewGrid that handles a series of gesture scroll
// events.
OverviewGrid* grid_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(OverviewGridPreEventHandler); DISALLOW_COPY_AND_ASSIGN(OverviewGridPreEventHandler);
}; };
......
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