am eea0aa25
: Support primitive ALT-TAB style navigation using Recent Apps. (DO NOT MERGE)
* commit 'eea0aa25870d49e381567f09abbfb41de52a5a32': Support primitive ALT-TAB style navigation using Recent Apps. (DO NOT MERGE)
This commit is contained in:
@ -287,8 +287,8 @@ key 9 {
|
|||||||
key SPACE {
|
key SPACE {
|
||||||
label: ' '
|
label: ' '
|
||||||
base: ' '
|
base: ' '
|
||||||
ctrl, alt: none
|
ctrl: none
|
||||||
meta: fallback SEARCH
|
alt, meta: fallback SEARCH
|
||||||
}
|
}
|
||||||
|
|
||||||
key ENTER {
|
key ENTER {
|
||||||
@ -300,8 +300,8 @@ key ENTER {
|
|||||||
key TAB {
|
key TAB {
|
||||||
label: '\t'
|
label: '\t'
|
||||||
base: '\t'
|
base: '\t'
|
||||||
ctrl, alt: none
|
ctrl: none
|
||||||
meta: fallback APP_SWITCH
|
alt, meta: fallback APP_SWITCH
|
||||||
}
|
}
|
||||||
|
|
||||||
key COMMA {
|
key COMMA {
|
||||||
@ -542,8 +542,8 @@ key PLUS {
|
|||||||
|
|
||||||
key ESCAPE {
|
key ESCAPE {
|
||||||
base: fallback BACK
|
base: fallback BACK
|
||||||
meta: fallback HOME
|
alt, meta: fallback HOME
|
||||||
alt: fallback MENU
|
ctrl: fallback MENU
|
||||||
}
|
}
|
||||||
|
|
||||||
### Gamepad buttons ###
|
### Gamepad buttons ###
|
||||||
|
@ -623,7 +623,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
|
if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
|
||||||
showRecentAppsDialog();
|
showRecentAppsDialog(0);
|
||||||
} else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_ACTIVITY) {
|
} else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_ACTIVITY) {
|
||||||
try {
|
try {
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
@ -642,12 +642,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
/**
|
/**
|
||||||
* Create (if necessary) and launch the recent apps dialog
|
* Create (if necessary) and launch the recent apps dialog
|
||||||
*/
|
*/
|
||||||
void showRecentAppsDialog() {
|
void showRecentAppsDialog(final int initialModifiers) {
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mRecentAppsDialog == null) {
|
if (mRecentAppsDialog == null) {
|
||||||
mRecentAppsDialog = new RecentApplicationsDialog(mContext);
|
mRecentAppsDialog = new RecentApplicationsDialog(mContext, initialModifiers);
|
||||||
}
|
}
|
||||||
mRecentAppsDialog.show();
|
mRecentAppsDialog.show();
|
||||||
}
|
}
|
||||||
@ -1433,7 +1433,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
return false;
|
return false;
|
||||||
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
|
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
|
||||||
if (down && repeatCount == 0) {
|
if (down && repeatCount == 0) {
|
||||||
showRecentAppsDialog();
|
showRecentAppsDialog(event.getMetaState() & KeyEvent.getModifierMetaStateMask());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,13 @@
|
|||||||
package com.android.internal.policy.impl;
|
package com.android.internal.policy.impl;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityManagerNative;
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.IActivityManager;
|
|
||||||
import android.app.StatusBarManager;
|
import android.app.StatusBarManager;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
@ -34,6 +31,8 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.SoundEffectConstants;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
@ -72,13 +71,12 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private int mIconSize;
|
private int mInitialModifiers;
|
||||||
|
|
||||||
public RecentApplicationsDialog(Context context) {
|
public RecentApplicationsDialog(Context context, int initialModifiers) {
|
||||||
super(context, com.android.internal.R.style.Theme_Dialog_RecentApplications);
|
super(context, com.android.internal.R.style.Theme_Dialog_RecentApplications);
|
||||||
|
|
||||||
final Resources resources = context.getResources();
|
mInitialModifiers = initialModifiers;
|
||||||
mIconSize = (int) resources.getDimension(android.R.dimen.app_icon_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,14 +125,86 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_APP_SWITCH || keyCode == KeyEvent.KEYCODE_TAB) {
|
||||||
|
// Ignore all meta keys other than SHIFT. The app switch key could be a
|
||||||
|
// fallback action chorded with ALT, META or even CTRL depending on the key map.
|
||||||
|
// DPad navigation is handled by the ViewRoot elsewhere.
|
||||||
|
final boolean backward = event.isShiftPressed();
|
||||||
|
final int numIcons = mIcons.length;
|
||||||
|
int numButtons = 0;
|
||||||
|
while (numButtons < numIcons && mIcons[numButtons].getVisibility() == View.VISIBLE) {
|
||||||
|
numButtons += 1;
|
||||||
|
}
|
||||||
|
if (numButtons != 0) {
|
||||||
|
int nextFocus = backward ? numButtons - 1 : 0;
|
||||||
|
for (int i = 0; i < numButtons; i++) {
|
||||||
|
if (mIcons[i].hasFocus()) {
|
||||||
|
if (backward) {
|
||||||
|
nextFocus = (i + numButtons - 1) % numButtons;
|
||||||
|
} else {
|
||||||
|
nextFocus = (i + 1) % numButtons;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final int direction = backward ? View.FOCUS_BACKWARD : View.FOCUS_FORWARD;
|
||||||
|
if (mIcons[nextFocus].requestFocus(direction)) {
|
||||||
|
mIcons[nextFocus].playSoundEffect(
|
||||||
|
SoundEffectConstants.getContantForFocusDirection(direction));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The dialog always handles the key to prevent the ViewRoot from
|
||||||
|
// performing the default navigation itself.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onKeyDown(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||||
|
if (mInitialModifiers != 0 && event.hasNoModifiers()) {
|
||||||
|
final int numIcons = mIcons.length;
|
||||||
|
RecentTag tag = null;
|
||||||
|
for (int i = 0; i < numIcons; i++) {
|
||||||
|
if (mIcons[i].getVisibility() != View.VISIBLE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == 0 || mIcons[i].hasFocus()) {
|
||||||
|
tag = (RecentTag) mIcons[i].getTag();
|
||||||
|
if (mIcons[i].hasFocus()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tag != null) {
|
||||||
|
switchTo(tag);
|
||||||
|
}
|
||||||
|
dismiss();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onKeyUp(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for user clicks. If a button was clicked, launch the corresponding activity.
|
* Handler for user clicks. If a button was clicked, launch the corresponding activity.
|
||||||
*/
|
*/
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
|
||||||
for (TextView b: mIcons) {
|
for (TextView b: mIcons) {
|
||||||
if (b == v) {
|
if (b == v) {
|
||||||
RecentTag tag = (RecentTag)b.getTag();
|
RecentTag tag = (RecentTag)b.getTag();
|
||||||
|
switchTo(tag);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchTo(RecentTag tag) {
|
||||||
if (tag.info.id >= 0) {
|
if (tag.info.id >= 0) {
|
||||||
// This is an active task; it should just go to the foreground.
|
// This is an active task; it should just go to the foreground.
|
||||||
final ActivityManager am = (ActivityManager)
|
final ActivityManager am = (ActivityManager)
|
||||||
@ -149,10 +219,6 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
|
|||||||
Log.w("Recent", "Unable to launch recent task", e);
|
Log.w("Recent", "Unable to launch recent task", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dismiss();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user