Commit 57098dce authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Better coordinate swipe to home gesture and drag handle nudge

Manages the drag handle nudge during window drag from shelf to home or
overview (which may end up in a gesture the nudge is describing).

If the contextual nudge is shown when the window drag starts, the nudge
will not be hidden until the gesture completes (end it will get hidden
when the gesture completes, even if the user does not end up going
home).

If the contextual nudge is scheduled to be shown when the gesture
starts, the show request will be canceled.

Adds logic that prevents drag handle nudge from showing up, unless it's
a result of an explicit user action - tapping the drag handle.

BUG=1058617

Change-Id: I96fa2748308143ec42295dbfb472dc564da5bd03
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2107135
Commit-Queue: Toni Baržić <tbarzic@chromium.org>
Reviewed-by: default avatarManu Cornet <manucornet@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751200}
parent 3bb3e09c
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h" #include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_provider.h" #include "ash/style/ash_color_provider.h"
#include "ash/wm/overview/overview_controller.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/debug/stack_trace.h" #include "base/debug/stack_trace.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
...@@ -103,11 +104,18 @@ bool DragHandle::DoesIntersectRect(const views::View* target, ...@@ -103,11 +104,18 @@ bool DragHandle::DoesIntersectRect(const views::View* target,
} }
bool DragHandle::ShowDragHandleNudge() { bool DragHandle::ShowDragHandleNudge() {
// Stop observing overview state if nudge show timer has fired.
if (!show_drag_handle_nudge_timer_.IsRunning())
overview_observer_.RemoveAll();
// Do not show drag handle nudge if it is already shown or drag handle is not // Do not show drag handle nudge if it is already shown or drag handle is not
// visible. // visible.
if (ShowingNudge() || !GetVisible()) if (ShowingNudge() || window_drag_from_shelf_in_progress_ || !GetVisible())
return false; return false;
showing_nudge_ = true; showing_nudge_ = true;
StopDragHandleNudgeShowTimer();
PrefService* pref = PrefService* pref =
Shell::Get()->session_controller()->GetLastActiveUserPrefService(); Shell::Get()->session_controller()->GetLastActiveUserPrefService();
base::TimeDelta nudge_duration = contextual_tooltip::GetNudgeTimeout( base::TimeDelta nudge_duration = contextual_tooltip::GetNudgeTimeout(
...@@ -127,8 +135,16 @@ bool DragHandle::ShowDragHandleNudge() { ...@@ -127,8 +135,16 @@ bool DragHandle::ShowDragHandleNudge() {
} }
void DragHandle::ScheduleShowDragHandleNudge() { void DragHandle::ScheduleShowDragHandleNudge() {
if (showing_nudge_) if (showing_nudge_ || show_drag_handle_nudge_timer_.IsRunning() ||
window_drag_from_shelf_in_progress_ ||
Shell::Get()->overview_controller()->InOverviewSession()) {
return; return;
}
// Observe overview controller to detect overview session start - this should
// cancel the scheduled nudge show.
overview_observer_.Add(Shell::Get()->overview_controller());
show_drag_handle_nudge_timer_.Start( show_drag_handle_nudge_timer_.Start(
FROM_HERE, kShowNudgeDelay, FROM_HERE, kShowNudgeDelay,
base::BindOnce(base::IgnoreResult(&DragHandle::ShowDragHandleNudge), base::BindOnce(base::IgnoreResult(&DragHandle::ShowDragHandleNudge),
...@@ -141,7 +157,8 @@ void DragHandle::SetColorAndOpacity(SkColor color, float opacity) { ...@@ -141,7 +157,8 @@ void DragHandle::SetColorAndOpacity(SkColor color, float opacity) {
} }
void DragHandle::HideDragHandleNudge(bool hidden_by_tap) { void DragHandle::HideDragHandleNudge(bool hidden_by_tap) {
show_drag_handle_nudge_timer_.Stop(); StopDragHandleNudgeShowTimer();
if (!ShowingNudge()) if (!ShowingNudge())
return; return;
hide_drag_handle_nudge_timer_.Stop(); hide_drag_handle_nudge_timer_.Stop();
...@@ -149,6 +166,28 @@ void DragHandle::HideDragHandleNudge(bool hidden_by_tap) { ...@@ -149,6 +166,28 @@ void DragHandle::HideDragHandleNudge(bool hidden_by_tap) {
showing_nudge_ = false; showing_nudge_ = false;
} }
void DragHandle::SetWindowDragFromShelfInProgress(bool gesture_in_progress) {
if (window_drag_from_shelf_in_progress_ == gesture_in_progress)
return;
window_drag_from_shelf_in_progress_ = gesture_in_progress;
// If the contextual nudge is not yet shown, make sure that any scheduled
// nudge show request is canceled.
if (!ShowingNudge()) {
StopDragHandleNudgeShowTimer();
return;
}
// If the drag handle nudge is shown when the gesture to home or overview
// starts, keep it around until the gesture completes.
if (window_drag_from_shelf_in_progress_) {
hide_drag_handle_nudge_timer_.Stop();
} else {
HideDragHandleNudge(/*hidden_by_tap=*/false);
}
}
void DragHandle::OnGestureEvent(ui::GestureEvent* event) { void DragHandle::OnGestureEvent(ui::GestureEvent* event) {
if (!features::AreContextualNudgesEnabled()) if (!features::AreContextualNudgesEnabled())
return; return;
...@@ -180,6 +219,10 @@ gfx::Rect DragHandle::GetAnchorBoundsInScreen() const { ...@@ -180,6 +219,10 @@ gfx::Rect DragHandle::GetAnchorBoundsInScreen() const {
return anchor_bounds; return anchor_bounds;
} }
void DragHandle::OnOverviewModeStarting() {
StopDragHandleNudgeShowTimer();
}
void DragHandle::ShowDragHandleTooltip() { void DragHandle::ShowDragHandleTooltip() {
DCHECK(!drag_handle_nudge_); DCHECK(!drag_handle_nudge_);
drag_handle_nudge_ = new ContextualNudge( drag_handle_nudge_ = new ContextualNudge(
...@@ -251,7 +294,7 @@ void DragHandle::HideDragHandleNudgeHelper(bool hidden_by_tap) { ...@@ -251,7 +294,7 @@ void DragHandle::HideDragHandleNudgeHelper(bool hidden_by_tap) {
ui::ScopedLayerAnimationSettings opacity_animation_settings( ui::ScopedLayerAnimationSettings opacity_animation_settings(
opacity_animator); opacity_animator);
opacity_animation_settings.SetPreemptionStrategy( opacity_animation_settings.SetPreemptionStrategy(
ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
opacity_animation_settings.SetTweenType(gfx::Tween::LINEAR); opacity_animation_settings.SetTweenType(gfx::Tween::LINEAR);
opacity_animation_settings.SetTransitionDuration( opacity_animation_settings.SetTransitionDuration(
hidden_by_tap ? kDragHandleHideOnTapAnimationDuration hidden_by_tap ? kDragHandleHideOnTapAnimationDuration
...@@ -304,4 +347,9 @@ void DragHandle::HandleTapOnNudge() { ...@@ -304,4 +347,9 @@ void DragHandle::HandleTapOnNudge() {
HideDragHandleNudge(true /*hidden_by_tap*/); HideDragHandleNudge(true /*hidden_by_tap*/);
} }
void DragHandle::StopDragHandleNudgeShowTimer() {
show_drag_handle_nudge_timer_.Stop();
overview_observer_.RemoveAll();
}
} // namespace ash } // namespace ash
...@@ -8,7 +8,10 @@ ...@@ -8,7 +8,10 @@
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ash/shelf/contextual_nudge.h" #include "ash/shelf/contextual_nudge.h"
#include "ash/shelf/shelf_widget.h" #include "ash/shelf/shelf_widget.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_observer.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "ui/compositor/layer_animator.h" #include "ui/compositor/layer_animator.h"
#include "ui/views/view.h" #include "ui/views/view.h"
...@@ -17,7 +20,8 @@ ...@@ -17,7 +20,8 @@
namespace ash { namespace ash {
class ASH_EXPORT DragHandle : public views::View, class ASH_EXPORT DragHandle : public views::View,
public views::ViewTargeterDelegate { public views::ViewTargeterDelegate,
public OverviewObserver {
public: public:
explicit DragHandle(int drag_handle_corner_radius); explicit DragHandle(int drag_handle_corner_radius);
DragHandle(const DragHandle&) = delete; DragHandle(const DragHandle&) = delete;
...@@ -45,10 +49,17 @@ class ASH_EXPORT DragHandle : public views::View, ...@@ -45,10 +49,17 @@ class ASH_EXPORT DragHandle : public views::View,
// tapping the nudge. // tapping the nudge.
void HideDragHandleNudge(bool hidden_by_tap); void HideDragHandleNudge(bool hidden_by_tap);
// Called when the window drag from shelf starts or ends. The drag handle
// contextual nudge will remain visible while the gesture is in progress.
void SetWindowDragFromShelfInProgress(bool gesture_in_progress);
// views::View: // views::View:
void OnGestureEvent(ui::GestureEvent* event) override; void OnGestureEvent(ui::GestureEvent* event) override;
gfx::Rect GetAnchorBoundsInScreen() const override; gfx::Rect GetAnchorBoundsInScreen() const override;
// OverviewObserver:
void OnOverviewModeStarting() override;
bool ShowingNudge() { return showing_nudge_; } bool ShowingNudge() { return showing_nudge_; }
bool has_show_drag_handle_timer_for_testing() { bool has_show_drag_handle_timer_for_testing() {
...@@ -63,6 +74,10 @@ class ASH_EXPORT DragHandle : public views::View, ...@@ -63,6 +74,10 @@ class ASH_EXPORT DragHandle : public views::View,
return hide_drag_handle_nudge_timer_.IsRunning(); return hide_drag_handle_nudge_timer_.IsRunning();
} }
void fire_hide_drag_handle_timer_for_testing() {
hide_drag_handle_nudge_timer_.FireNow();
}
ContextualNudge* drag_handle_nudge_for_testing() { ContextualNudge* drag_handle_nudge_for_testing() {
return drag_handle_nudge_; return drag_handle_nudge_;
} }
...@@ -90,6 +105,9 @@ class ASH_EXPORT DragHandle : public views::View, ...@@ -90,6 +105,9 @@ class ASH_EXPORT DragHandle : public views::View,
// Handler for tap gesture on the contextual nudge widget. It hides the nudge. // Handler for tap gesture on the contextual nudge widget. It hides the nudge.
void HandleTapOnNudge(); void HandleTapOnNudge();
// Stops the timer to show the drag handle nudge.
void StopDragHandleNudgeShowTimer();
// Timer to hide drag handle nudge if it has a timed life. // Timer to hide drag handle nudge if it has a timed life.
base::OneShotTimer hide_drag_handle_nudge_timer_; base::OneShotTimer hide_drag_handle_nudge_timer_;
...@@ -98,9 +116,16 @@ class ASH_EXPORT DragHandle : public views::View, ...@@ -98,9 +116,16 @@ class ASH_EXPORT DragHandle : public views::View,
bool showing_nudge_ = false; bool showing_nudge_ = false;
// Whether window drag from shelf (i.e. gesture from in-app shelf to home or
// overview) is currently in progress. If the contextual nudge is shown when
// the gesture starts, it should remain shown until the gesture ends.
// Set by ShelfLayoutManager using SetWindowDragFromShelfInProgress().
bool window_drag_from_shelf_in_progress_ = false;
// A label used to educate users about swipe gestures on the drag handle. // A label used to educate users about swipe gestures on the drag handle.
ContextualNudge* drag_handle_nudge_ = nullptr; ContextualNudge* drag_handle_nudge_ = nullptr;
ScopedObserver<OverviewController, OverviewObserver> overview_observer_{this};
base::WeakPtrFactory<DragHandle> weak_factory_{this}; base::WeakPtrFactory<DragHandle> weak_factory_{this};
}; };
......
This diff is collapsed.
...@@ -2603,6 +2603,8 @@ bool ShelfLayoutManager::MaybeStartDragWindowFromShelf( ...@@ -2603,6 +2603,8 @@ bool ShelfLayoutManager::MaybeStartDragWindowFromShelf(
return false; return false;
} }
shelf_widget_->GetDragHandle()->SetWindowDragFromShelfInProgress(true);
aura::Window* window = aura::Window* window =
GetWindowForDragToHomeOrOverview(event_in_screen.location()); GetWindowForDragToHomeOrOverview(event_in_screen.location());
allow_fling_from_overview_to_home_ = !window; allow_fling_from_overview_to_home_ = !window;
...@@ -2632,6 +2634,8 @@ base::Optional<ShelfWindowDragResult> ShelfLayoutManager::MaybeEndWindowDrag( ...@@ -2632,6 +2634,8 @@ base::Optional<ShelfWindowDragResult> ShelfLayoutManager::MaybeEndWindowDrag(
if (!IsWindowDragInProgress()) if (!IsWindowDragInProgress())
return base::nullopt; return base::nullopt;
shelf_widget_->GetDragHandle()->SetWindowDragFromShelfInProgress(false);
DCHECK_EQ(drag_status_, kDragInProgress); DCHECK_EQ(drag_status_, kDragInProgress);
base::Optional<float> velocity_y; base::Optional<float> velocity_y;
if (event_in_screen.type() == ui::ET_SCROLL_FLING_START) { if (event_in_screen.type() == ui::ET_SCROLL_FLING_START) {
...@@ -2653,6 +2657,8 @@ bool ShelfLayoutManager::MaybeEndDragFromOverviewToHome( ...@@ -2653,6 +2657,8 @@ bool ShelfLayoutManager::MaybeEndDragFromOverviewToHome(
return false; return false;
} }
shelf_widget_->GetDragHandle()->SetWindowDragFromShelfInProgress(false);
if (event_in_screen.type() != ui::ET_SCROLL_FLING_START) if (event_in_screen.type() != ui::ET_SCROLL_FLING_START)
return false; return false;
...@@ -2685,6 +2691,7 @@ void ShelfLayoutManager::MaybeCancelWindowDrag() { ...@@ -2685,6 +2691,7 @@ void ShelfLayoutManager::MaybeCancelWindowDrag() {
return; return;
DCHECK_EQ(drag_status_, kDragInProgress); DCHECK_EQ(drag_status_, kDragInProgress);
shelf_widget_->GetDragHandle()->SetWindowDragFromShelfInProgress(false);
window_drag_controller_->CancelDrag(); window_drag_controller_->CancelDrag();
} }
......
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