Commit c035b3ff authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

applist: Allow swiping up on shelf to show applist when autohide.

Test: manual
Bug: 881483, 891366
Change-Id: I88c5d7a5d41f7ef4013c84debf5c4e963f891d21
Reviewed-on: https://chromium-review.googlesource.com/c/1279356
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#599778}
parent e89d87c7
......@@ -729,7 +729,8 @@ bool AppListControllerImpl::ProcessHomeLauncherGesture(
return home_launcher_gesture_handler_->OnScrollEvent(
screen_location, event->details().scroll_y());
case ui::ET_GESTURE_END:
return home_launcher_gesture_handler_->OnReleaseEvent(screen_location);
return home_launcher_gesture_handler_->OnReleaseEvent(
screen_location, /*out_dragged_down=*/nullptr);
default:
break;
}
......
......@@ -58,10 +58,6 @@ bool CanProcessWindow(aura::Window* window,
if (!window)
return false;
// Window should not be fullscreen as we do not allow swiping up when auto
// hide for shelf.
DCHECK(!wm::GetWindowState(window)->IsFullscreen());
if (!window->IsVisible() &&
mode == HomeLauncherGestureHandler::Mode::kSlideUpToShow) {
return false;
......@@ -208,6 +204,7 @@ bool HomeLauncherGestureHandler::OnPressEvent(Mode mode,
return false;
mode_ = mode;
initial_event_location_ = location;
last_event_location_ = base::make_optional(location);
UpdateWindows(0.0, /*animate=*/false);
......@@ -221,17 +218,29 @@ bool HomeLauncherGestureHandler::OnScrollEvent(const gfx::Point& location,
last_event_location_ = base::make_optional(location);
last_scroll_y_ = scroll_y;
if (mode_ == Mode::kSlideUpToShow &&
(*last_event_location_ - initial_event_location_).y() > 0) {
UpdateWindows(0.0, /*animate=*/false);
return true;
}
DCHECK(display_.is_valid());
UpdateWindows(GetHeightInWorkAreaAsRatio(location, display_.work_area()),
/*animate=*/false);
return true;
}
bool HomeLauncherGestureHandler::OnReleaseEvent(const gfx::Point& location) {
bool HomeLauncherGestureHandler::OnReleaseEvent(const gfx::Point& location,
bool* out_dragged_down) {
if (!IsDragInProgress())
return false;
last_event_location_ = base::make_optional(location);
if (out_dragged_down) {
DCHECK_EQ(mode_, Mode::kSlideUpToShow);
*out_dragged_down =
(*last_event_location_ - initial_event_location_).y() > 0;
}
AnimateToFinalState();
return true;
}
......
......@@ -53,7 +53,7 @@ class ASH_EXPORT HomeLauncherGestureHandler : aura::WindowObserver,
// was not processed.
bool OnPressEvent(Mode mode, const gfx::Point& location);
bool OnScrollEvent(const gfx::Point& location, float scroll_y);
bool OnReleaseEvent(const gfx::Point& location);
bool OnReleaseEvent(const gfx::Point& location, bool* out_dragged_down);
// Cancel a current drag and animates the items to their final state based on
// |last_event_location_|.
......@@ -155,6 +155,8 @@ class ASH_EXPORT HomeLauncherGestureHandler : aura::WindowObserver,
// hidden so the home launcher is visible when swiping up.
std::vector<aura::Window*> hidden_windows_;
gfx::Point initial_event_location_;
// Tracks the location of the last received event in screen coordinates. Empty
// if there is currently no window being processed.
base::Optional<gfx::Point> last_event_location_;
......
......@@ -5,6 +5,7 @@
#include "ash/app_list/home_launcher_gesture_handler.h"
#include "ash/app_list/app_list_controller_impl.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/overview/window_selector_controller.h"
......@@ -47,6 +48,18 @@ class HomeLauncherGestureHandlerTest : public AshTestBase {
return Shell::Get()->app_list_controller()->home_launcher_gesture_handler();
}
void DoPress(Mode mode) {
DCHECK_NE(mode, Mode::kNone);
gfx::Point press_location;
if (mode == Mode::kSlideUpToShow) {
press_location = Shelf::ForWindow(Shell::GetPrimaryRootWindow())
->GetIdealBounds()
.CenterPoint();
}
GetGestureHandler()->OnPressEvent(mode, press_location);
}
private:
DISALLOW_COPY_AND_ASSIGN(HomeLauncherGestureHandlerTest);
};
......@@ -54,26 +67,26 @@ class HomeLauncherGestureHandlerTest : public AshTestBase {
// Tests that the gesture handler will not have a window to act on if there are
// none in the mru list.
TEST_F(HomeLauncherGestureHandlerTest, NeedsOneWindowToShow) {
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
DoPress(Mode::kSlideUpToShow);
EXPECT_FALSE(GetGestureHandler()->window());
auto window = CreateWindowForTesting();
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
DoPress(Mode::kSlideUpToShow);
EXPECT_TRUE(GetGestureHandler()->window());
}
// Tests that the gesture handler will not have a window to act on if there are
// none in the mru list, or if they are not minimized.
TEST_F(HomeLauncherGestureHandlerTest, NeedsOneMinimizedWindowToHide) {
GetGestureHandler()->OnPressEvent(Mode::kSlideDownToHide, gfx::Point());
DoPress(Mode::kSlideDownToHide);
EXPECT_FALSE(GetGestureHandler()->window());
auto window = CreateWindowForTesting();
GetGestureHandler()->OnPressEvent(Mode::kSlideDownToHide, gfx::Point());
DoPress(Mode::kSlideDownToHide);
EXPECT_FALSE(GetGestureHandler()->window());
wm::GetWindowState(window.get())->Minimize();
GetGestureHandler()->OnPressEvent(Mode::kSlideDownToHide, gfx::Point());
DoPress(Mode::kSlideDownToHide);
EXPECT_TRUE(GetGestureHandler()->window());
}
......@@ -90,7 +103,7 @@ TEST_F(HomeLauncherGestureHandlerTest, ShowWindowsAreHidden) {
// Test that the most recently activated window is visible, but the others are
// not.
::wm::ActivateWindow(window1.get());
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
DoPress(Mode::kSlideUpToShow);
EXPECT_TRUE(window1->IsVisible());
EXPECT_FALSE(window2->IsVisible());
EXPECT_FALSE(window3->IsVisible());
......@@ -104,14 +117,14 @@ TEST_F(HomeLauncherGestureHandlerTest, CancellingSlideUp) {
// Tests that when cancelling a scroll that was on the bottom half, the window
// is still visible.
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
DoPress(Mode::kSlideUpToShow);
GetGestureHandler()->OnScrollEvent(gfx::Point(0, 300), 1.f);
GetGestureHandler()->Cancel();
EXPECT_TRUE(window->IsVisible());
// Tests that when cancelling a scroll that was on the top half, the window is
// now invisible.
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
DoPress(Mode::kSlideUpToShow);
GetGestureHandler()->OnScrollEvent(gfx::Point(0, 100), 1.f);
GetGestureHandler()->Cancel();
EXPECT_FALSE(window->IsVisible());
......@@ -125,9 +138,9 @@ TEST_F(HomeLauncherGestureHandlerTest, FlingingSlideUp) {
auto window = CreateWindowForTesting();
ASSERT_TRUE(window->IsVisible());
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
DoPress(Mode::kSlideUpToShow);
GetGestureHandler()->OnScrollEvent(gfx::Point(0, 300), -10.f);
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300));
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300), nullptr);
EXPECT_FALSE(window->IsVisible());
}
......@@ -140,12 +153,31 @@ TEST_F(HomeLauncherGestureHandlerTest, FlingingSlideDown) {
wm::GetWindowState(window.get())->Minimize();
ASSERT_FALSE(window->IsVisible());
GetGestureHandler()->OnPressEvent(Mode::kSlideDownToHide, gfx::Point());
DoPress(Mode::kSlideDownToHide);
GetGestureHandler()->OnScrollEvent(gfx::Point(0, 100), 10.f);
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 100));
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 100), nullptr);
EXPECT_TRUE(window->IsVisible());
}
TEST_F(HomeLauncherGestureHandlerTest, SlidingBelowPressPoint) {
UpdateDisplay("400x456");
auto window = CreateWindowForTesting();
ASSERT_TRUE(window->IsVisible());
// Tests that the windows transform does not change when trying to slide below
// the press event location.
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point(0, 400));
GetGestureHandler()->OnScrollEvent(gfx::Point(0, 420), 1.f);
EXPECT_EQ(gfx::Transform(), window->transform());
// Tests that OnReleaseEvent returns true when checking if the release point
// is below the press point.
bool released_below;
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 420), &released_below);
EXPECT_TRUE(released_below);
}
// Tests that the home launcher gestures work with overview mode as expected.
TEST_F(HomeLauncherGestureHandlerTest, OverviewMode) {
UpdateDisplay("400x456");
......@@ -162,7 +194,7 @@ TEST_F(HomeLauncherGestureHandlerTest, OverviewMode) {
window1->transform().To2dTranslation().y();
const int window2_initial_translation =
window2->transform().To2dTranslation().y();
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
DoPress(Mode::kSlideUpToShow);
EXPECT_FALSE(GetGestureHandler()->window());
// Tests that while scrolling the window transform changes.
......@@ -174,7 +206,7 @@ TEST_F(HomeLauncherGestureHandlerTest, OverviewMode) {
// Tests that after releasing at below the halfway point, we remain in
// overview mode.
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300));
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300), nullptr);
EXPECT_TRUE(controller->IsSelecting());
EXPECT_EQ(window1_initial_translation,
window1->transform().To2dTranslation().y());
......@@ -183,8 +215,8 @@ TEST_F(HomeLauncherGestureHandlerTest, OverviewMode) {
// Tests that after releasing on the bottom half, overview mode has been
// exited, and the two windows have been minimized to show the home launcher.
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 100));
DoPress(Mode::kSlideUpToShow);
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 100), nullptr);
EXPECT_FALSE(controller->IsSelecting());
EXPECT_TRUE(wm::GetWindowState(window1.get())->IsMinimized());
EXPECT_TRUE(wm::GetWindowState(window2.get())->IsMinimized());
......@@ -210,7 +242,7 @@ TEST_F(HomeLauncherGestureHandlerTest, SplitviewOneSnappedWindow) {
const int window2_initial_translation =
window2->transform().To2dTranslation().y();
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
DoPress(Mode::kSlideUpToShow);
EXPECT_EQ(window1.get(), GetGestureHandler()->window());
// Tests that while scrolling the window transforms change.
......@@ -221,7 +253,7 @@ TEST_F(HomeLauncherGestureHandlerTest, SplitviewOneSnappedWindow) {
// Tests that after releasing at below the halfway point, we remain in
// both splitview and overview mode.
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300));
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300), nullptr);
EXPECT_EQ(window1->transform(), gfx::Transform());
EXPECT_EQ(window2_initial_translation,
window2->transform().To2dTranslation().y());
......@@ -230,8 +262,8 @@ TEST_F(HomeLauncherGestureHandlerTest, SplitviewOneSnappedWindow) {
// Tests that after releasing on the bottom half, overivew and splitview have
// both been exited, and both windows are minimized to show the home launcher.
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 100));
DoPress(Mode::kSlideUpToShow);
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 100), nullptr);
EXPECT_FALSE(window_selector_controller->IsSelecting());
EXPECT_FALSE(split_view_controller->IsSplitViewModeActive());
EXPECT_TRUE(wm::GetWindowState(window1.get())->IsMinimized());
......@@ -256,7 +288,7 @@ TEST_F(HomeLauncherGestureHandlerTest, SplitviewTwoSnappedWindows) {
// Make |window1| the most recent used window. It should be the main window in
// HomeLauncherGestureHandler.
::wm::ActivateWindow(window1.get());
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
DoPress(Mode::kSlideUpToShow);
EXPECT_EQ(window1.get(), GetGestureHandler()->window());
EXPECT_EQ(window2.get(), GetGestureHandler()->window2());
......@@ -267,15 +299,15 @@ TEST_F(HomeLauncherGestureHandlerTest, SplitviewTwoSnappedWindows) {
// Tests that after releasing at below the halfway point, we remain in
// splitview.
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300));
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300), nullptr);
EXPECT_EQ(window1->transform(), gfx::Transform());
EXPECT_EQ(window2->transform(), gfx::Transform());
EXPECT_TRUE(split_view_controller->IsSplitViewModeActive());
// Tests that after releasing on the bottom half, splitview has been ended,
// and the two windows have been minimized to show the home launcher.
GetGestureHandler()->OnPressEvent(Mode::kSlideUpToShow, gfx::Point());
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 100));
DoPress(Mode::kSlideUpToShow);
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 100), nullptr);
EXPECT_FALSE(split_view_controller->IsSplitViewModeActive());
EXPECT_TRUE(wm::GetWindowState(window1.get())->IsMinimized());
EXPECT_TRUE(wm::GetWindowState(window2.get())->IsMinimized());
......@@ -313,7 +345,7 @@ INSTANTIATE_TEST_CASE_P(,
TEST_P(HomeLauncherModeGestureHandlerTest, TransformAndOpacityChangesOnScroll) {
auto window = CreateWindowForTesting();
GetGestureHandler()->OnPressEvent(mode_, gfx::Point());
DoPress(mode_);
ASSERT_TRUE(GetGestureHandler()->window());
// Test that on scrolling to a point on the top half of the work area, the
......@@ -341,7 +373,7 @@ TEST_P(HomeLauncherModeGestureHandlerTest, BelowHalfShowsWindow) {
auto window2 = CreateWindowForTesting();
auto window1 = CreateWindowForTesting();
GetGestureHandler()->OnPressEvent(mode_, gfx::Point());
DoPress(mode_);
ASSERT_TRUE(GetGestureHandler()->window());
ASSERT_FALSE(window2->IsVisible());
ASSERT_FALSE(window3->IsVisible());
......@@ -352,7 +384,7 @@ TEST_P(HomeLauncherModeGestureHandlerTest, BelowHalfShowsWindow) {
EXPECT_NE(1.f, window1->layer()->opacity());
// Tests the transform and opacity have returned to the identity and 1.
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300));
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300), nullptr);
EXPECT_EQ(gfx::Transform(), window1->transform());
EXPECT_EQ(1.f, window1->layer()->opacity());
......@@ -373,13 +405,13 @@ TEST_P(HomeLauncherModeGestureHandlerTest, AboveHalfReleaseMinimizesWindow) {
auto window2 = CreateWindowForTesting();
auto window1 = CreateWindowForTesting();
GetGestureHandler()->OnPressEvent(mode_, gfx::Point());
DoPress(mode_);
ASSERT_TRUE(GetGestureHandler()->window());
ASSERT_FALSE(window2->IsVisible());
ASSERT_FALSE(window3->IsVisible());
// Test that |window1| is minimized on release.
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 100));
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 100), nullptr);
EXPECT_TRUE(wm::GetWindowState(window1.get())->IsMinimized());
// The rest of the windows remain invisible, to show the home launcher.
......@@ -401,7 +433,7 @@ TEST_P(HomeLauncherModeGestureHandlerTest, WindowWithTransientChild) {
::wm::AddTransientChild(parent.get(), child.get());
// |parent| should be the window that is getting hidden.
GetGestureHandler()->OnPressEvent(mode_, gfx::Point());
DoPress(mode_);
ASSERT_EQ(parent.get(), GetGestureHandler()->window());
// Tests that after scrolling to the halfway point, the transient child's
......@@ -413,7 +445,7 @@ TEST_P(HomeLauncherModeGestureHandlerTest, WindowWithTransientChild) {
// Tests that after releasing on the bottom half, the transient child reverts
// to its original values.
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300));
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 300), nullptr);
EXPECT_EQ(1.0f, child->layer()->opacity());
EXPECT_EQ(gfx::Transform(), child->transform());
}
......@@ -423,7 +455,7 @@ TEST_P(HomeLauncherModeGestureHandlerTest, WindowWithTransientChild) {
TEST_P(HomeLauncherModeGestureHandlerTest, EndScrollOnTabletModeEnd) {
auto window = CreateWindowForTesting();
GetGestureHandler()->OnPressEvent(mode_, gfx::Point());
DoPress(mode_);
ASSERT_TRUE(GetGestureHandler()->window());
// Scroll to a point above the halfway mark of the work area.
......@@ -456,7 +488,7 @@ TEST_P(HomeLauncherModeGestureHandlerTest, AnimatingToEndResetsState) {
}
// Tests that the variables which change when dragging are as expected.
GetGestureHandler()->OnPressEvent(mode_, gfx::Point());
DoPress(mode_);
EXPECT_EQ(window1.get(), GetGestureHandler()->window());
EXPECT_TRUE(GetGestureHandler()->last_event_location_);
EXPECT_EQ(mode_, GetGestureHandler()->mode_);
......@@ -467,7 +499,7 @@ TEST_P(HomeLauncherModeGestureHandlerTest, AnimatingToEndResetsState) {
EXPECT_FALSE(GetGestureHandler()->transient_descendants_values_.empty());
// Tests that after a drag, the variables are either null or empty.
GetGestureHandler()->OnReleaseEvent(gfx::Point(10, 10));
GetGestureHandler()->OnReleaseEvent(gfx::Point(10, 10), nullptr);
EXPECT_FALSE(GetGestureHandler()->window());
EXPECT_FALSE(GetGestureHandler()->last_event_location_);
EXPECT_EQ(Mode::kNone, GetGestureHandler()->mode_);
......
......@@ -1212,7 +1212,7 @@ void ShelfLayoutManager::StartGestureDrag(
} else {
HomeLauncherGestureHandler* home_launcher_handler =
Shell::Get()->app_list_controller()->home_launcher_gesture_handler();
if (home_launcher_handler && visibility_state() == SHELF_VISIBLE &&
if (home_launcher_handler && IsVisible() &&
home_launcher_handler->OnPressEvent(
HomeLauncherGestureHandler::Mode::kSlideUpToShow,
gesture_in_screen.location())) {
......@@ -1237,7 +1237,7 @@ void ShelfLayoutManager::UpdateGestureDrag(
const ui::GestureEvent& gesture_in_screen) {
HomeLauncherGestureHandler* home_launcher_handler =
Shell::Get()->app_list_controller()->home_launcher_gesture_handler();
if (home_launcher_handler && visibility_state() == SHELF_VISIBLE &&
if (home_launcher_handler && IsVisible() &&
home_launcher_handler->OnScrollEvent(
gesture_in_screen.location(),
gesture_in_screen.details().scroll_y())) {
......@@ -1301,8 +1301,16 @@ void ShelfLayoutManager::CompleteAppListDrag(
HomeLauncherGestureHandler* home_launcher_handler =
Shell::Get()->app_list_controller()->home_launcher_gesture_handler();
if (home_launcher_handler && visibility_state() == SHELF_VISIBLE &&
home_launcher_handler->OnReleaseEvent(gesture_in_screen.location())) {
bool dragged_down;
if (home_launcher_handler && IsVisible() &&
home_launcher_handler->OnReleaseEvent(gesture_in_screen.location(),
&dragged_down)) {
if (dragged_down && visibility_state() == SHELF_AUTO_HIDE) {
DCHECK_EQ(SHELF_AUTO_HIDE_SHOWN, gesture_drag_auto_hide_state_);
gesture_drag_auto_hide_state_ = SHELF_AUTO_HIDE_HIDDEN;
gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS;
UpdateVisibilityState();
}
gesture_drag_status_ = GESTURE_DRAG_NONE;
return;
}
......
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