Commit b486411b authored by minch's avatar minch Committed by Commit Bot

Swiping from left edge to go to previous page.

Bug: 1002733
Change-Id: Ia298bce1dd101fbb96af3d066ac4a04f05789013
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1797462Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarXiaoqian Dai <xdai@chromium.org>
Commit-Queue: Min Chen <minch@chromium.org>
Cr-Commit-Position: refs/heads/master@{#697337}
parent 6892a730
...@@ -90,6 +90,9 @@ const base::Feature kUnifiedMessageCenterRefactor{ ...@@ -90,6 +90,9 @@ const base::Feature kUnifiedMessageCenterRefactor{
const base::Feature kEnableBackgroundBlur{"EnableBackgroundBlur", const base::Feature kEnableBackgroundBlur{"EnableBackgroundBlur",
base::FEATURE_DISABLED_BY_DEFAULT}; base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kSwipingFromLeftEdgeToGoBack{
"SwipingFromLeftEdgeToGoBack", base::FEATURE_DISABLED_BY_DEFAULT};
bool IsHideArcMediaNotificationsEnabled() { bool IsHideArcMediaNotificationsEnabled() {
return base::FeatureList::IsEnabled(kMediaSessionNotification) && return base::FeatureList::IsEnabled(kMediaSessionNotification) &&
base::FeatureList::IsEnabled(kHideArcMediaNotifications); base::FeatureList::IsEnabled(kHideArcMediaNotifications);
...@@ -167,5 +170,9 @@ bool IsBackgroundBlurEnabled() { ...@@ -167,5 +170,9 @@ bool IsBackgroundBlurEnabled() {
return base::FeatureList::IsEnabled(kEnableBackgroundBlur); return base::FeatureList::IsEnabled(kEnableBackgroundBlur);
} }
bool IsSwipingFromLeftEdgeToGoBackEnabled() {
return base::FeatureList::IsEnabled(kSwipingFromLeftEdgeToGoBack);
}
} // namespace features } // namespace features
} // namespace ash } // namespace ash
...@@ -115,6 +115,10 @@ ASH_PUBLIC_EXPORT extern const base::Feature kEnableBackgroundBlur; ...@@ -115,6 +115,10 @@ ASH_PUBLIC_EXPORT extern const base::Feature kEnableBackgroundBlur;
// the UnifiedSystemTrayView. // the UnifiedSystemTrayView.
ASH_PUBLIC_EXPORT extern const base::Feature kUnifiedMessageCenterRefactor; ASH_PUBLIC_EXPORT extern const base::Feature kUnifiedMessageCenterRefactor;
// Enables going back to previous page while swiping from the left edge of the
// display. Only for tablet mode.
ASH_PUBLIC_EXPORT extern const base::Feature kSwipingFromLeftEdgeToGoBack;
ASH_PUBLIC_EXPORT bool IsHideArcMediaNotificationsEnabled(); ASH_PUBLIC_EXPORT bool IsHideArcMediaNotificationsEnabled();
ASH_PUBLIC_EXPORT bool IsKeyboardShortcutViewerAppEnabled(); ASH_PUBLIC_EXPORT bool IsKeyboardShortcutViewerAppEnabled();
...@@ -151,6 +155,8 @@ ASH_PUBLIC_EXPORT bool IsUnifiedMessageCenterRefactorEnabled(); ...@@ -151,6 +155,8 @@ ASH_PUBLIC_EXPORT bool IsUnifiedMessageCenterRefactorEnabled();
ASH_PUBLIC_EXPORT bool IsBackgroundBlurEnabled(); ASH_PUBLIC_EXPORT bool IsBackgroundBlurEnabled();
ASH_PUBLIC_EXPORT bool IsSwipingFromLeftEdgeToGoBackEnabled();
} // namespace features } // namespace features
} // namespace ash } // namespace ash
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "ash/wm/toplevel_window_event_handler.h" #include "ash/wm/toplevel_window_event_handler.h"
#include "ash/public/cpp/app_types.h" #include "ash/public/cpp/app_types.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/resize_shadow_controller.h" #include "ash/wm/resize_shadow_controller.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h"
...@@ -37,6 +38,10 @@ namespace { ...@@ -37,6 +38,10 @@ namespace {
// window from the top of the screen in tablet mode. // window from the top of the screen in tablet mode.
constexpr int kDragStartTopEdgeInset = 8; constexpr int kDragStartTopEdgeInset = 8;
// How many dips are reserved for gesture events to start swiping to previous
// page from the left edge of the screen in tablet mode.
constexpr int kStartGoingBackLeftEdgeInset = 16;
// Returns whether |window| can be moved via a two finger drag given // Returns whether |window| can be moved via a two finger drag given
// the hittest results of the two fingers. // the hittest results of the two fingers.
bool CanStartTwoFingerMove(aura::Window* window, bool CanStartTwoFingerMove(aura::Window* window,
...@@ -94,6 +99,35 @@ void OnDragCompleted( ...@@ -94,6 +99,35 @@ void OnDragCompleted(
run_loop->Quit(); run_loop->Quit();
} }
// True if we can start swiping from left edge to go to previous page.
bool CanStartGoingBack() {
if (!features::IsSwipingFromLeftEdgeToGoBackEnabled())
return false;
if (!Shell::Get()->tablet_mode_controller()->InTabletMode())
return false;
return true;
}
// True if |event| is scrolling away from the restricted left area of the
// display.
bool StartedAwayFromLeftArea(ui::GestureEvent* event) {
if (event->details().scroll_x_hint() < 0)
return false;
const gfx::Point location_in_screen =
event->target()->GetScreenLocation(*event);
const gfx::Rect work_area_bounds =
display::Screen::GetScreen()
->GetDisplayNearestWindow(static_cast<aura::Window*>(event->target()))
.work_area();
gfx::Rect hit_bounds_in_screen(work_area_bounds);
hit_bounds_in_screen.set_width(kStartGoingBackLeftEdgeInset);
return hit_bounds_in_screen.Contains(location_in_screen);
}
} // namespace } // namespace
// ScopedWindowResizer --------------------------------------------------------- // ScopedWindowResizer ---------------------------------------------------------
...@@ -264,6 +298,11 @@ void ToplevelWindowEventHandler::OnMouseEvent(ui::MouseEvent* event) { ...@@ -264,6 +298,11 @@ void ToplevelWindowEventHandler::OnMouseEvent(ui::MouseEvent* event) {
} }
void ToplevelWindowEventHandler::OnGestureEvent(ui::GestureEvent* event) { void ToplevelWindowEventHandler::OnGestureEvent(ui::GestureEvent* event) {
if (HandleGoingBackFromLeftEdge(event)) {
event->StopPropagation();
return;
}
aura::Window* target = static_cast<aura::Window*>(event->target()); aura::Window* target = static_cast<aura::Window*>(event->target());
int component = window_util::GetNonClientComponent(target, event->location()); int component = window_util::GetNonClientComponent(target, event->location());
gfx::Point event_location = event->location(); gfx::Point event_location = event->location();
...@@ -796,4 +835,47 @@ void ToplevelWindowEventHandler::UpdateGestureTarget( ...@@ -796,4 +835,47 @@ void ToplevelWindowEventHandler::UpdateGestureTarget(
gesture_target_->AddObserver(this); gesture_target_->AddObserver(this);
} }
bool ToplevelWindowEventHandler::HandleGoingBackFromLeftEdge(
ui::GestureEvent* event) {
if (!CanStartGoingBack())
return false;
switch (event->type()) {
case ui::ET_GESTURE_SCROLL_BEGIN:
going_back_started_ = StartedAwayFromLeftArea(event);
if (going_back_started_)
return true;
break;
case ui::ET_GESTURE_SCROLL_UPDATE:
if (!going_back_started_)
break;
// TODO(crbug.com/1002733): Update the arrow animation.
return true;
case ui::ET_GESTURE_SCROLL_END:
if (!going_back_started_)
break;
if (event->location().x() >= kSwipingDistanceForGoingBack) {
aura::Window* root_window =
window_util::GetRootWindowAt(event->location());
ui::KeyEvent press_key_event(ui::ET_KEY_PRESSED, ui::VKEY_BROWSER_BACK,
ui::EF_NONE);
ignore_result(
root_window->GetHost()->SendEventToSink(&press_key_event));
ui::KeyEvent release_key_event(ui::ET_KEY_RELEASED,
ui::VKEY_BROWSER_BACK, ui::EF_NONE);
ignore_result(
root_window->GetHost()->SendEventToSink(&release_key_event));
} else {
// TODO(crbug.com/1002733): Revert going back animation.
}
going_back_started_ = false;
return true;
// TODO(crbug.com/1002733): Add support for fling event.
default:
break;
}
return false;
}
} // namespace ash } // namespace ash
...@@ -43,6 +43,9 @@ class ASH_EXPORT ToplevelWindowEventHandler ...@@ -43,6 +43,9 @@ class ASH_EXPORT ToplevelWindowEventHandler
public ui::EventHandler, public ui::EventHandler,
public ::wm::WindowMoveClient { public ::wm::WindowMoveClient {
public: public:
// The distance for swiping from left edge to go previous page.
static constexpr int kSwipingDistanceForGoingBack = 80;
// Describes what triggered ending the drag. // Describes what triggered ending the drag.
enum class DragResult { enum class DragResult {
// The drag successfully completed. // The drag successfully completed.
...@@ -157,6 +160,9 @@ class ASH_EXPORT ToplevelWindowEventHandler ...@@ -157,6 +160,9 @@ class ASH_EXPORT ToplevelWindowEventHandler
void UpdateGestureTarget(aura::Window* window, void UpdateGestureTarget(aura::Window* window,
const gfx::Point& location = gfx::Point()); const gfx::Point& location = gfx::Point());
// True if the event is handled for swiping to previous page.
bool HandleGoingBackFromLeftEdge(ui::GestureEvent* event);
// The hittest result for the first finger at the time that it initially // The hittest result for the first finger at the time that it initially
// touched the screen. |first_finger_hittest_| is one of ui/base/hit_test.h // touched the screen. |first_finger_hittest_| is one of ui/base/hit_test.h
int first_finger_hittest_; int first_finger_hittest_;
...@@ -178,6 +184,9 @@ class ASH_EXPORT ToplevelWindowEventHandler ...@@ -178,6 +184,9 @@ class ASH_EXPORT ToplevelWindowEventHandler
// Are we running a nested run loop from RunMoveLoop(). // Are we running a nested run loop from RunMoveLoop().
bool in_move_loop_ = false; bool in_move_loop_ = false;
// True if swiping from left edge to go to previous page is in progress.
bool going_back_started_ = false;
base::WeakPtrFactory<ToplevelWindowEventHandler> weak_factory_{this}; base::WeakPtrFactory<ToplevelWindowEventHandler> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(ToplevelWindowEventHandler); DISALLOW_COPY_AND_ASSIGN(ToplevelWindowEventHandler);
......
...@@ -4,9 +4,11 @@ ...@@ -4,9 +4,11 @@
#include "ash/wm/toplevel_window_event_handler.h" #include "ash/wm/toplevel_window_event_handler.h"
#include "ash/accelerators/accelerator_controller_impl.h"
#include "ash/display/screen_orientation_controller.h" #include "ash/display/screen_orientation_controller.h"
#include "ash/display/screen_orientation_controller_test_api.h" #include "ash/display/screen_orientation_controller_test_api.h"
#include "ash/public/cpp/app_types.h" #include "ash/public/cpp/app_types.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/root_window_controller.h" #include "ash/root_window_controller.h"
#include "ash/shell.h" #include "ash/shell.h"
...@@ -29,6 +31,7 @@ ...@@ -29,6 +31,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
...@@ -37,6 +40,8 @@ ...@@ -37,6 +40,8 @@
#include "ui/aura/test/test_window_delegate.h" #include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/accelerators/test_accelerator_target.h"
#include "ui/base/hit_test.h" #include "ui/base/hit_test.h"
#include "ui/display/display_layout_builder.h" #include "ui/display/display_layout_builder.h"
#include "ui/display/manager/display_manager.h" #include "ui/display/manager/display_manager.h"
...@@ -1006,6 +1011,51 @@ TEST_F(ToplevelWindowEventHandlerTest, RunMoveLoopFailsDuringInProgressDrag) { ...@@ -1006,6 +1011,51 @@ TEST_F(ToplevelWindowEventHandlerTest, RunMoveLoopFailsDuringInProgressDrag) {
EXPECT_EQ("10,11 100x100", window1->bounds().ToString()); EXPECT_EQ("10,11 100x100", window1->bounds().ToString());
} }
TEST_F(ToplevelWindowEventHandlerTest, SwipingFromLeftEdgeToGoBack) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
ash::features::kSwipingFromLeftEdgeToGoBack);
std::unique_ptr<aura::Window> w1 = CreateTestWindow();
TabletModeControllerTestApi().EnterTabletMode();
AcceleratorControllerImpl* controller =
Shell::Get()->accelerator_controller();
// Register an accelerator that looks for back presses.
ui::Accelerator accelerator_back_press(ui::VKEY_BROWSER_BACK, ui::EF_NONE);
accelerator_back_press.set_key_state(ui::Accelerator::KeyState::PRESSED);
ui::TestAcceleratorTarget target_back_press;
controller->Register({accelerator_back_press}, &target_back_press);
// Register an accelerator that looks for back releases.
ui::Accelerator accelerator_back_release(ui::VKEY_BROWSER_BACK, ui::EF_NONE);
accelerator_back_release.set_key_state(ui::Accelerator::KeyState::RELEASED);
ui::TestAcceleratorTarget target_back_release;
controller->Register({accelerator_back_release}, &target_back_release);
// Tests that swiping from the left less than |kSwipingDistanceForGoingBack|
// should not go to previous page.
ui::test::EventGenerator* generator = GetEventGenerator();
const gfx::Point start(0, 100);
generator->GestureScrollSequence(
start,
gfx::Point(ToplevelWindowEventHandler::kSwipingDistanceForGoingBack - 10,
100),
base::TimeDelta::FromMilliseconds(100), 3);
EXPECT_EQ(0, target_back_press.accelerator_count());
EXPECT_EQ(0, target_back_release.accelerator_count());
// Tests that swiping from the left more than |kSwipingDistanceForGoingBack|
// should go to previous page.
generator->GestureScrollSequence(
start,
gfx::Point(ToplevelWindowEventHandler::kSwipingDistanceForGoingBack + 10,
100),
base::TimeDelta::FromMilliseconds(100), 3);
EXPECT_EQ(1, target_back_press.accelerator_count());
EXPECT_EQ(1, target_back_release.accelerator_count());
}
namespace { namespace {
void SendMouseReleaseAndReleaseCapture(ui::test::EventGenerator* generator, void SendMouseReleaseAndReleaseCapture(ui::test::EventGenerator* generator,
......
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