Fixing some bugs in Recents keyboard behaviour.
- Ensuring that we don't allow meta-tab to trigger Recents (since meta is a system key now) - Adding dpad keys support to traverse stack - Adding workaround for cases where tasks wouldn't be focused depending on how you launch Recents Change-Id: I4101ced7e47e0d1659d5fa236214be5697c00560
This commit is contained in:
@ -147,7 +147,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
|
||||
}
|
||||
} else if (action.equals(RecentsService.ACTION_START_ENTER_ANIMATION)) {
|
||||
// Try and start the enter animation (or restart it on configuration changed)
|
||||
mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(mFullScreenOverlayView));
|
||||
ReferenceCountedTrigger t = new ReferenceCountedTrigger(context, null, null, null);
|
||||
mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(
|
||||
mFullScreenOverlayView, t));
|
||||
// Call our callback
|
||||
onEnterAnimationTriggered();
|
||||
}
|
||||
@ -392,7 +394,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
|
||||
|
||||
void onConfigurationChange() {
|
||||
// Try and start the enter animation (or restart it on configuration changed)
|
||||
mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(mFullScreenOverlayView));
|
||||
ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null);
|
||||
mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(
|
||||
mFullScreenOverlayView, t));
|
||||
// Call our callback
|
||||
onEnterAnimationTriggered();
|
||||
}
|
||||
@ -536,6 +540,12 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
|
||||
final boolean backward = event.isShiftPressed();
|
||||
mRecentsView.focusNextTask(!backward);
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
|
||||
mRecentsView.focusNextTask(true);
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
|
||||
mRecentsView.focusNextTask(false);
|
||||
return true;
|
||||
}
|
||||
// Pass through the debug trigger
|
||||
mDebugTrigger.onKeyEvent(keyCode);
|
||||
|
@ -186,6 +186,10 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
|
||||
|
||||
/** Requests all task stacks to start their enter-recents animation */
|
||||
public void startEnterRecentsAnimation(ViewAnimation.TaskViewEnterContext ctx) {
|
||||
// Handle the case when there are no views by incrementing and decrementing after all
|
||||
// animations are started.
|
||||
ctx.postAnimationTrigger.increment();
|
||||
|
||||
int childCount = getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = getChildAt(i);
|
||||
@ -194,6 +198,10 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
|
||||
stackView.startEnterRecentsAnimation(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the case when there are no views by incrementing and decrementing after all
|
||||
// animations are started.
|
||||
ctx.postAnimationTrigger.decrement();
|
||||
}
|
||||
|
||||
/** Requests all task stacks to start their exit-recents animation */
|
||||
|
@ -747,9 +747,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
// Mark that we have completely the first layout
|
||||
mAwaitingFirstLayout = false;
|
||||
|
||||
// Start dozing
|
||||
mUIDozeTrigger.startDozing();
|
||||
|
||||
// Prepare the first view for its enter animation
|
||||
int offsetTopAlign = -mStackAlgorithm.mTaskRect.top;
|
||||
int offscreenY = mStackAlgorithm.mRect.bottom -
|
||||
@ -770,7 +767,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
|
||||
// Update the focused task index to be the next item to the top task
|
||||
if (mConfig.launchedWithAltTab) {
|
||||
// When alt-tabbing, we focus the next previous task
|
||||
focusTask(Math.max(0, mStack.getTaskCount() - 2), false);
|
||||
} else {
|
||||
// Normally we just focus the front task
|
||||
focusTask(Math.max(0, mStack.getTaskCount() - 1), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -799,6 +800,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
mStack.indexOfTask(tv.getTask()), getStackScroll());
|
||||
tv.startEnterRecentsAnimation(ctx);
|
||||
}
|
||||
|
||||
// Add a runnable to the post animation ref counter to clear all the views
|
||||
ctx.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Start dozing
|
||||
mUIDozeTrigger.startDozing();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Requests this task stacks to start it's exit-recents animation. */
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.systemui.recents.views;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
@ -296,7 +298,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
}
|
||||
|
||||
/** Animates this task view as it enters recents */
|
||||
public void startEnterRecentsAnimation(ViewAnimation.TaskViewEnterContext ctx) {
|
||||
public void startEnterRecentsAnimation(final ViewAnimation.TaskViewEnterContext ctx) {
|
||||
TaskViewTransform transform = ctx.transform;
|
||||
|
||||
if (mConfig.launchedFromAppWithScreenshot) {
|
||||
@ -308,6 +310,8 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
// Animate the task bar of the first task view
|
||||
mBarView.startEnterRecentsAnimation(0, mEnableThumbnailClip);
|
||||
setVisibility(View.VISIBLE);
|
||||
// Decrement the post animation trigger
|
||||
ctx.postAnimationTrigger.decrement();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -321,9 +325,17 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
.setInterpolator(mConfig.linearOutSlowInInterpolator)
|
||||
.setDuration(475)
|
||||
.withLayer()
|
||||
.withEndAction(mEnableThumbnailClip)
|
||||
.withEndAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mEnableThumbnailClip.run();
|
||||
// Decrement the post animation trigger
|
||||
ctx.postAnimationTrigger.decrement();
|
||||
}
|
||||
})
|
||||
.start();
|
||||
}
|
||||
ctx.postAnimationTrigger.increment();
|
||||
|
||||
} else if (mConfig.launchedFromAppWithThumbnail) {
|
||||
if (ctx.isFrontMost) {
|
||||
@ -335,7 +347,15 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
anim.setStartDelay(mConfig.taskBarEnterAnimDelay);
|
||||
anim.setDuration(mConfig.taskBarEnterAnimDuration);
|
||||
anim.setInterpolator(mConfig.fastOutLinearInInterpolator);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
// Decrement the post animation trigger
|
||||
ctx.postAnimationTrigger.decrement();
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
ctx.postAnimationTrigger.increment();
|
||||
} else {
|
||||
mEnableThumbnailClip.run();
|
||||
}
|
||||
@ -355,8 +375,16 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
.setInterpolator(mConfig.quintOutInterpolator)
|
||||
.setDuration(mConfig.taskViewEnterFromHomeDuration)
|
||||
.withLayer()
|
||||
.withEndAction(mEnableThumbnailClip)
|
||||
.withEndAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mEnableThumbnailClip.run();
|
||||
// Decrement the post animation trigger
|
||||
ctx.postAnimationTrigger.decrement();
|
||||
}
|
||||
})
|
||||
.start();
|
||||
ctx.postAnimationTrigger.increment();
|
||||
}
|
||||
}
|
||||
|
||||
@ -518,7 +546,12 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
*/
|
||||
public void setFocusedTask() {
|
||||
mIsFocused = true;
|
||||
// Workaround, we don't always want it focusable in touch mode, but we want the first task
|
||||
// to be focused after the enter-recents animation, which can be triggered from either touch
|
||||
// or keyboard
|
||||
setFocusableInTouchMode(true);
|
||||
requestFocus();
|
||||
setFocusableInTouchMode(false);
|
||||
invalidate();
|
||||
mCb.onTaskFocused(this);
|
||||
}
|
||||
|
@ -38,9 +38,13 @@ public class ViewAnimation {
|
||||
int stackViewCount;
|
||||
// Whether this is the front most task view
|
||||
boolean isFrontMost;
|
||||
// A trigger to run some logic when all the animations complete. This works around the fact
|
||||
// that it is difficult to coordinate ViewPropertyAnimators
|
||||
ReferenceCountedTrigger postAnimationTrigger;
|
||||
|
||||
public TaskViewEnterContext(FullscreenTransitionOverlayView fss) {
|
||||
public TaskViewEnterContext(FullscreenTransitionOverlayView fss, ReferenceCountedTrigger t) {
|
||||
fullScreenshot = fss;
|
||||
postAnimationTrigger = t;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2380,9 +2380,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) {
|
||||
if (mRecentAppsHeldModifiers == 0 && !keyguardOn) {
|
||||
final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
|
||||
if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)
|
||||
|| KeyEvent.metaStateHasModifiers(
|
||||
shiftlessModifiers, KeyEvent.META_META_ON)) {
|
||||
if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)) {
|
||||
mRecentAppsHeldModifiers = shiftlessModifiers;
|
||||
showRecentApps(true);
|
||||
return -1;
|
||||
|
Reference in New Issue
Block a user