mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 11:18:21 +00:00
Launcher3: Fix overview scrolling scale animation
Adapt it for Live Tile support + fix landscape handling Change-Id: I1cf5d79aa6373e836d33bc7ddb15c0c5258a63d7 Signed-off-by: Adithya R <gh0strider.2k18.reborn@gmail.com>
This commit is contained in:
@@ -191,19 +191,18 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
|
||||
protected MultiStateCallback mStateCallback;
|
||||
protected boolean mCanceled;
|
||||
private boolean mRecentsViewScrollLinked = false;
|
||||
private final ActivityLifecycleCallbacksAdapter mLifecycleCallbacks =
|
||||
new ActivityLifecycleCallbacksAdapter() {
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {
|
||||
if (mActivity != activity) {
|
||||
return;
|
||||
}
|
||||
ActiveGestureLog.INSTANCE.addLog("Launcher destroyed", LAUNCHER_DESTROYED);
|
||||
mRecentsView = null;
|
||||
mActivity = null;
|
||||
mStateCallback.clearState(STATE_LAUNCHER_PRESENT);
|
||||
}
|
||||
};
|
||||
private final ActivityLifecycleCallbacksAdapter mLifecycleCallbacks = new ActivityLifecycleCallbacksAdapter() {
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {
|
||||
if (mActivity != activity) {
|
||||
return;
|
||||
}
|
||||
ActiveGestureLog.INSTANCE.addLog("Launcher destroyed", LAUNCHER_DESTROYED);
|
||||
mRecentsView = null;
|
||||
mActivity = null;
|
||||
mStateCallback.clearState(STATE_LAUNCHER_PRESENT);
|
||||
}
|
||||
};
|
||||
private static int FLAG_COUNT = 0;
|
||||
|
||||
private static int getNextStateFlag(String name) {
|
||||
@@ -670,7 +669,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
|
||||
runningTasks = cachedTaskInfo.getPlaceholderTasks();
|
||||
}
|
||||
|
||||
|
||||
// Safeguard against any null tasks being sent to recents view, happens when
|
||||
// quickswitching
|
||||
// very quickly w/ split tasks because TopTaskTracker provides stale information
|
||||
@@ -1502,13 +1500,25 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
|
||||
ArrayList<IBinder> launchCookies, long duration, boolean isTargetTranslucent,
|
||||
boolean appCanEnterPip, RemoteAnimationTarget runningTaskTarget);
|
||||
|
||||
private final TaskStackChangeListener mActivityRestartListener=new TaskStackChangeListener(){@Override public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,boolean homeTaskVisible,boolean clearedTask,boolean wasVisible){boolean taskRunningAndNotHome=Arrays.stream(mGestureState.getRunningTaskIds(true /*
|
||||
* getMultipleTasks
|
||||
*/)).anyMatch(taskId->task.taskId==taskId&&task.configuration.windowConfiguration.getActivityType()!=ACTIVITY_TYPE_HOME);if(taskRunningAndNotHome){
|
||||
// Since this is an edge case, just cancel and relaunch with default activity
|
||||
// options (since we don't know if there's an associated app icon to launch
|
||||
// from)
|
||||
endRunningWindowAnim(true /* cancel */);TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mActivityRestartListener);ActivityManagerWrapper.getInstance().startActivityFromRecents(task.taskId,null);}}};
|
||||
private final TaskStackChangeListener mActivityRestartListener = new TaskStackChangeListener() {
|
||||
@Override
|
||||
public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, boolean homeTaskVisible,
|
||||
boolean clearedTask, boolean wasVisible) {
|
||||
boolean taskRunningAndNotHome = Arrays.stream(mGestureState.getRunningTaskIds(true /*
|
||||
* getMultipleTasks
|
||||
*/))
|
||||
.anyMatch(taskId -> task.taskId == taskId
|
||||
&& task.configuration.windowConfiguration.getActivityType() != ACTIVITY_TYPE_HOME);
|
||||
if (taskRunningAndNotHome) {
|
||||
// Since this is an edge case, just cancel and relaunch with default activity
|
||||
// options (since we don't know if there's an associated app icon to launch
|
||||
// from)
|
||||
endRunningWindowAnim(true /* cancel */);
|
||||
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mActivityRestartListener);
|
||||
ActivityManagerWrapper.getInstance().startActivityFromRecents(task.taskId, null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@UiThread
|
||||
private void animateToProgressInternal(float start, float end, long duration,
|
||||
@@ -1544,11 +1554,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
|
||||
if (mGestureState.getEndTarget() == HOME) {
|
||||
getOrientationHandler().adjustFloatingIconStartVelocity(velocityPxPerMs);
|
||||
// Take first task ID, if there are multiple we don't have any special home
|
||||
// animation so doesn't matter for splitscreen.. though the "allowEnterPip" might change
|
||||
// animation so doesn't matter for splitscreen.. though the "allowEnterPip"
|
||||
// might change
|
||||
// depending on which task it is..
|
||||
final RemoteAnimationTarget runningTaskTarget = mRecentsAnimationTargets != null
|
||||
? mRecentsAnimationTargets
|
||||
.findTask(mGestureState.getTopRunningTaskId())
|
||||
.findTask(mGestureState.getTopRunningTaskId())
|
||||
: null;
|
||||
final ArrayList<IBinder> cookies = Utilities.ATLEAST_S && runningTaskTarget != null
|
||||
&& runningTaskTarget.taskInfo != null
|
||||
@@ -1577,7 +1588,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
|
||||
mSwipePipToHomeReleaseCheck.setCanRelease(false);
|
||||
}
|
||||
|
||||
// grab a screenshot before the PipContentOverlay gets parented on top of the task
|
||||
// grab a screenshot before the PipContentOverlay gets parented on top of the
|
||||
// task
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
// Directly use top task, split to pip handled on shell side
|
||||
final int taskId = mGestureState.getTopRunningTaskId();
|
||||
@@ -1603,7 +1615,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
|
||||
|
||||
windowAnim[0].addAnimatorListener(new AnimationSuccessListener() {
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
if (mRecentsAnimationController == null) {
|
||||
// If the recents animation is interrupted, we still end the running
|
||||
@@ -2435,7 +2447,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
|
||||
transaction.forSurface(target.leash).setAlpha(1).setLayer(-1).setShow();
|
||||
}
|
||||
surfaceApplier.scheduleApply(transaction);
|
||||
if (!LawnchairQuickstepCompat.ATLEAST_S) return;
|
||||
if (!LawnchairQuickstepCompat.ATLEAST_S)
|
||||
return;
|
||||
SplashScreenExitAnimationUtils.startAnimations(splashView, taskTarget.leash,
|
||||
mSplashMainWindowShiftLength, new TransactionPool(), new Rect(),
|
||||
SPLASH_ANIMATION_DURATION, SPLASH_FADE_OUT_DURATION,
|
||||
@@ -2521,6 +2534,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
|
||||
startInterceptingTouchesForGesture();
|
||||
}
|
||||
for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
|
||||
float scrollScale = setRecentsScroll ? mRecentsView.getScrollScale(remoteHandle) : 1f;
|
||||
AnimatorControllerWithResistance playbackController = remoteHandle.getPlaybackController();
|
||||
if (playbackController != null) {
|
||||
playbackController.setProgress(progress, mDragLengthFactor);
|
||||
@@ -2528,6 +2542,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
|
||||
|
||||
if (notSwipingToHome) {
|
||||
TaskViewSimulator taskViewSimulator = remoteHandle.getTaskViewSimulator();
|
||||
taskViewSimulator.scrollScale.value = scrollScale;
|
||||
if (setRecentsScroll) {
|
||||
taskViewSimulator.setScroll(scrollOffset);
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
private final FullscreenDrawParams mCurrentFullscreenParams;
|
||||
public final AnimatedFloat taskPrimaryTranslation = new AnimatedFloat();
|
||||
public final AnimatedFloat taskSecondaryTranslation = new AnimatedFloat();
|
||||
public final AnimatedFloat scrollScale = new AnimatedFloat();
|
||||
|
||||
// RecentsView properties
|
||||
public final AnimatedFloat recentsViewScale = new AnimatedFloat();
|
||||
@@ -119,6 +120,9 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
mOrientationStateId = mOrientationState.getStateId();
|
||||
Resources resources = context.getResources();
|
||||
mIsRecentsRtl = mOrientationState.getOrientationHandler().getRecentsRtlSetting(resources);
|
||||
//nick@lmo-20231004 this does belong here to avoid flicker in animation due to race of setting
|
||||
// value to 1. other code assumes it starts with 1 anyway, so let's just do it here
|
||||
this.scrollScale.value = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -344,6 +348,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
}
|
||||
|
||||
float fullScreenProgress = Utilities.boundToRange(this.fullScreenProgress.value, 0, 1);
|
||||
float scrollScale = this.scrollScale.value * (1f - fullScreenProgress) + fullScreenProgress;
|
||||
mCurrentFullscreenParams.setProgress(fullScreenProgress, recentsViewScale.value,
|
||||
/* taskViewScale= */1f, mTaskRect.width(), mDp, mPositionHelper);
|
||||
|
||||
@@ -355,6 +360,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
|
||||
// Apply TaskView matrix: taskRect, translate
|
||||
mMatrix.postTranslate(mTaskRect.left, mTaskRect.top);
|
||||
mMatrix.postScale(scrollScale, scrollScale, mTaskRect.left + (mTaskRect.width() / 2),
|
||||
mTaskRect.top + (mTaskRect.height() / 2));
|
||||
mOrientationState.getOrientationHandler().setPrimary(mMatrix, MATRIX_POST_TRANSLATE,
|
||||
taskPrimaryTranslation.value);
|
||||
mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
|
||||
@@ -392,6 +399,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
+ " recentsSecondaryT: " + recentsViewSecondaryTranslation.value
|
||||
+ " taskSecondaryT: " + taskSecondaryTranslation.value
|
||||
+ " recentsScroll: " + recentsViewScroll.value
|
||||
+ " scrollScale: " + scrollScale
|
||||
+ " this.scrollScale.value: " + this.scrollScale.value
|
||||
+ " pivot: " + mPivot
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3710,16 +3710,42 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
}
|
||||
|
||||
int scrollDiff = newScroll[i] - oldScroll[i] + offset;
|
||||
if (i == dismissedIndex + 1 ||
|
||||
dismissedIndex == taskCount -1 && i == dismissedIndex - 1) {
|
||||
if (child.getScaleX() <= dismissedTaskView.getScaleX())
|
||||
if (child.getScaleX() <= dismissedTaskView.getScaleX()) {
|
||||
anim.setFloat(child, SCALE_PROPERTY,
|
||||
dismissedTaskView.getScaleX(), LINEAR);
|
||||
else
|
||||
if (child instanceof TaskView && mRemoteTargetHandles != null) {
|
||||
TaskView tv = (TaskView) child;
|
||||
for (RemoteTargetHandle rth : mRemoteTargetHandles) {
|
||||
TransformParams params = rth.getTransformParams();
|
||||
RemoteAnimationTargets targets = params.getTargetSet();
|
||||
boolean match = false;
|
||||
for (int id : tv.getTaskIds()) {
|
||||
if (targets != null && targets.findTask(id) != null) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
anim.addOnFrameCallback(() -> {
|
||||
rth.getTaskViewSimulator().scrollScale.value =
|
||||
mOrientationHandler.getPrimaryValue(
|
||||
tv.getScaleX(),
|
||||
tv.getScaleY()
|
||||
);
|
||||
// if scrollDiff != 0, we redraw in later(AOSP) code
|
||||
if (mEnableDrawingLiveTile && scrollDiff == 0) {
|
||||
redrawLiveTile();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
anim.setFloat(child, SCALE_PROPERTY, 1f, LINEAR);
|
||||
}
|
||||
|
||||
int scrollDiff = newScroll[i] - oldScroll[i] + offset;
|
||||
if (scrollDiff != 0) {
|
||||
FloatProperty translationProperty = child instanceof TaskView
|
||||
? ((TaskView) child).getPrimaryDismissTranslationProperty()
|
||||
@@ -6174,10 +6200,16 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (showAsGrid())
|
||||
return;
|
||||
|
||||
boolean isInLandscape = mOrientationState.getTouchRotation() != ROTATION_0
|
||||
//nick@lmo-20231004 if rotating launcher is enabled, rotation works differently
|
||||
// There are many edge cases (going from landscape app to recents, rotating in recents etc)
|
||||
boolean touchInLandscape = mOrientationState.getTouchRotation() != ROTATION_0
|
||||
&& mOrientationState.getTouchRotation() != ROTATION_180;
|
||||
boolean layoutInLandscape = mOrientationState.getRecentsActivityRotation() != ROTATION_0
|
||||
&& mOrientationState.getRecentsActivityRotation() != ROTATION_180;
|
||||
boolean canRotateRecents = mOrientationState.isRecentsActivityRotationAllowed();
|
||||
int childCount = Math.min(mPageScrolls.length, getChildCount());
|
||||
int curScroll = isInLandscape ? getScrollY() : getScrollX();
|
||||
int curScroll = !canRotateRecents && touchInLandscape && !layoutInLandscape
|
||||
? getScrollY() : getScrollX();
|
||||
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = getChildAt(i);
|
||||
@@ -6192,9 +6224,44 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
child.setScaleX(scale);
|
||||
child.setScaleY(scale);
|
||||
}
|
||||
if (!(child instanceof TaskView && mRemoteTargetHandles != null)) continue;
|
||||
TaskView tv = (TaskView) child;
|
||||
for (RemoteTargetHandle rth : mRemoteTargetHandles) {
|
||||
TransformParams params = rth.getTransformParams();
|
||||
RemoteAnimationTargets targets = params.getTargetSet();
|
||||
for (int id : tv.getTaskIds()) {
|
||||
if (targets != null && targets.findTask(id) != null) {
|
||||
rth.getTaskViewSimulator().scrollScale.value =
|
||||
mOrientationHandler.getPrimaryValue(
|
||||
tv.getScaleX(),
|
||||
tv.getScaleY()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float getScrollScale(RemoteTargetHandle rth) {
|
||||
int childCount = Math.min(mPageScrolls.length, getChildCount());
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = getChildAt(i);
|
||||
if (!(child instanceof TaskView && !showAsGrid())) continue;
|
||||
TaskView tv = (TaskView) child;
|
||||
TransformParams params = rth.getTransformParams();
|
||||
RemoteAnimationTargets targets = params.getTargetSet();
|
||||
for (int id : tv.getTaskIds()) {
|
||||
if (targets != null && targets.findTask(id) != null) {
|
||||
return mOrientationHandler.getPrimaryValue(
|
||||
tv.getScaleX(),
|
||||
tv.getScaleY()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1f;
|
||||
}
|
||||
|
||||
private void dispatchScrollChanged() {
|
||||
runActionOnRemoteHandles(
|
||||
remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator().setScroll(getScrollOffset()));
|
||||
|
||||
Reference in New Issue
Block a user