Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eea0aa25 authored by Jeff Brown's avatar Jeff Brown Committed by Jeff Brown
Browse files

Support primitive ALT-TAB style navigation using Recent Apps. (DO NOT MERGE)

Change-Id: I0296a09519ba9417c208d197ebd996b586ee3daa
parent 36001a9f
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -287,8 +287,8 @@ key 9 {
key SPACE {
    label:                              ' '
    base:                               ' '
    ctrl, alt:                          none
    meta:                               fallback SEARCH
    ctrl:                               none
    alt, meta:                          fallback SEARCH
}

key ENTER {
@@ -300,8 +300,8 @@ key ENTER {
key TAB {
    label:                              '\t'
    base:                               '\t'
    ctrl, alt:                          none
    meta:                               fallback APP_SWITCH
    ctrl:                               none
    alt, meta:                          fallback APP_SWITCH
}

key COMMA {
@@ -542,8 +542,8 @@ key PLUS {

key ESCAPE {
    base:                               fallback BACK
    meta:                               fallback HOME
    alt:                                fallback MENU
    alt, meta:                          fallback HOME
    ctrl:                               fallback MENU
}

### Gamepad buttons ###
+4 −4
Original line number Diff line number Diff line
@@ -623,7 +623,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }

        if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
            showRecentAppsDialog();
            showRecentAppsDialog(0);
        } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_ACTIVITY) {
            try {
                Intent intent = new Intent();
@@ -642,12 +642,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    /**
     * Create (if necessary) and launch the recent apps dialog
     */
    void showRecentAppsDialog() {
    void showRecentAppsDialog(final int initialModifiers) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mRecentAppsDialog == null) {
                    mRecentAppsDialog = new RecentApplicationsDialog(mContext);
                    mRecentAppsDialog = new RecentApplicationsDialog(mContext, initialModifiers);
                }
                mRecentAppsDialog.show();
            }
@@ -1433,7 +1433,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            return false;
        } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
            if (down && repeatCount == 0) {
                showRecentAppsDialog();
                showRecentAppsDialog(event.getMetaState() & KeyEvent.getModifierMetaStateMask());
            }
            return true;
        }
+88 −22
Original line number Diff line number Diff line
@@ -17,16 +17,13 @@
package com.android.internal.policy.impl;

import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.Dialog;
import android.app.IActivityManager;
import android.app.StatusBarManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -34,6 +31,8 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.Window;
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);

        final Resources resources = context.getResources();
        mIconSize = (int) resources.getDimension(android.R.dimen.app_icon_size);
        mInitialModifiers = initialModifiers;
    }

    /**
@@ -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.
     */
    public void onClick(View v) {

        for (TextView b: mIcons) {
            if (b == v) {
                RecentTag tag = (RecentTag)b.getTag();
                switchTo(tag);
                break;
            }
        }
        dismiss();
    }

    private void switchTo(RecentTag tag) {
        if (tag.info.id >= 0) {
            // This is an active task; it should just go to the foreground.
            final ActivityManager am = (ActivityManager)
@@ -149,10 +219,6 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
                Log.w("Recent", "Unable to launch recent task", e);
            }
        }
                break;
            }
        }
        dismiss();
    }

    /**