Commit 3bf51a6c authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

desks: Add framework for touchpad continuous desk gestures.

Adds a way to pipe data from WmGestureHandler -> DeskController ->
DeskAnimationBase -> RootWindowDeskSwitchAnimator in preparation for the
touchpad continuous desks gestures feature. This CL will remove the
touchpad animation temporarily, if the feature is on, but will still
switch desks. Done in this CL:

1) WmGestureHandler uses different path if the feature is enabled.
2) DesksController has 3 new functions for WmGestureHandler to use.
3) DesksAnimationBase has Update and End functions.

Test: manual, with and without feature
Bug: 1111445
Change-Id: I08af31452a6614de3d72c42433d1dde8b5704cbd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2388276
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Reviewed-by: default avatarAhmed Fakhry <afakhry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805092}
parent 000f827f
...@@ -30,9 +30,11 @@ ui::Compositor* GetSelectedCompositorForAnimationSmoothness() { ...@@ -30,9 +30,11 @@ ui::Compositor* GetSelectedCompositorForAnimationSmoothness() {
} // namespace } // namespace
DeskAnimationBase::DeskAnimationBase(DesksController* controller, DeskAnimationBase::DeskAnimationBase(DesksController* controller,
int ending_desk_index) int ending_desk_index,
bool is_continuous_gesture_animation)
: controller_(controller), : controller_(controller),
ending_desk_index_(ending_desk_index), ending_desk_index_(ending_desk_index),
is_continuous_gesture_animation_(is_continuous_gesture_animation),
throughput_tracker_(GetSelectedCompositorForAnimationSmoothness() throughput_tracker_(GetSelectedCompositorForAnimationSmoothness()
->RequestNewThroughputTracker()) { ->RequestNewThroughputTracker()) {
DCHECK(controller_); DCHECK(controller_);
...@@ -67,6 +69,14 @@ bool DeskAnimationBase::Replace(bool moving_left, DesksSwitchSource source) { ...@@ -67,6 +69,14 @@ bool DeskAnimationBase::Replace(bool moving_left, DesksSwitchSource source) {
return false; return false;
} }
bool DeskAnimationBase::Update(float scroll_delta_x) {
return false;
}
bool DeskAnimationBase::End() {
return false;
}
void DeskAnimationBase::OnStartingDeskScreenshotTaken(int ending_desk_index) { void DeskAnimationBase::OnStartingDeskScreenshotTaken(int ending_desk_index) {
DCHECK(!desk_switch_animators_.empty()); DCHECK(!desk_switch_animators_.empty());
...@@ -104,6 +114,12 @@ void DeskAnimationBase::OnEndingDeskScreenshotTaken() { ...@@ -104,6 +114,12 @@ void DeskAnimationBase::OnEndingDeskScreenshotTaken() {
return; return;
} }
// Continuous gesture animations do not want to start an animation on
// creation/replacement (because they want to update). They will request an
// animation explicitly if they need (gesture end).
if (is_continuous_gesture_animation_)
return;
for (auto& animator : desk_switch_animators_) for (auto& animator : desk_switch_animators_)
animator->StartAnimation(); animator->StartAnimation();
} }
......
...@@ -21,7 +21,9 @@ class DesksController; ...@@ -21,7 +21,9 @@ class DesksController;
// each animation type. // each animation type.
class DeskAnimationBase : public RootWindowDeskSwitchAnimator::Delegate { class DeskAnimationBase : public RootWindowDeskSwitchAnimator::Delegate {
public: public:
DeskAnimationBase(DesksController* controller, int ending_desk_index); DeskAnimationBase(DesksController* controller,
int ending_desk_index,
bool is_continuous_gesture_animation);
DeskAnimationBase(const DeskAnimationBase&) = delete; DeskAnimationBase(const DeskAnimationBase&) = delete;
DeskAnimationBase& operator=(const DeskAnimationBase&) = delete; DeskAnimationBase& operator=(const DeskAnimationBase&) = delete;
~DeskAnimationBase() override; ~DeskAnimationBase() override;
...@@ -35,9 +37,18 @@ class DeskAnimationBase : public RootWindowDeskSwitchAnimator::Delegate { ...@@ -35,9 +37,18 @@ class DeskAnimationBase : public RootWindowDeskSwitchAnimator::Delegate {
void Launch(); void Launch();
// Replaces a current animation with an animation to an adjacent desk. By // Replaces a current animation with an animation to an adjacent desk. By
// default returns false as most animations do not support replacement. // default returns false as most animations do not support replacing.
virtual bool Replace(bool moving_left, DesksSwitchSource source); virtual bool Replace(bool moving_left, DesksSwitchSource source);
// Updates a current animation by shifting its animating layer.
// |scroll_delta_x| is the amount of scroll change since the last scroll
// update event. Returns false if the animation does not support updating.
virtual bool Update(float scroll_delta_x);
// Ends a current animation, animating to a desk determined by the
// implementatiaion. Returns false if the animation does not support ending.
virtual bool End();
// RootWindowDeskSwitchAnimator::Delegate: // RootWindowDeskSwitchAnimator::Delegate:
void OnStartingDeskScreenshotTaken(int ending_desk_index) override; void OnStartingDeskScreenshotTaken(int ending_desk_index) override;
void OnEndingDeskScreenshotTaken() override; void OnEndingDeskScreenshotTaken() override;
...@@ -68,6 +79,11 @@ class DeskAnimationBase : public RootWindowDeskSwitchAnimator::Delegate { ...@@ -68,6 +79,11 @@ class DeskAnimationBase : public RootWindowDeskSwitchAnimator::Delegate {
// The index of the desk that will be active after this animation ends. // The index of the desk that will be active after this animation ends.
int ending_desk_index_; int ending_desk_index_;
// True if this animation is a continuous gesture animation. Update and End
// only work when this is true, and we do not start the animation when
// OnEndingDeskScreenshotTaken is called.
const bool is_continuous_gesture_animation_;
private: private:
// ThroughputTracker used for measuring this animation smoothness. // ThroughputTracker used for measuring this animation smoothness.
ui::ThroughputTracker throughput_tracker_; ui::ThroughputTracker throughput_tracker_;
......
...@@ -4,9 +4,11 @@ ...@@ -4,9 +4,11 @@
#include "ash/wm/desks/desk_animation_impl.h" #include "ash/wm/desks/desk_animation_impl.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/desks/desk.h" #include "ash/wm/desks/desk.h"
#include "ash/wm/desks/desks_controller.h" #include "ash/wm/desks/desks_controller.h"
#include "ash/wm/desks/desks_histogram_enums.h"
#include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_controller.h"
#include "ash/wm/splitview/split_view_utils.h" #include "ash/wm/splitview/split_view_utils.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
...@@ -21,6 +23,11 @@ constexpr char kDeskActivationSmoothnessHistogramName[] = ...@@ -21,6 +23,11 @@ constexpr char kDeskActivationSmoothnessHistogramName[] =
constexpr char kDeskRemovalSmoothnessHistogramName[] = constexpr char kDeskRemovalSmoothnessHistogramName[] =
"Ash.Desks.AnimationSmoothness.DeskRemoval"; "Ash.Desks.AnimationSmoothness.DeskRemoval";
bool IsForContinuousGestures(DesksSwitchSource source) {
return source == DesksSwitchSource::kDeskSwitchTouchpad &&
features::IsEnhancedDeskAnimations();
}
} // namespace } // namespace
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -30,7 +37,10 @@ DeskActivationAnimation::DeskActivationAnimation(DesksController* controller, ...@@ -30,7 +37,10 @@ DeskActivationAnimation::DeskActivationAnimation(DesksController* controller,
int starting_desk_index, int starting_desk_index,
int ending_desk_index, int ending_desk_index,
DesksSwitchSource source) DesksSwitchSource source)
: DeskAnimationBase(controller, ending_desk_index), switch_source_(source) { : DeskAnimationBase(controller,
ending_desk_index,
IsForContinuousGestures(source)),
switch_source_(source) {
for (auto* root : Shell::GetAllRootWindows()) { for (auto* root : Shell::GetAllRootWindows()) {
desk_switch_animators_.emplace_back( desk_switch_animators_.emplace_back(
std::make_unique<RootWindowDeskSwitchAnimator>( std::make_unique<RootWindowDeskSwitchAnimator>(
...@@ -90,6 +100,28 @@ bool DeskActivationAnimation::Replace(bool moving_left, ...@@ -90,6 +100,28 @@ bool DeskActivationAnimation::Replace(bool moving_left,
return true; return true;
} }
bool DeskActivationAnimation::Update(float scroll_delta_x) {
if (!is_continuous_gesture_animation_)
return false;
for (const auto& animator : desk_switch_animators_)
animator->UpdateAnimation(scroll_delta_x);
return true;
}
bool DeskActivationAnimation::End() {
if (!is_continuous_gesture_animation_)
return false;
for (const auto& animator : desk_switch_animators_)
animator->EndAnimation();
// TODO(sammiequon): Remove this, this is temporary so we can destroy |this|
// before Update and End get filled out.
OnDeskSwitchAnimationFinished();
return true;
}
void DeskActivationAnimation::OnStartingDeskScreenshotTakenInternal( void DeskActivationAnimation::OnStartingDeskScreenshotTakenInternal(
int ending_desk_index) { int ending_desk_index) {
DCHECK_EQ(ending_desk_index_, ending_desk_index); DCHECK_EQ(ending_desk_index_, ending_desk_index);
...@@ -150,7 +182,9 @@ DeskRemovalAnimation::DeskRemovalAnimation(DesksController* controller, ...@@ -150,7 +182,9 @@ DeskRemovalAnimation::DeskRemovalAnimation(DesksController* controller,
int desk_to_remove_index, int desk_to_remove_index,
int desk_to_activate_index, int desk_to_activate_index,
DesksCreationRemovalSource source) DesksCreationRemovalSource source)
: DeskAnimationBase(controller, desk_to_activate_index), : DeskAnimationBase(controller,
desk_to_activate_index,
/*is_continuous_gesture_animation=*/false),
desk_to_remove_index_(desk_to_remove_index), desk_to_remove_index_(desk_to_remove_index),
request_source_(source) { request_source_(source) {
DCHECK(!Shell::Get()->overview_controller()->InOverviewSession()); DCHECK(!Shell::Get()->overview_controller()->InOverviewSession());
......
...@@ -25,6 +25,8 @@ class DeskActivationAnimation : public DeskAnimationBase { ...@@ -25,6 +25,8 @@ class DeskActivationAnimation : public DeskAnimationBase {
// DeskAnimationBase: // DeskAnimationBase:
bool Replace(bool moving_left, DesksSwitchSource source) override; bool Replace(bool moving_left, DesksSwitchSource source) override;
bool Update(float scroll_delta_x) override;
bool End() override;
void OnStartingDeskScreenshotTakenInternal(int ending_desk_index) override; void OnStartingDeskScreenshotTakenInternal(int ending_desk_index) override;
void OnDeskSwitchAnimationFinishedInternal() override; void OnDeskSwitchAnimationFinishedInternal() override;
metrics_util::ReportCallback GetReportCallback() const override; metrics_util::ReportCallback GetReportCallback() const override;
......
...@@ -338,6 +338,31 @@ bool DesksController::ActivateAdjacentDesk(bool going_left, ...@@ -338,6 +338,31 @@ bool DesksController::ActivateAdjacentDesk(bool going_left,
return true; return true;
} }
bool DesksController::StartAnimationForGesture(bool move_left) {
DCHECK(is_enhanced_desk_animations_);
// Activate an adjacent desk. It will replace an ongoing touchpad animation if
// one exists.
return ActivateAdjacentDesk(move_left,
DesksSwitchSource::kDeskSwitchTouchpad);
}
void DesksController::UpdateAnimationForGesture(float scroll_delta_x) {
DCHECK(is_enhanced_desk_animations_);
for (const auto& animation : animations_) {
if (animation->Update(scroll_delta_x))
return;
}
}
void DesksController::EndAnimationForGesture() {
DCHECK(is_enhanced_desk_animations_);
for (const auto& animation : animations_) {
if (animation->End())
return;
}
}
bool DesksController::MoveWindowFromActiveDeskTo( bool DesksController::MoveWindowFromActiveDeskTo(
aura::Window* window, aura::Window* window,
Desk* target_desk, Desk* target_desk,
......
...@@ -123,6 +123,14 @@ class ASH_EXPORT DesksController : public DesksHelper, ...@@ -123,6 +123,14 @@ class ASH_EXPORT DesksController : public DesksHelper,
// do nothing, no desk switch or hit the wall animation. // do nothing, no desk switch or hit the wall animation.
bool ActivateAdjacentDesk(bool going_left, DesksSwitchSource source); bool ActivateAdjacentDesk(bool going_left, DesksSwitchSource source);
// Functions used by WmGestureHandler to modify the current touchpad desk
// animation, if it exists. StartAnimationForGesture starts a new animation to
// an adjacent desk, or replaces an existing gesture animation. It returns
// true if either of those were successful, false otherwise.
bool StartAnimationForGesture(bool move_left);
void UpdateAnimationForGesture(float scroll_delta_x);
void EndAnimationForGesture();
// Moves |window| (which must belong to the currently active desk) to // Moves |window| (which must belong to the currently active desk) to
// |target_desk| (which must be a different desk). // |target_desk| (which must be a different desk).
// |target_root| is provided if |window| is desired to be moved to another // |target_root| is provided if |window| is desired to be moved to another
......
...@@ -226,6 +226,17 @@ bool RootWindowDeskSwitchAnimator::ReplaceAnimation(int new_ending_desk_index) { ...@@ -226,6 +226,17 @@ bool RootWindowDeskSwitchAnimator::ReplaceAnimation(int new_ending_desk_index) {
return true; return true;
} }
bool RootWindowDeskSwitchAnimator::UpdateAnimation(float scroll_delta_x) {
// TODO(sammiequon): Fill in here.
return false;
}
void RootWindowDeskSwitchAnimator::EndAnimation() {
// TODO(sammiequon): Fill in here. Change |animation_finished_| here for now
// so the delegate will delete |this| after this function is called.
animation_finished_ = true;
}
void RootWindowDeskSwitchAnimator::OnImplicitAnimationsCompleted() { void RootWindowDeskSwitchAnimator::OnImplicitAnimationsCompleted() {
// |setting_new_transform_| is true we call SetTransform while an animation is // |setting_new_transform_| is true we call SetTransform while an animation is
// under progress. Do not notify our delegate in that case. // under progress. Do not notify our delegate in that case.
......
...@@ -219,6 +219,16 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { ...@@ -219,6 +219,16 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver {
// to be taken. // to be taken.
bool ReplaceAnimation(int new_ending_desk_index); bool ReplaceAnimation(int new_ending_desk_index);
// Called as a user is performing a touchpad swipe. Requests a new screenshot
// if necessary based on the last direction as specified in |scroll_delta_x|.
// |scroll_delta_x| is in touchpad units, it will be converted to display
// units and then used to shift the animation layer.
bool UpdateAnimation(float scroll_delta_x);
// Called when a user ends a touchpad gesture. This will animate to the most
// visible desk.
void EndAnimation();
// ui::ImplicitAnimationObserver: // ui::ImplicitAnimationObserver:
void OnImplicitAnimationsCompleted() override; void OnImplicitAnimationsCompleted() override;
......
...@@ -18,6 +18,10 @@ namespace ash { ...@@ -18,6 +18,10 @@ namespace ash {
namespace { namespace {
// The amount the fingers must move in a direction before a continuous gesture
// animation is started. This is to minimize accidental scrolls.
constexpr int kContinuousGestureMoveThresholdDp = 10;
// Handles vertical 3-finger scroll gesture by entering overview on scrolling // Handles vertical 3-finger scroll gesture by entering overview on scrolling
// up, and exiting it on scrolling down. If entering overview and window cycle // up, and exiting it on scrolling down. If entering overview and window cycle
// list is open, close the window cycle list. // list is open, close the window cycle list.
...@@ -63,22 +67,27 @@ bool HandleDesksSwitchHorizontalScroll(float scroll_x) { ...@@ -63,22 +67,27 @@ bool HandleDesksSwitchHorizontalScroll(float scroll_x) {
} // namespace } // namespace
WmGestureHandler::WmGestureHandler() = default; WmGestureHandler::WmGestureHandler()
: is_enhanced_desk_animations_(features::IsEnhancedDeskAnimations()) {}
WmGestureHandler::~WmGestureHandler() = default; WmGestureHandler::~WmGestureHandler() = default;
bool WmGestureHandler::ProcessScrollEvent(const ui::ScrollEvent& event) { bool WmGestureHandler::ProcessScrollEvent(const ui::ScrollEvent& event) {
// 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) {
scroll_data_ = base::make_optional(ScrollData()); scroll_data_ = ScrollData();
return false; return false;
} }
// ET_SCROLL_FLING_START means a touchpad swipe has ended.
if (event.type() == ui::ET_SCROLL_FLING_START) { if (event.type() == ui::ET_SCROLL_FLING_START) {
bool success = EndScroll(); bool success = EndScroll();
DCHECK(!scroll_data_); DCHECK(!scroll_data_);
return success; return success;
} }
DCHECK_EQ(ui::ET_SCROLL, event.type());
if (!scroll_data_) if (!scroll_data_)
return false; return false;
...@@ -89,6 +98,7 @@ bool WmGestureHandler::ProcessScrollEvent(const ui::ScrollEvent& event) { ...@@ -89,6 +98,7 @@ bool WmGestureHandler::ProcessScrollEvent(const ui::ScrollEvent& event) {
return false; return false;
} }
// There is a finger switch, end the current gesture.
if (scroll_data_->finger_count != 0 && if (scroll_data_->finger_count != 0 &&
scroll_data_->finger_count != finger_count) { scroll_data_->finger_count != finger_count) {
scroll_data_.reset(); scroll_data_.reset();
...@@ -97,6 +107,7 @@ bool WmGestureHandler::ProcessScrollEvent(const ui::ScrollEvent& event) { ...@@ -97,6 +107,7 @@ bool WmGestureHandler::ProcessScrollEvent(const ui::ScrollEvent& event) {
scroll_data_->scroll_x += event.x_offset(); scroll_data_->scroll_x += event.x_offset();
scroll_data_->scroll_y += event.y_offset(); scroll_data_->scroll_y += event.y_offset();
// If the requirements to move the overview selector or the window cycle list // If the requirements to move the overview selector or the window cycle list
// selector are met, reset |scroll_data_|. If both are open, move the cycle // selector are met, reset |scroll_data_|. If both are open, move the cycle
// list's selector. // list's selector.
...@@ -105,8 +116,30 @@ bool WmGestureHandler::ProcessScrollEvent(const ui::ScrollEvent& event) { ...@@ -105,8 +116,30 @@ bool WmGestureHandler::ProcessScrollEvent(const ui::ScrollEvent& event) {
scroll_data_->scroll_y) || scroll_data_->scroll_y) ||
MoveOverviewSelection(finger_count, scroll_data_->scroll_x, MoveOverviewSelection(finger_count, scroll_data_->scroll_x,
scroll_data_->scroll_y); scroll_data_->scroll_y);
if (is_enhanced_desk_animations_ && finger_count == 4) {
DCHECK(!moved);
// Update the continuous desk animation if it has already been started,
// otherwise start it if it passes the threshold.
if (scroll_data_->continuous_gesture_started) {
DesksController::Get()->UpdateAnimationForGesture(event.x_offset());
} else if (std::abs(scroll_data_->scroll_x) >
kContinuousGestureMoveThresholdDp) {
if (!DesksController::Get()->StartAnimationForGesture(
/*move_left=*/event.x_offset() > 0)) {
// Starting an animation failed. This can happen if we are on the
// lockscreen or an ongoing animation from a different source is
// happening. In this case reset |scroll_data_| and wait for the next 4
// finger swipe.
scroll_data_.reset();
return false;
}
scroll_data_->continuous_gesture_started = true;
}
}
if (moved) if (moved)
scroll_data_ = base::make_optional(ScrollData()); scroll_data_ = ScrollData();
scroll_data_->finger_count = finger_count; scroll_data_->finger_count = finger_count;
return moved; return moved;
} }
...@@ -115,9 +148,11 @@ bool WmGestureHandler::EndScroll() { ...@@ -115,9 +148,11 @@ bool WmGestureHandler::EndScroll() {
if (!scroll_data_) if (!scroll_data_)
return false; return false;
const int finger_count = scroll_data_->finger_count;
const float scroll_x = scroll_data_->scroll_x; const float scroll_x = scroll_data_->scroll_x;
const float scroll_y = scroll_data_->scroll_y; const float scroll_y = scroll_data_->scroll_y;
const int finger_count = scroll_data_->finger_count; const bool continuous_gesture_started =
scroll_data_->continuous_gesture_started;
scroll_data_.reset(); scroll_data_.reset();
if (finger_count == 0) if (finger_count == 0)
...@@ -130,7 +165,16 @@ bool WmGestureHandler::EndScroll() { ...@@ -130,7 +165,16 @@ bool WmGestureHandler::EndScroll() {
return MoveOverviewSelection(finger_count, scroll_x, scroll_y); return MoveOverviewSelection(finger_count, scroll_x, scroll_y);
} }
return finger_count == 4 && HandleDesksSwitchHorizontalScroll(scroll_x); if (finger_count != 4)
return false;
if (!is_enhanced_desk_animations_)
return HandleDesksSwitchHorizontalScroll(scroll_x);
if (continuous_gesture_started)
DesksController::Get()->EndAnimationForGesture();
return continuous_gesture_started;
} }
bool WmGestureHandler::MoveOverviewSelection(int finger_count, bool WmGestureHandler::MoveOverviewSelection(int finger_count,
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define ASH_WM_GESTURES_WM_GESTURE_HANDLER_H_ #define ASH_WM_GESTURES_WM_GESTURE_HANDLER_H_
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "base/macros.h"
#include "base/optional.h" #include "base/optional.h"
namespace ui { namespace ui {
...@@ -26,19 +25,29 @@ class ASH_EXPORT WmGestureHandler { ...@@ -26,19 +25,29 @@ class ASH_EXPORT WmGestureHandler {
static constexpr float kHorizontalThresholdDp = 330.f; static constexpr float kHorizontalThresholdDp = 330.f;
WmGestureHandler(); WmGestureHandler();
WmGestureHandler(const WmGestureHandler&) = delete;
WmGestureHandler& operator=(const WmGestureHandler&) = delete;
virtual ~WmGestureHandler(); virtual ~WmGestureHandler();
// Processes a scroll event and may switch desks, start overview or move the // Processes a scroll event and may switch desks, start overview or move the
// overivew highlight. Returns true if the event has been handled and should // overivew highlight. Returns true if the event has been handled and should
// not be processed further, false otherwise. // not be processed further, false otherwise. Forwards events to
// DesksController if |is_enhanced_desk_animations_| is true.
bool ProcessScrollEvent(const ui::ScrollEvent& event); bool ProcessScrollEvent(const ui::ScrollEvent& event);
private: private:
// A struct containing the relevant data during a scroll session. // A struct containing the relevant data during a scroll session.
struct ScrollData { struct ScrollData {
int finger_count = 0; 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_x = 0.f;
float scroll_y = 0.f; float scroll_y = 0.f;
// Continuous gestures need to first pass a threshold before we update the
// UI. We still update this struct before that happens.
bool continuous_gesture_started = false;
}; };
// Called when a scroll is ended. Returns true if the scroll is processed. // Called when a scroll is ended. Returns true if the scroll is processed.
...@@ -63,7 +72,8 @@ class ASH_EXPORT WmGestureHandler { ...@@ -63,7 +72,8 @@ class ASH_EXPORT WmGestureHandler {
// Contains the data during a scroll session. Empty is no scroll is underway. // Contains the data during a scroll session. Empty is no scroll is underway.
base::Optional<ScrollData> scroll_data_; base::Optional<ScrollData> scroll_data_;
DISALLOW_COPY_AND_ASSIGN(WmGestureHandler); // True when the enhanced desk animations feature is enabled.
const bool is_enhanced_desk_animations_;
}; };
} // namespace ash } // namespace ash
......
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