mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-01 16:26:47 +00:00
Merge "Support 4-finger gesture to quick switch" into udc-dev
This commit is contained in:
@@ -15,11 +15,15 @@
|
||||
*/
|
||||
package com.android.launcher3.uioverrides.touchcontrollers;
|
||||
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
import static android.view.MotionEvent.ACTION_MOVE;
|
||||
|
||||
import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS;
|
||||
import static com.android.launcher3.LauncherState.QUICK_SWITCH_FROM_HOME;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadFourFingerSwipe;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
|
||||
import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD;
|
||||
import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
|
||||
@@ -106,6 +110,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
newCancelListener(this::clearState);
|
||||
|
||||
private boolean mNoIntercept;
|
||||
private Boolean mIsTrackpadFourFingerSwipe;
|
||||
private LauncherState mStartState;
|
||||
|
||||
private boolean mIsHomeScreenVisible = true;
|
||||
@@ -131,7 +136,9 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
|
||||
@Override
|
||||
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
int action = ev.getActionMasked();
|
||||
if (action == ACTION_DOWN) {
|
||||
mIsTrackpadFourFingerSwipe = null;
|
||||
mNoIntercept = !canInterceptTouch(ev);
|
||||
if (mNoIntercept) {
|
||||
return false;
|
||||
@@ -140,6 +147,13 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
// Only detect horizontal swipe for intercept, then we will allow swipe up as well.
|
||||
mSwipeDetector.setDetectableScrollConditions(DIRECTION_RIGHT,
|
||||
false /* ignoreSlopWhenSettling */);
|
||||
} else if (isTrackpadMultiFingerSwipe(ev) && mIsTrackpadFourFingerSwipe == null
|
||||
&& action == ACTION_MOVE) {
|
||||
mIsTrackpadFourFingerSwipe = isTrackpadFourFingerSwipe(ev);
|
||||
mNoIntercept = !mIsTrackpadFourFingerSwipe;
|
||||
if (mNoIntercept) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mNoIntercept) {
|
||||
@@ -162,9 +176,6 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
if ((ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) == 0) {
|
||||
return false;
|
||||
}
|
||||
if (isTrackpadMultiFingerSwipe(ev)) {
|
||||
return false;
|
||||
}
|
||||
int stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
|
||||
if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0) {
|
||||
return false;
|
||||
|
||||
@@ -2064,8 +2064,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController,
|
||||
mRecentsAnimationTargets));
|
||||
|
||||
// Disable scrolling in RecentsView for trackpad gestures.
|
||||
if (!mGestureState.isTrackpadGesture()) {
|
||||
// Disable scrolling in RecentsView for trackpad 3-finger swipe up gesture.
|
||||
if (!mGestureState.isThreeFingerTrackpadGesture()) {
|
||||
mRecentsViewScrollLinked = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadFourFingerSwipe;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadThreeFingerSwipe;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
|
||||
@@ -27,6 +30,7 @@ import android.annotation.Nullable;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
|
||||
import com.android.launcher3.statemanager.BaseState;
|
||||
@@ -139,8 +143,30 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
private final BaseActivityInterface mActivityInterface;
|
||||
private final MultiStateCallback mStateCallback;
|
||||
private final int mGestureId;
|
||||
private boolean mIsTrackpadGesture;
|
||||
|
||||
public enum TrackpadGestureType {
|
||||
NONE,
|
||||
// Assigned before we know whether it's a 3-finger or 4-finger gesture.
|
||||
MULTI_FINGER,
|
||||
THREE_FINGER,
|
||||
FOUR_FINGER;
|
||||
|
||||
public static TrackpadGestureType getTrackpadGestureType(MotionEvent event) {
|
||||
if (!isTrackpadMultiFingerSwipe(event)) {
|
||||
return TrackpadGestureType.NONE;
|
||||
}
|
||||
if (isTrackpadThreeFingerSwipe(event)) {
|
||||
return TrackpadGestureType.THREE_FINGER;
|
||||
}
|
||||
if (isTrackpadFourFingerSwipe(event)) {
|
||||
return TrackpadGestureType.FOUR_FINGER;
|
||||
}
|
||||
|
||||
return TrackpadGestureType.MULTI_FINGER;
|
||||
}
|
||||
}
|
||||
|
||||
private TrackpadGestureType mTrackpadGestureType = TrackpadGestureType.NONE;
|
||||
private CachedTaskInfo mRunningTask;
|
||||
private GestureEndTarget mEndTarget;
|
||||
private RemoteAnimationTarget mLastAppearedTaskTarget;
|
||||
@@ -249,17 +275,22 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the gesture is is from the trackpad.
|
||||
* Sets if the gesture is is from the trackpad, if so, whether 3-finger, or 4-finger
|
||||
*/
|
||||
public void setIsTrackpadGesture(boolean isTrackpadGesture) {
|
||||
mIsTrackpadGesture = isTrackpadGesture;
|
||||
public void setTrackpadGestureType(TrackpadGestureType trackpadGestureType) {
|
||||
mTrackpadGestureType = trackpadGestureType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if the gesture is from the trackpad.
|
||||
*/
|
||||
public boolean isTrackpadGesture() {
|
||||
return mIsTrackpadGesture;
|
||||
return mTrackpadGestureType != TrackpadGestureType.NONE;
|
||||
}
|
||||
|
||||
public boolean isThreeFingerTrackpadGesture() {
|
||||
return mTrackpadGestureType == TrackpadGestureType.THREE_FINGER;
|
||||
}
|
||||
|
||||
public boolean isFourFingerTrackpadGesture() {
|
||||
return mTrackpadGestureType == TrackpadGestureType.FOUR_FINGER;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -249,7 +249,7 @@ public class OverviewCommandHelper {
|
||||
}
|
||||
|
||||
GestureState gestureState = mService.createGestureState(GestureState.DEFAULT_STATE,
|
||||
false /* isTrackpadGesture */);
|
||||
GestureState.TrackpadGestureType.NONE);
|
||||
gestureState.setHandlingAtomicEvent(true);
|
||||
AbsSwipeUpHandler interactionHandler = mService.getSwipeUpHandlerFactory()
|
||||
.newHandler(gestureState, cmd.createTime);
|
||||
|
||||
@@ -24,11 +24,11 @@ import static android.view.MotionEvent.ACTION_POINTER_UP;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
|
||||
import static com.android.launcher3.Launcher.INTENT_ACTION_ALL_APPS_TOGGLE;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
|
||||
import static com.android.launcher3.config.FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.quickstep.GestureState.DEFAULT_STATE;
|
||||
import static com.android.quickstep.GestureState.TrackpadGestureType.getTrackpadGestureType;
|
||||
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER;
|
||||
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_DOWN;
|
||||
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_MOVE;
|
||||
@@ -647,7 +647,7 @@ public class TouchInteractionService extends Service
|
||||
// onConsumerInactive and wipe the previous gesture state
|
||||
GestureState prevGestureState = new GestureState(mGestureState);
|
||||
GestureState newGestureState = createGestureState(mGestureState,
|
||||
isTrackpadMultiFingerSwipe(event));
|
||||
getTrackpadGestureType(event));
|
||||
newGestureState.setSwipeUpStartTimeMs(SystemClock.uptimeMillis());
|
||||
mConsumer.onConsumerAboutToBeSwitched();
|
||||
mGestureState = newGestureState;
|
||||
@@ -656,7 +656,7 @@ public class TouchInteractionService extends Service
|
||||
} else if (mDeviceState.isUserUnlocked() && mDeviceState.isFullyGesturalNavMode()
|
||||
&& mDeviceState.canTriggerAssistantAction(event)) {
|
||||
mGestureState = createGestureState(mGestureState,
|
||||
isTrackpadMultiFingerSwipe(event));
|
||||
getTrackpadGestureType(event));
|
||||
// Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we
|
||||
// should not interrupt it. QuickSwitch assumes that interruption can only
|
||||
// happen if the next gesture is also quick switch.
|
||||
@@ -713,9 +713,13 @@ public class TouchInteractionService extends Service
|
||||
event.setAction(ACTION_CANCEL);
|
||||
}
|
||||
|
||||
// Skip ACTION_POINTER_DOWN and ACTION_POINTER_UP events from trackpad.
|
||||
if (!mGestureState.isTrackpadGesture() || (action != ACTION_POINTER_DOWN
|
||||
&& action != ACTION_POINTER_UP)) {
|
||||
if (mGestureState.isTrackpadGesture() && (action == ACTION_POINTER_DOWN
|
||||
|| action == ACTION_POINTER_UP)) {
|
||||
// Skip ACTION_POINTER_DOWN and ACTION_POINTER_UP events from trackpad.
|
||||
if (action == ACTION_POINTER_DOWN) {
|
||||
mGestureState.setTrackpadGestureType(getTrackpadGestureType(event));
|
||||
}
|
||||
} else {
|
||||
mUncheckedConsumer.onMotionEvent(event);
|
||||
}
|
||||
|
||||
@@ -749,7 +753,7 @@ public class TouchInteractionService extends Service
|
||||
}
|
||||
|
||||
public GestureState createGestureState(GestureState previousGestureState,
|
||||
boolean isTrackpadGesture) {
|
||||
GestureState.TrackpadGestureType trackpadGestureType) {
|
||||
final GestureState gestureState;
|
||||
TopTaskTracker.CachedTaskInfo taskInfo;
|
||||
if (mTaskAnimationManager.isRecentsAnimationRunning()) {
|
||||
@@ -766,7 +770,7 @@ public class TouchInteractionService extends Service
|
||||
taskInfo = TopTaskTracker.INSTANCE.get(this).getCachedTopTask(false);
|
||||
gestureState.updateRunningTask(taskInfo);
|
||||
}
|
||||
gestureState.setIsTrackpadGesture(isTrackpadGesture);
|
||||
gestureState.setTrackpadGestureType(trackpadGestureType);
|
||||
|
||||
// Log initial state for the gesture.
|
||||
ActiveGestureLog.INSTANCE.addLog(new CompoundString("Current running task package name=")
|
||||
|
||||
@@ -203,8 +203,24 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
}
|
||||
int edgeFlags = ev.getEdgeFlags();
|
||||
ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR);
|
||||
// Disable scrolling in RecentsView for trackpad gestures.
|
||||
if (!mGestureState.isTrackpadGesture()) {
|
||||
|
||||
if (mGestureState.isTrackpadGesture()) {
|
||||
// Disable scrolling in RecentsView for 3-finger trackpad gesture. We don't know if a
|
||||
// trackpad motion event is 3-finger or 4-finger with the U API until ACTION_MOVE (we
|
||||
// skip ACTION_POINTER_UP events in TouchInteractionService), so in order to make sure
|
||||
// that RecentsView always get a closed sequence of motion events and yet disable
|
||||
// 3-finger scroll, we do the following (1) always dispatch ACTION_DOWN and ACTION_UP
|
||||
// trackpad multi-finger motion events. (2) only dispatch 4-finger ACTION_MOVE motion
|
||||
// events.
|
||||
switch (ev.getActionMasked()) {
|
||||
case ACTION_MOVE -> {
|
||||
if (mGestureState.isFourFingerTrackpadGesture()) {
|
||||
mRecentsViewDispatcher.dispatchEvent(ev);
|
||||
}
|
||||
}
|
||||
default -> mRecentsViewDispatcher.dispatchEvent(ev);
|
||||
}
|
||||
} else {
|
||||
mRecentsViewDispatcher.dispatchEvent(ev);
|
||||
}
|
||||
ev.setEdgeFlags(edgeFlags);
|
||||
@@ -312,9 +328,12 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
// Do not allow quick switch for trackpad 3-finger gestures
|
||||
// TODO(b/261815244): might need to impose stronger conditions for the swipe
|
||||
// angle
|
||||
boolean noQuickSwitchForTrackpadGesture = mGestureState.isTrackpadGesture()
|
||||
&& isLikelyToStartNewTask;
|
||||
if (isHorizontalSwipeWhenDisabled || noQuickSwitchForTrackpadGesture) {
|
||||
boolean noQuickSwitchForThreeFingerGesture = isLikelyToStartNewTask
|
||||
&& mGestureState.isThreeFingerTrackpadGesture();
|
||||
boolean noQuickstepForFourFingerGesture = !isLikelyToStartNewTask
|
||||
&& mGestureState.isFourFingerTrackpadGesture();
|
||||
if (isHorizontalSwipeWhenDisabled || noQuickSwitchForThreeFingerGesture
|
||||
|| noQuickstepForFourFingerGesture) {
|
||||
forceCancelGesture(ev);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,14 @@ public class MotionEventsUtils {
|
||||
&& event.getClassification() == CLASSIFICATION_MULTI_FINGER_SWIPE;
|
||||
}
|
||||
|
||||
public static boolean isTrackpadThreeFingerSwipe(MotionEvent event) {
|
||||
return isTrackpadMultiFingerSwipe(event) && event.getPointerCount() == 3;
|
||||
}
|
||||
|
||||
public static boolean isTrackpadFourFingerSwipe(MotionEvent event) {
|
||||
return isTrackpadMultiFingerSwipe(event) && event.getPointerCount() == 4;
|
||||
}
|
||||
|
||||
public static boolean isTrackpadMotionEvent(MotionEvent event) {
|
||||
return isTrackpadScroll(event) || isTrackpadMultiFingerSwipe(event);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user