Commit 0d150c2c authored by chinsenj's avatar chinsenj Committed by Chromium LUCI CQ

cros: Refactor window cycle list logic out of WmGestureHandler.

Currently the WmGestureHandler handles events for the wm and also the
window cycle list. There is also the WindowCycleEventFilter which
handles some events for the window cycle list. This was implemented
like this to share logic for scrolling, but after further investigation
the common logic has been determined to not warrant having the handling
for the window cycle list to live in two separate event handlers.

This CL refactors the WmGestureHandler, moving all window cycle list
logic to the WindowCycleEventFilter.

A followup CL will refactor the WindowCycleEventFilter to reorder fcns
according to order in its header file.

Test: manual + existing tests.
Bug: 1136554
Change-Id: I055d0533169992ad1022bdd14da9ce89d91f7e5b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2606494Reviewed-by: default avatarXiaoqian Dai <xdai@chromium.org>
Commit-Queue: Jeremy Chinsen <chinsenj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842584}
parent a2ef2236
...@@ -53,13 +53,6 @@ bool IsNaturalScrollOn() { ...@@ -53,13 +53,6 @@ bool IsNaturalScrollOn() {
pref->GetBoolean(prefs::kNaturalScroll); pref->GetBoolean(prefs::kNaturalScroll);
} }
// Is reverse scrolling for mouse wheel on.
bool IsReverseScrollOn() {
PrefService* pref =
Shell::Get()->session_controller()->GetActivePrefService();
return pref->GetBoolean(prefs::kMouseReverseScroll);
}
// Reverse an offset when the reverse scrolling is on. // Reverse an offset when the reverse scrolling is on.
float GetOffset(float offset) { float GetOffset(float offset) {
// The handler code uses the new directions which is the reverse of the old // The handler code uses the new directions which is the reverse of the old
...@@ -204,24 +197,6 @@ WmGestureHandler::WmGestureHandler() ...@@ -204,24 +197,6 @@ WmGestureHandler::WmGestureHandler()
WmGestureHandler::~WmGestureHandler() = default; WmGestureHandler::~WmGestureHandler() = default;
bool WmGestureHandler::ProcessWheelEvent(const ui::MouseEvent& event) {
if (event.IsMouseWheelEvent() &&
Shell::Get()->window_cycle_controller()->IsCycling()) {
if (!scroll_data_)
scroll_data_ = ScrollData();
// Convert mouse wheel events into three-finger scrolls for window cycle
// list and also swap y offset with x offset.
return ProcessEventImpl(
/*finger_count=*/3,
IsReverseScrollOn() ? event.AsMouseWheelEvent()->y_offset()
: -event.AsMouseWheelEvent()->y_offset(),
event.AsMouseWheelEvent()->x_offset());
}
return false;
}
bool WmGestureHandler::ProcessScrollEvent(const ui::ScrollEvent& event) { bool WmGestureHandler::ProcessScrollEvent(const ui::ScrollEvent& event) {
// ET_SCROLL_FLING_CANCEL means a touchpad swipe has started. // ET_SCROLL_FLING_CANCEL means a touchpad swipe has started.
if (event.type() == ui::ET_SCROLL_FLING_CANCEL) { if (event.type() == ui::ET_SCROLL_FLING_CANCEL) {
...@@ -248,8 +223,8 @@ bool WmGestureHandler::ProcessEventImpl(int finger_count, ...@@ -248,8 +223,8 @@ bool WmGestureHandler::ProcessEventImpl(int finger_count,
if (!scroll_data_) if (!scroll_data_)
return false; return false;
// Only two, three or four finger scrolls are supported. // Only three or four finger scrolls are supported.
if (finger_count != 2 && finger_count != 3 && finger_count != 4) { if (finger_count != 3 && finger_count != 4) {
scroll_data_.reset(); scroll_data_.reset();
return false; return false;
} }
...@@ -261,21 +236,12 @@ bool WmGestureHandler::ProcessEventImpl(int finger_count, ...@@ -261,21 +236,12 @@ bool WmGestureHandler::ProcessEventImpl(int finger_count,
return false; return false;
} }
if (finger_count == 2 && !IsNaturalScrollOn()) {
// Two finger swipe from left to right should move the list right regardless
// of natural scroll settings.
delta_x = -delta_x;
}
scroll_data_->scroll_x += delta_x; scroll_data_->scroll_x += delta_x;
scroll_data_->scroll_y += delta_y; scroll_data_->scroll_y += delta_y;
// If the requirements to cycle the window cycle list or move the overview // If the requirements to move the overview selector are met, reset
// selector are met, reset |scroll_data_|. If both are open, cycle the window // |scroll_data_|.
// cycle list. const bool moved = MoveOverviewSelection(finger_count, scroll_data_->scroll_x,
const bool moved = CycleWindowCycleList(finger_count, scroll_data_->scroll_x,
scroll_data_->scroll_y) ||
MoveOverviewSelection(finger_count, scroll_data_->scroll_x,
scroll_data_->scroll_y); scroll_data_->scroll_y);
if (is_enhanced_desk_animations_ && finger_count == 4) { if (is_enhanced_desk_animations_ && finger_count == 4) {
...@@ -358,25 +324,6 @@ bool WmGestureHandler::MoveOverviewSelection(int finger_count, ...@@ -358,25 +324,6 @@ bool WmGestureHandler::MoveOverviewSelection(int finger_count,
return true; return true;
} }
bool WmGestureHandler::CycleWindowCycleList(int finger_count,
float scroll_x,
float scroll_y) {
if (!features::IsInteractiveWindowCycleListEnabled() ||
(finger_count != 2 && finger_count != 3)) {
return false;
}
auto* window_cycle_controller = Shell::Get()->window_cycle_controller();
const bool is_cycling = window_cycle_controller->IsCycling();
if (!ShouldHorizontallyScroll(is_cycling, scroll_x, scroll_y))
return false;
window_cycle_controller->HandleCycleWindow(
scroll_x > 0 ? WindowCycleController::FORWARD
: WindowCycleController::BACKWARD);
return true;
}
bool WmGestureHandler::ShouldHorizontallyScroll(bool in_session, bool WmGestureHandler::ShouldHorizontallyScroll(bool in_session,
float scroll_x, float scroll_x,
float scroll_y) { float scroll_y) {
......
...@@ -10,28 +10,15 @@ ...@@ -10,28 +10,15 @@
#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_registry_simple.h"
namespace ui { namespace ui {
class MouseEvent;
class ScrollEvent; class ScrollEvent;
} }
namespace ash { namespace ash {
// TODO(chinsenj): Consider renaming this to WmEventHandler and moving to parent
// directory since this now handles mouse wheel events.
// This handles the following interactions: // This handles the following interactions:
// - 3-finger touchpad scroll events to enter/exit overview mode and move the // - 3-finger touchpad scroll events to enter/exit overview mode and move the
// overview highlight if it is visible. // overview highlight if it is visible.
// - 4-finger horizontal scrolls to switch desks. // - 4-finger horizontal scrolls to switch desks.
//
// This handles the following interactions if the InteractiveWindowCycleList
// flag is enabled. TODO(chinsenj): Merge these comments when the flag is
// removed.
// - 3-finger horizontal touchpad scroll events to cycle the window cycle
// list.
// - 2-finger horizontal touchpad scroll events to cycle the window cycle
// list.
// - Mouse wheel events to cycle the window cycle list.
class ASH_EXPORT WmGestureHandler { class ASH_EXPORT WmGestureHandler {
public: public:
// The thresholds of performing a wm action with a touchpad three or four // The thresholds of performing a wm action with a touchpad three or four
...@@ -49,15 +36,9 @@ class ASH_EXPORT WmGestureHandler { ...@@ -49,15 +36,9 @@ class ASH_EXPORT WmGestureHandler {
WmGestureHandler& operator=(const WmGestureHandler&) = delete; WmGestureHandler& operator=(const WmGestureHandler&) = delete;
virtual ~WmGestureHandler(); virtual ~WmGestureHandler();
// Processes a mouse wheel event and may cycle the window cycle list. Returns // Processes a scroll event and may switch desks, start overview or move the
// true if the event has been handled and should not be processed further, // overview highlight. Returns true if the event has been handled and should
// false otherwise. // not be processed further, false otherwise.
bool ProcessWheelEvent(const ui::MouseEvent& event);
// Processes a scroll event and may switch desks, start overview, move the
// overview highlight or cycle the window cycle list. Returns true if
// the event has been handled and should not be processed further, false
// otherwise.
bool ProcessScrollEvent(const ui::ScrollEvent& event); bool ProcessScrollEvent(const ui::ScrollEvent& event);
private: private:
...@@ -75,9 +56,8 @@ class ASH_EXPORT WmGestureHandler { ...@@ -75,9 +56,8 @@ class ASH_EXPORT WmGestureHandler {
bool continuous_gesture_started = false; bool continuous_gesture_started = false;
}; };
// Called by ProcessWheelEvent() and ProcessScrollEvent(). Depending on // Called by ProcessScrollEvent(). Depending on |finger_count|, may switch
// |finger_count|, may switch desks, start overview, move the overview // desks, start overview or move the overview highlight. Returns true if the
// highlight or cycle the window cycle list. Returns true if the
// event has been handled and should not be processed further, false // event has been handled and should not be processed further, false
// otherwise. Forwards events to DesksController if // otherwise. Forwards events to DesksController if
// |is_enhanced_desk_animations_| is true. // |is_enhanced_desk_animations_| is true.
...@@ -90,12 +70,8 @@ class ASH_EXPORT WmGestureHandler { ...@@ -90,12 +70,8 @@ class ASH_EXPORT WmGestureHandler {
// the middle of scrolls and when scrolls have ended. // the middle of scrolls and when scrolls have ended.
bool MoveOverviewSelection(int finger_count, float scroll_x, float scroll_y); bool MoveOverviewSelection(int finger_count, float scroll_x, float scroll_y);
// Tries to cycle the window cycle list. Returns true if successful. // Returns whether or not a given session of overview should horizontally
// Called in the middle of scrolls and when scrolls have ended. // scroll.
bool CycleWindowCycleList(int finger_count, float scroll_x, float scroll_y);
// Returns whether or not a given session of overview/window cycle list should
// horizontally scroll.
bool ShouldHorizontallyScroll(bool in_session, bool ShouldHorizontallyScroll(bool in_session,
float scroll_x, float scroll_x,
float scroll_y); float scroll_y);
......
...@@ -24,11 +24,6 @@ void SystemGestureEventFilter::OnMouseEvent(ui::MouseEvent* event) { ...@@ -24,11 +24,6 @@ void SystemGestureEventFilter::OnMouseEvent(ui::MouseEvent* event) {
ui::TouchScreensAvailability::ENABLED) { ui::TouchScreensAvailability::ENABLED) {
base::RecordAction(base::UserMetricsAction("Mouse_Down")); base::RecordAction(base::UserMetricsAction("Mouse_Down"));
} }
if (event->IsMouseWheelEvent() && wm_gesture_handler_ &&
wm_gesture_handler_->ProcessWheelEvent(*event)) {
event->StopPropagation();
}
} }
void SystemGestureEventFilter::OnScrollEvent(ui::ScrollEvent* event) { void SystemGestureEventFilter::OnScrollEvent(ui::ScrollEvent* event) {
......
...@@ -7,11 +7,15 @@ ...@@ -7,11 +7,15 @@
#include "ash/accelerators/debug_commands.h" #include "ash/accelerators/debug_commands.h"
#include "ash/display/screen_ash.h" #include "ash/display/screen_ash.h"
#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/ash_pref_names.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/window_cycle/window_cycle_controller.h" #include "ash/wm/window_cycle/window_cycle_controller.h"
#include "ash/wm/window_cycle/window_cycle_list.h" #include "ash/wm/window_cycle/window_cycle_list.h"
#include "base/bind.h" #include "base/bind.h"
#include "components/prefs/pref_service.h"
#include "ui/events/event.h" #include "ui/events/event.h"
#include "ui/events/types/event_type.h"
#include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/coordinate_conversion.h"
namespace ash { namespace ash {
...@@ -20,6 +24,21 @@ namespace ash { ...@@ -20,6 +24,21 @@ namespace ash {
// before this stops filtering mouse events. // before this stops filtering mouse events.
constexpr int kMouseMovementThreshold = 5; constexpr int kMouseMovementThreshold = 5;
// Is the reverse scrolling for touchpad on.
bool IsNaturalScrollOn() {
PrefService* pref =
Shell::Get()->session_controller()->GetActivePrefService();
return pref->GetBoolean(prefs::kTouchpadEnabled) &&
pref->GetBoolean(prefs::kNaturalScroll);
}
// Is reverse scrolling for mouse wheel on.
bool IsReverseScrollOn() {
PrefService* pref =
Shell::Get()->session_controller()->GetActivePrefService();
return pref->GetBoolean(prefs::kMouseReverseScroll);
}
WindowCycleEventFilter::WindowCycleEventFilter() WindowCycleEventFilter::WindowCycleEventFilter()
: initial_mouse_location_( : initial_mouse_location_(
display::Screen::GetScreen()->GetCursorScreenPoint()) { display::Screen::GetScreen()->GetCursorScreenPoint()) {
...@@ -117,6 +136,87 @@ void WindowCycleEventFilter::SetHasUserUsedMouse(ui::MouseEvent* event) { ...@@ -117,6 +136,87 @@ void WindowCycleEventFilter::SetHasUserUsedMouse(ui::MouseEvent* event) {
} }
} }
void WindowCycleEventFilter::ProcessMouseEvent(ui::MouseEvent* event) {
auto* window_cycle_controller = Shell::Get()->window_cycle_controller();
if (event->type() == ui::ET_MOUSE_PRESSED &&
!window_cycle_controller->IsEventInCycleView(event)) {
// Close the window cycle list if a user clicks outside of it.
window_cycle_controller->CancelCycling();
return;
}
if (event->IsMouseWheelEvent()) {
if (!scroll_data_)
scroll_data_ = ScrollData();
const ui::MouseWheelEvent* wheel_event = event->AsMouseWheelEvent();
const float y_offset = wheel_event->y_offset();
// Convert mouse wheel events into three-finger scrolls for window cycle
// list and also swap y offset with x offset.
if (ProcessEventImpl(/*finger_count=*/3,
IsReverseScrollOn() ? y_offset : -y_offset,
wheel_event->x_offset())) {
event->SetHandled();
event->StopPropagation();
}
}
}
bool WindowCycleEventFilter::ProcessEventImpl(int finger_count,
float delta_x,
float delta_y) {
if (!scroll_data_ || !features::IsInteractiveWindowCycleListEnabled())
return false;
if (finger_count != 2 && finger_count != 3) {
scroll_data_.reset();
return false;
}
if (scroll_data_->finger_count != 0 &&
scroll_data_->finger_count != finger_count) {
scroll_data_.reset();
return false;
}
if (finger_count == 2 && !IsNaturalScrollOn()) {
// Two finger swipe from left to right should move the list right regardless
// of natural scroll settings.
delta_x = -delta_x;
}
scroll_data_->scroll_x += delta_x;
scroll_data_->scroll_y += delta_y;
const bool moved = CycleWindowCycleList(finger_count, scroll_data_->scroll_x,
scroll_data_->scroll_y);
if (moved)
scroll_data_ = ScrollData();
scroll_data_->finger_count = finger_count;
return moved;
}
bool WindowCycleEventFilter::CycleWindowCycleList(int finger_count,
float scroll_x,
float scroll_y) {
if (!features::IsInteractiveWindowCycleListEnabled() ||
(finger_count != 2 && finger_count != 3)) {
return false;
}
auto* window_cycle_controller = Shell::Get()->window_cycle_controller();
if (!window_cycle_controller->IsCycling() ||
std::fabs(scroll_x) < std::fabs(scroll_y) ||
std::fabs(scroll_x) < kHorizontalThresholdDp) {
return false;
}
window_cycle_controller->HandleCycleWindow(
scroll_x > 0 ? WindowCycleController::FORWARD
: WindowCycleController::BACKWARD);
return true;
}
WindowCycleController::Direction WindowCycleEventFilter::GetDirection( WindowCycleController::Direction WindowCycleEventFilter::GetDirection(
ui::KeyEvent* event) const { ui::KeyEvent* event) const {
DCHECK(IsTriggerKey(event)); DCHECK(IsTriggerKey(event));
...@@ -134,19 +234,17 @@ void WindowCycleEventFilter::OnMouseEvent(ui::MouseEvent* event) { ...@@ -134,19 +234,17 @@ void WindowCycleEventFilter::OnMouseEvent(ui::MouseEvent* event) {
if (!has_user_used_mouse_) if (!has_user_used_mouse_)
SetHasUserUsedMouse(event); SetHasUserUsedMouse(event);
if (features::IsInteractiveWindowCycleListEnabled()) { if (features::IsInteractiveWindowCycleListEnabled() && has_user_used_mouse_) {
WindowCycleController* window_cycle_controller = WindowCycleController* window_cycle_controller =
Shell::Get()->window_cycle_controller(); Shell::Get()->window_cycle_controller();
const bool cycle_list_is_visible = const bool cycle_list_is_visible =
window_cycle_controller->IsWindowListVisible(); window_cycle_controller->IsWindowListVisible();
const bool event_should_not_be_filtered = if (cycle_list_is_visible)
has_user_used_mouse_ && ProcessMouseEvent(event);
window_cycle_controller->IsEventInCycleView(event);
if (event_should_not_be_filtered || !cycle_list_is_visible) { if (window_cycle_controller->IsEventInCycleView(event) ||
!cycle_list_is_visible) {
return; return;
} else if (event->type() == ui::ET_MOUSE_PRESSED && cycle_list_is_visible) {
// Close the window cycle list if a user clicks outside of it.
window_cycle_controller->CancelCycling();
} }
} }
...@@ -159,6 +257,28 @@ void WindowCycleEventFilter::OnMouseEvent(ui::MouseEvent* event) { ...@@ -159,6 +257,28 @@ void WindowCycleEventFilter::OnMouseEvent(ui::MouseEvent* event) {
} }
} }
void WindowCycleEventFilter::OnScrollEvent(ui::ScrollEvent* event) {
// ET_SCROLL_FLING_CANCEL means a touchpad swipe has started.
if (event->type() == ui::ET_SCROLL_FLING_CANCEL) {
scroll_data_ = ScrollData();
return;
}
// ET_SCROLL_FLING_START means a touchpad swipe has ended.
if (event->type() == ui::ET_SCROLL_FLING_START) {
scroll_data_.reset();
return;
}
DCHECK_EQ(ui::ET_SCROLL, event->type());
if (ProcessEventImpl(event->finger_count(), event->x_offset(),
event->y_offset())) {
event->SetHandled();
event->StopPropagation();
}
}
void WindowCycleEventFilter::OnGestureEvent(ui::GestureEvent* event) { void WindowCycleEventFilter::OnGestureEvent(ui::GestureEvent* event) {
if (features::IsInteractiveWindowCycleListEnabled() && if (features::IsInteractiveWindowCycleListEnabled() &&
Shell::Get()->window_cycle_controller()->IsEventInCycleView(event)) { Shell::Get()->window_cycle_controller()->IsEventInCycleView(event)) {
......
...@@ -8,10 +8,18 @@ ...@@ -8,10 +8,18 @@
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ash/wm/window_cycle/window_cycle_controller.h" #include "ash/wm/window_cycle/window_cycle_controller.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "ui/events/event_handler.h" #include "ui/events/event_handler.h"
#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point.h"
namespace ui {
class GestureEvent;
class KeyEvent;
class MouseEvent;
class ScrollEvent;
} // namespace ui
namespace ash { namespace ash {
// Created by WindowCycleController when cycling through windows. Eats all key // Created by WindowCycleController when cycling through windows. Eats all key
...@@ -19,15 +27,30 @@ namespace ash { ...@@ -19,15 +27,30 @@ namespace ash {
// Also allows users to cycle using right/left keys. // Also allows users to cycle using right/left keys.
class ASH_EXPORT WindowCycleEventFilter : public ui::EventHandler { class ASH_EXPORT WindowCycleEventFilter : public ui::EventHandler {
public: public:
// The threshold of performing an action with a touchpad or mouse wheel
// scroll.
static constexpr float kHorizontalThresholdDp = 330.f;
WindowCycleEventFilter(); WindowCycleEventFilter();
~WindowCycleEventFilter() override; ~WindowCycleEventFilter() override;
// Overridden from ui::EventHandler: // Overridden from ui::EventHandler:
void OnKeyEvent(ui::KeyEvent* event) override; void OnKeyEvent(ui::KeyEvent* event) override;
void OnMouseEvent(ui::MouseEvent* event) override; void OnMouseEvent(ui::MouseEvent* event) override;
void OnScrollEvent(ui::ScrollEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override; void OnGestureEvent(ui::GestureEvent* event) override;
private: private:
// A struct containing the relevant data during a scroll session.
struct ScrollData {
int finger_count = 0;
// Values are cumulative (ex. |scroll_x| is the total x distance moved
// since the scroll began.
float scroll_x = 0.f;
float scroll_y = 0.f;
};
class AltReleaseHandler : public ui::EventHandler { class AltReleaseHandler : public ui::EventHandler {
public: public:
AltReleaseHandler(); AltReleaseHandler();
...@@ -59,6 +82,20 @@ class ASH_EXPORT WindowCycleEventFilter : public ui::EventHandler { ...@@ -59,6 +82,20 @@ class ASH_EXPORT WindowCycleEventFilter : public ui::EventHandler {
// clicked. // clicked.
void SetHasUserUsedMouse(ui::MouseEvent* event); void SetHasUserUsedMouse(ui::MouseEvent* event);
// Depending on the properties of |event|, may cycle the window cycle list or
// complete cycling.
void ProcessMouseEvent(ui::MouseEvent* event);
// Called by ProcessMouseEvent() and OnScrollEvent(). May cycle the window
// cycle list. Returns true if the event has been handled and should not be
// processed further, false otherwise.
bool ProcessEventImpl(int finger_count, float delta_x, float delta_y);
// Based on the given scroll data, determine whether we should cycle the
// window cycle list. Return true if we do cycle the window cycle list,
// otherwise return false.
bool CycleWindowCycleList(int finger_count, float scroll_x, float scroll_y);
// Returns the direction the window cycle should cycle depending on the // Returns the direction the window cycle should cycle depending on the
// combination of keys being pressed. // combination of keys being pressed.
WindowCycleController::Direction GetDirection(ui::KeyEvent* event) const; WindowCycleController::Direction GetDirection(ui::KeyEvent* event) const;
...@@ -83,6 +120,10 @@ class ASH_EXPORT WindowCycleEventFilter : public ui::EventHandler { ...@@ -83,6 +120,10 @@ class ASH_EXPORT WindowCycleEventFilter : public ui::EventHandler {
// See crbug.com/114375. // See crbug.com/114375.
bool has_user_used_mouse_ = false; bool has_user_used_mouse_ = false;
// Stores the current scroll session data. If it does not exist, there is no
// active scroll session.
base::Optional<ScrollData> scroll_data_;
DISALLOW_COPY_AND_ASSIGN(WindowCycleEventFilter); DISALLOW_COPY_AND_ASSIGN(WindowCycleEventFilter);
}; };
......
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