Can now swipe away to dismiss second task
Previously we only allowed dragging the forefront task. Now you can
swipe up to dismiss the second task as well, but can't drag it down to
launch.
Also cleaned up page-scroll-while-dismissing logic to ensure it works
correctly in RTL and for new cases with dismissing adjacent pages.
Bug: 73187449
Change-Id: I1fe873c4cf1380b951dd3b2e396ab401ca1f7470
diff --git a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
index e73b219..42f8105 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
@@ -22,7 +22,6 @@
import android.animation.ValueAnimator;
import android.util.Log;
import android.view.MotionEvent;
-import android.view.View;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
@@ -32,9 +31,9 @@
import com.android.launcher3.touch.SwipeDetector;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.util.PendingAnimation;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
-import com.android.launcher3.util.PendingAnimation;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -107,7 +106,7 @@
// Now figure out which direction scroll events the controller will start
// calling the callbacks.
- final int directionsToDetectScroll;
+ int directionsToDetectScroll = 0;
boolean ignoreSlopWhenSettling = false;
if (mCurrentAnimation != null) {
directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH;
@@ -115,12 +114,19 @@
} else {
mTaskBeingDragged = null;
- View view = mRecentsView.getChildAt(mRecentsView.getCurrentPage());
- if (view instanceof TaskView && mActivity.getDragLayer().isEventOverView(view, ev)) {
- // The tile can be dragged down to open the task.
- mTaskBeingDragged = (TaskView) view;
- directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH;
- } else {
+ for (int i = 0; i < mRecentsView.getChildCount(); i++) {
+ TaskView view = mRecentsView.getPageAt(i);
+ if (mRecentsView.isTaskViewVisible(view) && mActivity.getDragLayer()
+ .isEventOverView(view, ev)) {
+ // The task can be dragged up to dismiss it,
+ // and down to open if it's the current page.
+ mTaskBeingDragged = view;
+ directionsToDetectScroll = i == mRecentsView.getCurrentPage()
+ ? SwipeDetector.DIRECTION_BOTH : SwipeDetector.DIRECTION_POSITIVE;
+ break;
+ }
+ }
+ if (mTaskBeingDragged == null) {
mNoIntercept = true;
return false;
}
@@ -143,10 +149,16 @@
return mDetector.onTouchEvent(ev);
}
- private void reInitAnimationController(boolean goingUp) {
+ private boolean reInitAnimationController(boolean goingUp) {
if (mCurrentAnimation != null && mCurrentAnimationIsGoingUp == goingUp) {
// No need to init
- return;
+ return false;
+ }
+ int scrollDirections = mDetector.getScrollDirections();
+ if (goingUp && ((scrollDirections & SwipeDetector.DIRECTION_POSITIVE) == 0)
+ || !goingUp && ((scrollDirections & SwipeDetector.DIRECTION_NEGATIVE) == 0)) {
+ // Trying to re-init in an unsupported direction.
+ return false;
}
if (mCurrentAnimation != null) {
mCurrentAnimation.setPlayFraction(0);
@@ -180,6 +192,7 @@
mCurrentAnimation.getTarget().addListener(this);
mCurrentAnimation.dispatchOnStart();
mProgressMultiplier = 1 / mEndDisplacement;
+ return true;
}
@Override
@@ -220,8 +233,7 @@
// Not allowed
goingToEnd = false;
} else {
- reInitAnimationController(goingUp);
- goingToEnd = true;
+ goingToEnd = reInitAnimationController(goingUp);
}
} else {
goingToEnd = true;
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index d95619c..644b098 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -708,14 +708,14 @@
int[] newScroll = new int[count];
getPageScrolls(newScroll, false, (v) -> v.getVisibility() != GONE && v != taskView);
- int maxScrollDiff = 0;
- int lastPage = mIsRtl ? 0 : count - 1;
- if (getChildAt(lastPage) == taskView) {
- if (count > 1) {
- int secondLastPage = mIsRtl ? 1 : count - 2;
- maxScrollDiff = oldScroll[lastPage] - newScroll[secondLastPage];
- }
+ int scrollDiffPerPage = 0;
+ int leftmostPage = mIsRtl ? count -1 : 0;
+ int rightmostPage = mIsRtl ? 0 : count - 1;
+ if (count > 1) {
+ int secondRightmostPage = mIsRtl ? 1 : count - 2;
+ scrollDiffPerPage = oldScroll[rightmostPage] - oldScroll[secondRightmostPage];
}
+ int draggedIndex = indexOfChild(taskView);
boolean needsCurveUpdates = false;
for (int i = 0; i < count; i++) {
@@ -727,7 +727,26 @@
duration, LINEAR, anim);
}
} else {
- int scrollDiff = newScroll[i] - oldScroll[i] + maxScrollDiff;
+ // If we just take newScroll - oldScroll, everything to the right of dragged task
+ // translates to the left. We need to offset this in some cases:
+ // - In RTL, add page offset to all pages, since we want pages to move to the right
+ // Additionally, add a page offset if:
+ // - Current page is rightmost page (leftmost for RTL)
+ // - Dragging an adjacent page on the left side (right side for RTL)
+ int offset = mIsRtl ? scrollDiffPerPage : 0;
+ if (mCurrentPage == draggedIndex) {
+ int lastPage = mIsRtl ? leftmostPage : rightmostPage;
+ if (mCurrentPage == lastPage) {
+ offset += mIsRtl ? -scrollDiffPerPage : scrollDiffPerPage;
+ }
+ } else {
+ // Dragging an adjacent page.
+ int negativeAdjacent = mCurrentPage - 1; // (Right in RTL, left in LTR)
+ if (draggedIndex == negativeAdjacent) {
+ offset += mIsRtl ? -scrollDiffPerPage : scrollDiffPerPage;
+ }
+ }
+ int scrollDiff = newScroll[i] - oldScroll[i] + offset;
if (scrollDiff != 0) {
addAnim(ObjectAnimator.ofFloat(child, TRANSLATION_X, scrollDiff),
duration, ACCEL, anim);
@@ -753,9 +772,15 @@
if (removeTask) {
ActivityManagerWrapper.getInstance().removeTask(taskView.getTask().key.id);
}
+ int pageToSnapTo = mCurrentPage;
+ if (draggedIndex < pageToSnapTo) {
+ pageToSnapTo -= 1;
+ }
removeView(taskView);
if (getChildCount() == 0) {
onAllTasksRemoved();
+ } else {
+ snapToPageImmediately(pageToSnapTo);
}
}
resetTaskVisuals();
diff --git a/src/com/android/launcher3/touch/SwipeDetector.java b/src/com/android/launcher3/touch/SwipeDetector.java
index 4b36ad9..703e4fd 100644
--- a/src/com/android/launcher3/touch/SwipeDetector.java
+++ b/src/com/android/launcher3/touch/SwipeDetector.java
@@ -194,6 +194,10 @@
mIgnoreSlopWhenSettling = ignoreSlop;
}
+ public int getScrollDirections() {
+ return mScrollConditions;
+ }
+
private boolean shouldScrollStart(MotionEvent ev, int pointerIndex) {
// reject cases where the angle or slop condition is not met.
if (Math.max(mDir.getActiveTouchSlop(ev, pointerIndex, mDownPos), mTouchSlop)