Merge "Let the bubble bar handle gestures over the bubble bar." into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
44bd688301
@@ -155,7 +155,7 @@ public class TaskbarUIController {
|
||||
mControllers.taskbarActivityContext.startTranslationSpring();
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* @param ev MotionEvent in screen coordinates.
|
||||
* @return Whether any Taskbar item could handle the given MotionEvent if given the chance.
|
||||
*/
|
||||
@@ -164,6 +164,14 @@ public class TaskbarUIController {
|
||||
|| mControllers.navbarButtonsViewController.isEventOverAnyItem(ev);
|
||||
}
|
||||
|
||||
/** Checks if the given {@link MotionEvent} is over the bubble bar stash handle. */
|
||||
public boolean isEventOverBubbleBarStashHandle(MotionEvent ev) {
|
||||
return mControllers.bubbleControllers.map(
|
||||
bubbleControllers ->
|
||||
bubbleControllers.bubbleStashController.isEventOverStashHandle(ev))
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if icons should be aligned to hotseat in the current transition.
|
||||
*/
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.annotation.Nullable;
|
||||
import android.view.InsetsController;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.anim.AnimatedFloat;
|
||||
import com.android.launcher3.taskbar.StashedHandleViewController;
|
||||
@@ -350,4 +351,9 @@ public class BubbleStashController {
|
||||
return mBubblesShowingOnHome ? getBubbleBarTranslationYForHotseat()
|
||||
: getBubbleBarTranslationYForTaskbar();
|
||||
}
|
||||
|
||||
/** Checks whether the motion event is over the stash handle. */
|
||||
public boolean isEventOverStashHandle(MotionEvent ev) {
|
||||
return mHandleViewController.isEventOverHandle(ev);
|
||||
}
|
||||
}
|
||||
|
||||
+19
@@ -24,6 +24,7 @@ import android.animation.ValueAnimator;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Rect;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewOutlineProvider;
|
||||
|
||||
@@ -268,4 +269,22 @@ public class BubbleStashedHandleViewController {
|
||||
});
|
||||
return revealAnim;
|
||||
}
|
||||
|
||||
/** Checks that the stash handle is visible and that the motion event is within bounds. */
|
||||
public boolean isEventOverHandle(MotionEvent ev) {
|
||||
if (mStashedHandleView.getVisibility() != VISIBLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// the bounds of the handle only include the visible part, so we check that the Y coordinate
|
||||
// is anywhere within the stashed taskbar height.
|
||||
int top = mActivity.getDeviceProfile().heightPx - mStashedTaskbarHeight;
|
||||
|
||||
return (int) ev.getRawY() >= top && containsX((int) ev.getRawX());
|
||||
}
|
||||
|
||||
/** Checks if the given x coordinate is within the stashed handle bounds. */
|
||||
public boolean containsX(int x) {
|
||||
return x >= mStashedHandleBounds.left && x <= mStashedHandleBounds.right;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,8 +191,11 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
public abstract boolean allowAllAppsFromOverview();
|
||||
|
||||
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
|
||||
TaskbarUIController controller = getTaskbarController();
|
||||
boolean isEventOverBubbleBarStashHandle =
|
||||
controller != null && controller.isEventOverBubbleBarStashHandle(ev);
|
||||
return deviceState.isInDeferredGestureRegion(ev) || deviceState.isImeRenderingNavButtons()
|
||||
|| isTrackpadMultiFingerSwipe(ev);
|
||||
|| isTrackpadMultiFingerSwipe(ev) || isEventOverBubbleBarStashHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+89
-24
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package com.android.quickstep.inputconsumers;
|
||||
|
||||
import static android.view.MotionEvent.ACTION_CANCEL;
|
||||
import static android.view.MotionEvent.ACTION_MOVE;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
import static android.view.MotionEvent.INVALID_POINTER_ID;
|
||||
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent;
|
||||
@@ -30,6 +33,7 @@ import android.view.GestureDetector;
|
||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -68,6 +72,9 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
|
||||
private final boolean mIsTaskbarAllAppsOpen;
|
||||
private boolean mHasPassedTaskbarNavThreshold;
|
||||
private boolean mIsInBubbleBarArea;
|
||||
private boolean mIsVerticalGestureOverBubbleBar;
|
||||
private boolean mIsPassedBubbleBarSlop;
|
||||
private final int mTouchSlop;
|
||||
|
||||
private final PointF mDownPos = new PointF();
|
||||
private final PointF mLastPos = new PointF();
|
||||
@@ -91,6 +98,7 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
|
||||
mOverviewCommandHelper = overviewCommandHelper;
|
||||
// TODO(b/270395798): remove this when cleaning up old Persistent Taskbar code.
|
||||
mSquaredTouchSlop = Utilities.squaredTouchSlop(context);
|
||||
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||
mScreenWidth = taskbarActivityContext.getDeviceProfile().widthPx;
|
||||
|
||||
Resources res = context.getResources();
|
||||
@@ -99,8 +107,7 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
|
||||
taskbarActivityContext.getDeviceProfile());
|
||||
mTaskbarNavThresholdY = taskbarActivityContext.getDeviceProfile().heightPx
|
||||
- mTaskbarNavThreshold;
|
||||
mIsTaskbarAllAppsOpen =
|
||||
mTaskbarActivityContext != null && mTaskbarActivityContext.isTaskbarAllAppsOpen();
|
||||
mIsTaskbarAllAppsOpen = mTaskbarActivityContext.isTaskbarAllAppsOpen();
|
||||
|
||||
mIsTransientTaskbar = DisplayController.isTransientTaskbar(context);
|
||||
|
||||
@@ -132,12 +139,8 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
|
||||
if (mState != STATE_ACTIVE) {
|
||||
boolean isStashedTaskbarHovered = isMouseEvent(ev)
|
||||
&& isStashedTaskbarHovered((int) ev.getX(), (int) ev.getY());
|
||||
if (!isStashedTaskbarHovered) {
|
||||
mDelegate.onMotionEvent(ev);
|
||||
}
|
||||
|
||||
// Only show the transient task bar if the touch events are on the screen.
|
||||
if (mTaskbarActivityContext != null && !isTrackpadMotionEvent(ev)) {
|
||||
if (!isTrackpadMotionEvent(ev)) {
|
||||
final float x = ev.getRawX();
|
||||
final float y = ev.getRawY();
|
||||
switch (ev.getAction()) {
|
||||
@@ -193,14 +196,28 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
|
||||
}
|
||||
mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
|
||||
|
||||
float dX = mLastPos.x - mDownPos.x;
|
||||
float dY = mLastPos.y - mDownPos.y;
|
||||
|
||||
if (!mIsPassedBubbleBarSlop && mIsInBubbleBarArea) {
|
||||
boolean passedSlop =
|
||||
Math.abs(dY) > mTouchSlop || Math.abs(dX) > mTouchSlop;
|
||||
if (passedSlop) {
|
||||
mIsPassedBubbleBarSlop = true;
|
||||
mIsVerticalGestureOverBubbleBar = Math.abs(dY) > Math.abs(dX);
|
||||
if (mIsVerticalGestureOverBubbleBar) {
|
||||
setActive(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mIsTransientTaskbar) {
|
||||
float dY = mLastPos.y - mDownPos.y;
|
||||
boolean passedTaskbarNavThreshold = dY < 0
|
||||
&& Math.abs(dY) >= mTaskbarNavThreshold;
|
||||
|
||||
if (!mHasPassedTaskbarNavThreshold && passedTaskbarNavThreshold) {
|
||||
mHasPassedTaskbarNavThreshold = true;
|
||||
if (mIsInBubbleBarArea) {
|
||||
if (mIsInBubbleBarArea && mIsVerticalGestureOverBubbleBar) {
|
||||
mTaskbarActivityContext.onSwipeToOpenBubblebar();
|
||||
} else {
|
||||
mTaskbarActivityContext.onSwipeToUnstashTaskbar();
|
||||
@@ -217,17 +234,7 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
if (!mIsTransientTaskbar && !mCanceledUnstashHint) {
|
||||
mTaskbarActivityContext.startTaskbarUnstashHint(
|
||||
/* animateForward = */ false);
|
||||
}
|
||||
mTaskbarActivityContext.setAutohideSuspendFlag(
|
||||
FLAG_AUTOHIDE_SUSPEND_TOUCHING, false);
|
||||
if (mTransitionCallback != null) {
|
||||
mTransitionCallback.onActionEnd();
|
||||
}
|
||||
mHasPassedTaskbarNavThreshold = false;
|
||||
mIsInBubbleBarArea = false;
|
||||
cleanupAfterMotionEvent();
|
||||
break;
|
||||
case MotionEvent.ACTION_BUTTON_RELEASE:
|
||||
if (isStashedTaskbarHovered) {
|
||||
@@ -236,9 +243,61 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
|
||||
break;
|
||||
}
|
||||
}
|
||||
boolean isMovingInBubbleBarArea = mIsInBubbleBarArea && ev.getAction() == ACTION_MOVE;
|
||||
if (!isStashedTaskbarHovered) {
|
||||
// if we're moving in the bubble bar area but we haven't passed the slop yet, don't
|
||||
// propagate to the delegate, until we can determine the direction of the gesture.
|
||||
if (!isMovingInBubbleBarArea || mIsPassedBubbleBarSlop) {
|
||||
mDelegate.onMotionEvent(ev);
|
||||
}
|
||||
}
|
||||
} else if (mIsVerticalGestureOverBubbleBar) {
|
||||
// if we get here then this gesture is a vertical swipe over the bubble bar.
|
||||
// we're also active and there's no need to delegate any additional motion events. the
|
||||
// rest of the gesture will be handled here.
|
||||
switch (ev.getAction()) {
|
||||
case ACTION_MOVE:
|
||||
int pointerIndex = ev.findPointerIndex(mActivePointerId);
|
||||
if (pointerIndex == INVALID_POINTER_ID) {
|
||||
break;
|
||||
}
|
||||
mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
|
||||
|
||||
float dY = mLastPos.y - mDownPos.y;
|
||||
|
||||
// bubble bar swipe gesture uses the same threshold as the taskbar.
|
||||
boolean passedTaskbarNavThreshold = dY < 0
|
||||
&& Math.abs(dY) >= mTaskbarNavThreshold;
|
||||
|
||||
if (!mHasPassedTaskbarNavThreshold && passedTaskbarNavThreshold) {
|
||||
mHasPassedTaskbarNavThreshold = true;
|
||||
mTaskbarActivityContext.onSwipeToOpenBubblebar();
|
||||
}
|
||||
break;
|
||||
case ACTION_UP:
|
||||
case ACTION_CANCEL:
|
||||
cleanupAfterMotionEvent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanupAfterMotionEvent() {
|
||||
if (!mIsTransientTaskbar && !mCanceledUnstashHint) {
|
||||
mTaskbarActivityContext.startTaskbarUnstashHint(
|
||||
/* animateForward = */ false);
|
||||
}
|
||||
mTaskbarActivityContext.setAutohideSuspendFlag(
|
||||
FLAG_AUTOHIDE_SUSPEND_TOUCHING, false);
|
||||
if (mTransitionCallback != null) {
|
||||
mTransitionCallback.onActionEnd();
|
||||
}
|
||||
mHasPassedTaskbarNavThreshold = false;
|
||||
mIsInBubbleBarArea = false;
|
||||
mIsVerticalGestureOverBubbleBar = false;
|
||||
mIsPassedBubbleBarSlop = false;
|
||||
}
|
||||
|
||||
private boolean isInTaskbarArea(float x) {
|
||||
float areaFromMiddle = mUnstashArea / 2.0f;
|
||||
float distFromMiddle = Math.abs(mScreenWidth / 2.0f - x);
|
||||
@@ -246,13 +305,19 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
|
||||
}
|
||||
|
||||
private boolean isInBubbleBarArea(float x) {
|
||||
if (mTaskbarActivityContext != null && mIsTransientTaskbar) {
|
||||
BubbleControllers controllers = mTaskbarActivityContext.getBubbleControllers();
|
||||
if (controllers == null) return false;
|
||||
if (mTaskbarActivityContext == null || !mIsTransientTaskbar) {
|
||||
return false;
|
||||
}
|
||||
BubbleControllers controllers = mTaskbarActivityContext.getBubbleControllers();
|
||||
if (controllers == null) {
|
||||
return false;
|
||||
}
|
||||
if (controllers.bubbleStashController.isStashed()) {
|
||||
return controllers.bubbleStashedHandleViewController.containsX((int) x);
|
||||
} else {
|
||||
Rect bubbleBarBounds = controllers.bubbleBarViewController.getBubbleBarBounds();
|
||||
return x >= bubbleBarBounds.left && x <= bubbleBarBounds.right;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void onLongPressDetected(MotionEvent motionEvent) {
|
||||
|
||||
Reference in New Issue
Block a user