From 5487500cf3d9f6d7703ce0704cb91837aa95d716 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Wed, 6 Apr 2011 15:33:01 -0700 Subject: Minor Alt-TAB / Recent Apps Dialog improvements. Alt-TAB should have different semantics from the APP_SWITCH key or long-press on HOME. Accordingly, remove the fallback action for Alt-TAB and initiate the task switching behavior directly in the policy. Modified RecentApplicationsDialog to be more precise about the initial modifiers that it considers to be holding the dialog. The dialog is now dismissed by a second press on the APP_SWITCH key or by a second long press on HOME. Change-Id: Idf4d803f51103819057cb655ff3b770b7729e4be --- .../internal/policy/impl/PhoneWindowManager.java | 67 +++++++++++++++------- .../policy/impl/RecentApplicationsDialog.java | 20 +++++-- 2 files changed, 61 insertions(+), 26 deletions(-) (limited to 'policy/src') diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 44f55b3..ac38d0b 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -626,7 +626,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) { - showRecentAppsDialog(0); + showOrHideRecentAppsDialog(0, true /*dismissIfShown*/); } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_ACTIVITY) { try { Intent intent = new Intent(); @@ -643,16 +643,24 @@ public class PhoneWindowManager implements WindowManagerPolicy { } /** - * Create (if necessary) and launch the recent apps dialog + * Create (if necessary) and launch the recent apps dialog, or hide it if it is + * already shown. */ - void showRecentAppsDialog(final int initialModifiers) { + void showOrHideRecentAppsDialog(final int heldModifiers, final boolean dismissIfShown) { mHandler.post(new Runnable() { @Override public void run() { if (mRecentAppsDialog == null) { - mRecentAppsDialog = new RecentApplicationsDialog(mContext, initialModifiers); + mRecentAppsDialog = new RecentApplicationsDialog(mContext); + } + if (mRecentAppsDialog.isShowing()) { + if (dismissIfShown) { + mRecentAppsDialog.dismiss(); + } + } else { + mRecentAppsDialog.setHeldModifiers(heldModifiers); + mRecentAppsDialog.show(); } - mRecentAppsDialog.show(); } }); } @@ -1392,7 +1400,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { return false; } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) { if (down && repeatCount == 0) { - showRecentAppsDialog(event.getMetaState() & KeyEvent.getModifierMetaStateMask()); + showOrHideRecentAppsDialog(0, true /*dismissIfShown*/); } return true; } @@ -1434,6 +1442,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ @Override public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) { + // Note: This method is only called if the initial down was unhandled. if (DEBUG_FALLBACK) { Slog.d(TAG, "Unhandled key: win=" + win + ", action=" + event.getAction() + ", flags=" + event.getFlags() @@ -1445,28 +1454,44 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { - // Invoke shortcuts using Meta as a fallback. final KeyCharacterMap kcm = event.getKeyCharacterMap(); final int keyCode = event.getKeyCode(); final int metaState = event.getMetaState(); - if ((metaState & KeyEvent.META_META_ON) != 0) { - Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, - metaState & ~(KeyEvent.META_META_ON - | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON)); - if (shortcutIntent != null) { - shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - mContext.startActivity(shortcutIntent); - } catch (ActivityNotFoundException ex) { - Slog.w(TAG, "Dropping shortcut key combination because " - + "the activity to which it is registered was not found: " - + "META+" + KeyEvent.keyCodeToString(keyCode), ex); + final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN + && event.getRepeatCount() == 0; + + if (initialDown) { + // Invoke shortcuts using Meta as a fallback. + if ((metaState & KeyEvent.META_META_ON) != 0) { + Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, + metaState & ~(KeyEvent.META_META_ON + | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON)); + if (shortcutIntent != null) { + shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + mContext.startActivity(shortcutIntent); + } catch (ActivityNotFoundException ex) { + Slog.w(TAG, "Dropping shortcut key combination because " + + "the activity to which it is registered was not found: " + + "META+" + KeyEvent.keyCodeToString(keyCode), ex); + } + return null; + } + } + + // Display task switcher for ALT-TAB or Meta-TAB. + if (keyCode == KeyEvent.KEYCODE_TAB) { + final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK; + if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON) + || KeyEvent.metaStateHasModifiers( + shiftlessModifiers, KeyEvent.META_META_ON)) { + showOrHideRecentAppsDialog(shiftlessModifiers, false /*dismissIfShown*/); + return null; } - return null; } } - // Check for fallback actions. + // Check for fallback actions specified by the key character map. if (getFallbackAction(kcm, keyCode, metaState, mFallbackAction)) { if (DEBUG_FALLBACK) { Slog.d(TAG, "Fallback: keyCode=" + mFallbackAction.keyCode diff --git a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java index c4b7822..aa00fbd 100644 --- a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java +++ b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java @@ -71,12 +71,11 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener } }; - private int mInitialModifiers; + private int mHeldModifiers; - public RecentApplicationsDialog(Context context, int initialModifiers) { + public RecentApplicationsDialog(Context context) { super(context, com.android.internal.R.style.Theme_Dialog_RecentApplications); - mInitialModifiers = initialModifiers; } /** @@ -125,9 +124,20 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener } } + /** + * Sets the modifier keys that are being held to keep the dialog open, or 0 if none. + * Used to make the recent apps dialog automatically dismiss itself when the modifiers + * all go up. + * @param heldModifiers The held key modifiers, such as {@link KeyEvent#META_ALT_ON}. + * Should exclude shift. + */ + public void setHeldModifiers(int heldModifiers) { + mHeldModifiers = heldModifiers; + } + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_APP_SWITCH || keyCode == KeyEvent.KEYCODE_TAB) { + if (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. @@ -166,7 +176,7 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener @Override public boolean onKeyUp(int keyCode, KeyEvent event) { - if (mInitialModifiers != 0 && event.hasNoModifiers()) { + if (mHeldModifiers != 0 && (event.getModifiers() & mHeldModifiers) == 0) { final int numIcons = mIcons.length; RecentTag tag = null; for (int i = 0; i < numIcons; i++) { -- cgit v1.1