diff --git a/api/current.txt b/api/current.txt index e2720f27f2636..96b96dbdaecde 100644 --- a/api/current.txt +++ b/api/current.txt @@ -269,6 +269,7 @@ package android { field public static final int allowTaskReparenting = 16843268; // 0x1010204 field public static final int allowUndo = 16843999; // 0x10104df field public static final int alpha = 16843551; // 0x101031f + field public static final int alphabeticModifiers = 16844112; // 0x1010550 field public static final int alphabeticShortcut = 16843235; // 0x10101e3 field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef field public static final int alwaysRetainTaskState = 16843267; // 0x1010203 @@ -923,6 +924,7 @@ package android { field public static final int numbersSelectorColor = 16843939; // 0x10104a3 field public static final int numbersTextColor = 16843937; // 0x10104a1 field public static final deprecated int numeric = 16843109; // 0x1010165 + field public static final int numericModifiers = 16844113; // 0x1010551 field public static final int numericShortcut = 16843236; // 0x10101e4 field public static final int offset = 16844052; // 0x1010514 field public static final int onClick = 16843375; // 0x101026f @@ -43821,6 +43823,7 @@ package android.view { field public static final int FLAG_APPEND_TO_GROUP = 1; // 0x1 field public static final int FLAG_PERFORM_NO_CLOSE = 1; // 0x1 field public static final int NONE = 0; // 0x0 + field public static final int SUPPORTED_MODIFIERS_MASK = 69647; // 0x1100f } public class MenuInflater { @@ -43833,6 +43836,7 @@ package android.view { method public abstract boolean expandActionView(); method public abstract android.view.ActionProvider getActionProvider(); method public abstract android.view.View getActionView(); + method public default int getAlphabeticModifiers(); method public abstract char getAlphabeticShortcut(); method public default java.lang.CharSequence getContentDescription(); method public abstract int getGroupId(); @@ -43840,6 +43844,7 @@ package android.view { method public abstract android.content.Intent getIntent(); method public abstract int getItemId(); method public abstract android.view.ContextMenu.ContextMenuInfo getMenuInfo(); + method public default int getNumericModifiers(); method public abstract char getNumericShortcut(); method public abstract int getOrder(); method public abstract android.view.SubMenu getSubMenu(); @@ -43856,6 +43861,7 @@ package android.view { method public abstract android.view.MenuItem setActionView(android.view.View); method public abstract android.view.MenuItem setActionView(int); method public abstract android.view.MenuItem setAlphabeticShortcut(char); + method public default android.view.MenuItem setAlphabeticShortcut(char, int); method public abstract android.view.MenuItem setCheckable(boolean); method public abstract android.view.MenuItem setChecked(boolean); method public default android.view.MenuItem setContentDescription(java.lang.CharSequence); @@ -43864,9 +43870,11 @@ package android.view { method public abstract android.view.MenuItem setIcon(int); method public abstract android.view.MenuItem setIntent(android.content.Intent); method public abstract android.view.MenuItem setNumericShortcut(char); + method public default android.view.MenuItem setNumericShortcut(char, int); method public abstract android.view.MenuItem setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener); method public abstract android.view.MenuItem setOnMenuItemClickListener(android.view.MenuItem.OnMenuItemClickListener); method public abstract android.view.MenuItem setShortcut(char, char); + method public default android.view.MenuItem setShortcut(char, char, int, int); method public abstract void setShowAsAction(int); method public abstract android.view.MenuItem setShowAsActionFlags(int); method public abstract android.view.MenuItem setTitle(java.lang.CharSequence); diff --git a/api/system-current.txt b/api/system-current.txt index 14120aff98f49..3a58bf4c8d7a8 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -381,6 +381,7 @@ package android { field public static final int allowTaskReparenting = 16843268; // 0x1010204 field public static final int allowUndo = 16843999; // 0x10104df field public static final int alpha = 16843551; // 0x101031f + field public static final int alphabeticModifiers = 16844112; // 0x1010550 field public static final int alphabeticShortcut = 16843235; // 0x10101e3 field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef field public static final int alwaysRetainTaskState = 16843267; // 0x1010203 @@ -1035,6 +1036,7 @@ package android { field public static final int numbersSelectorColor = 16843939; // 0x10104a3 field public static final int numbersTextColor = 16843937; // 0x10104a1 field public static final deprecated int numeric = 16843109; // 0x1010165 + field public static final int numericModifiers = 16844113; // 0x1010551 field public static final int numericShortcut = 16843236; // 0x10101e4 field public static final int offset = 16844052; // 0x1010514 field public static final int onClick = 16843375; // 0x101026f @@ -47237,6 +47239,7 @@ package android.view { field public static final int FLAG_APPEND_TO_GROUP = 1; // 0x1 field public static final int FLAG_PERFORM_NO_CLOSE = 1; // 0x1 field public static final int NONE = 0; // 0x0 + field public static final int SUPPORTED_MODIFIERS_MASK = 69647; // 0x1100f } public class MenuInflater { @@ -47249,6 +47252,7 @@ package android.view { method public abstract boolean expandActionView(); method public abstract android.view.ActionProvider getActionProvider(); method public abstract android.view.View getActionView(); + method public default int getAlphabeticModifiers(); method public abstract char getAlphabeticShortcut(); method public default java.lang.CharSequence getContentDescription(); method public abstract int getGroupId(); @@ -47256,6 +47260,7 @@ package android.view { method public abstract android.content.Intent getIntent(); method public abstract int getItemId(); method public abstract android.view.ContextMenu.ContextMenuInfo getMenuInfo(); + method public default int getNumericModifiers(); method public abstract char getNumericShortcut(); method public abstract int getOrder(); method public abstract android.view.SubMenu getSubMenu(); @@ -47272,6 +47277,7 @@ package android.view { method public abstract android.view.MenuItem setActionView(android.view.View); method public abstract android.view.MenuItem setActionView(int); method public abstract android.view.MenuItem setAlphabeticShortcut(char); + method public default android.view.MenuItem setAlphabeticShortcut(char, int); method public abstract android.view.MenuItem setCheckable(boolean); method public abstract android.view.MenuItem setChecked(boolean); method public default android.view.MenuItem setContentDescription(java.lang.CharSequence); @@ -47280,9 +47286,11 @@ package android.view { method public abstract android.view.MenuItem setIcon(int); method public abstract android.view.MenuItem setIntent(android.content.Intent); method public abstract android.view.MenuItem setNumericShortcut(char); + method public default android.view.MenuItem setNumericShortcut(char, int); method public abstract android.view.MenuItem setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener); method public abstract android.view.MenuItem setOnMenuItemClickListener(android.view.MenuItem.OnMenuItemClickListener); method public abstract android.view.MenuItem setShortcut(char, char); + method public default android.view.MenuItem setShortcut(char, char, int, int); method public abstract void setShowAsAction(int); method public abstract android.view.MenuItem setShowAsActionFlags(int); method public abstract android.view.MenuItem setTitle(java.lang.CharSequence); diff --git a/api/test-current.txt b/api/test-current.txt index 4fb669ad4752e..36f5835188b3a 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -269,6 +269,7 @@ package android { field public static final int allowTaskReparenting = 16843268; // 0x1010204 field public static final int allowUndo = 16843999; // 0x10104df field public static final int alpha = 16843551; // 0x101031f + field public static final int alphabeticModifiers = 16844112; // 0x1010550 field public static final int alphabeticShortcut = 16843235; // 0x10101e3 field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef field public static final int alwaysRetainTaskState = 16843267; // 0x1010203 @@ -923,6 +924,7 @@ package android { field public static final int numbersSelectorColor = 16843939; // 0x10104a3 field public static final int numbersTextColor = 16843937; // 0x10104a1 field public static final deprecated int numeric = 16843109; // 0x1010165 + field public static final int numericModifiers = 16844113; // 0x1010551 field public static final int numericShortcut = 16843236; // 0x10101e4 field public static final int offset = 16844052; // 0x1010514 field public static final int onClick = 16843375; // 0x101026f @@ -44125,6 +44127,7 @@ package android.view { field public static final int FLAG_APPEND_TO_GROUP = 1; // 0x1 field public static final int FLAG_PERFORM_NO_CLOSE = 1; // 0x1 field public static final int NONE = 0; // 0x0 + field public static final int SUPPORTED_MODIFIERS_MASK = 69647; // 0x1100f } public class MenuInflater { @@ -44137,6 +44140,7 @@ package android.view { method public abstract boolean expandActionView(); method public abstract android.view.ActionProvider getActionProvider(); method public abstract android.view.View getActionView(); + method public default int getAlphabeticModifiers(); method public abstract char getAlphabeticShortcut(); method public default java.lang.CharSequence getContentDescription(); method public abstract int getGroupId(); @@ -44144,6 +44148,7 @@ package android.view { method public abstract android.content.Intent getIntent(); method public abstract int getItemId(); method public abstract android.view.ContextMenu.ContextMenuInfo getMenuInfo(); + method public default int getNumericModifiers(); method public abstract char getNumericShortcut(); method public abstract int getOrder(); method public abstract android.view.SubMenu getSubMenu(); @@ -44160,6 +44165,7 @@ package android.view { method public abstract android.view.MenuItem setActionView(android.view.View); method public abstract android.view.MenuItem setActionView(int); method public abstract android.view.MenuItem setAlphabeticShortcut(char); + method public default android.view.MenuItem setAlphabeticShortcut(char, int); method public abstract android.view.MenuItem setCheckable(boolean); method public abstract android.view.MenuItem setChecked(boolean); method public default android.view.MenuItem setContentDescription(java.lang.CharSequence); @@ -44168,9 +44174,11 @@ package android.view { method public abstract android.view.MenuItem setIcon(int); method public abstract android.view.MenuItem setIntent(android.content.Intent); method public abstract android.view.MenuItem setNumericShortcut(char); + method public default android.view.MenuItem setNumericShortcut(char, int); method public abstract android.view.MenuItem setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener); method public abstract android.view.MenuItem setOnMenuItemClickListener(android.view.MenuItem.OnMenuItemClickListener); method public abstract android.view.MenuItem setShortcut(char, char); + method public default android.view.MenuItem setShortcut(char, char, int, int); method public abstract void setShowAsAction(int); method public abstract android.view.MenuItem setShowAsActionFlags(int); method public abstract android.view.MenuItem setTitle(java.lang.CharSequence); diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 6a1e74e053e26..edf60b4b19269 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -1744,13 +1744,14 @@ public class Activity extends ContextThemeWrapper final MenuItem item = menu.getItem(i); final CharSequence title = item.getTitle(); final char alphaShortcut = item.getAlphabeticShortcut(); + final int alphaModifiers = item.getAlphabeticModifiers(); if (title != null && alphaShortcut != MIN_VALUE) { if (group == null) { final int resource = mApplication.getApplicationInfo().labelRes; group = new KeyboardShortcutGroup(resource != 0 ? getString(resource) : null); } group.addItem(new KeyboardShortcutInfo( - title, alphaShortcut, KeyEvent.META_CTRL_ON)); + title, alphaShortcut, alphaModifiers)); } } if (group != null) { diff --git a/core/java/android/view/Menu.java b/core/java/android/view/Menu.java index 0c2e9cff81baa..a8ea4dc1b8a0d 100644 --- a/core/java/android/view/Menu.java +++ b/core/java/android/view/Menu.java @@ -74,6 +74,13 @@ public interface Menu { */ static final int CATEGORY_SHIFT = 16; + /** + * A mask of all supported modifiers for MenuItem's keyboard shortcuts + */ + static final int SUPPORTED_MODIFIERS_MASK = KeyEvent.META_META_ON | KeyEvent.META_CTRL_ON + | KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON | KeyEvent.META_SYM_ON + | KeyEvent.META_FUNCTION_ON; + /** * Value to use for group and item identifier integers when you don't care * about them. diff --git a/core/java/android/view/MenuInflater.java b/core/java/android/view/MenuInflater.java index 7a5c65f6a87ef..6574bc0a1db82 100644 --- a/core/java/android/view/MenuInflater.java +++ b/core/java/android/view/MenuInflater.java @@ -305,7 +305,9 @@ public class MenuInflater { private CharSequence itemTitleCondensed; private int itemIconResId; private char itemAlphabeticShortcut; + private int itemAlphabeticModifiers; private char itemNumericShortcut; + private int itemNumericModifiers; /** * Sync to attrs.xml enum: * - 0: none @@ -395,8 +397,14 @@ public class MenuInflater { itemIconResId = a.getResourceId(com.android.internal.R.styleable.MenuItem_icon, 0); itemAlphabeticShortcut = getShortcut(a.getString(com.android.internal.R.styleable.MenuItem_alphabeticShortcut)); + itemAlphabeticModifiers = + a.getInt(com.android.internal.R.styleable.MenuItem_alphabeticModifiers, + KeyEvent.META_CTRL_ON); itemNumericShortcut = getShortcut(a.getString(com.android.internal.R.styleable.MenuItem_numericShortcut)); + itemNumericModifiers = + a.getInt(com.android.internal.R.styleable.MenuItem_numericModifiers, + KeyEvent.META_CTRL_ON); if (a.hasValue(com.android.internal.R.styleable.MenuItem_checkable)) { // Item has attribute checkable, use it itemCheckable = a.getBoolean(com.android.internal.R.styleable.MenuItem_checkable, false) ? 1 : 0; @@ -451,8 +459,8 @@ public class MenuInflater { .setCheckable(itemCheckable >= 1) .setTitleCondensed(itemTitleCondensed) .setIcon(itemIconResId) - .setAlphabeticShortcut(itemAlphabeticShortcut) - .setNumericShortcut(itemNumericShortcut); + .setAlphabeticShortcut(itemAlphabeticShortcut, itemAlphabeticModifiers) + .setNumericShortcut(itemNumericShortcut, itemNumericModifiers); if (itemShowAsAction >= 0) { item.setShowAsAction(itemShowAsAction); diff --git a/core/java/android/view/MenuItem.java b/core/java/android/view/MenuItem.java index 3f8d08937a777..6aaaedbeb1af5 100644 --- a/core/java/android/view/MenuItem.java +++ b/core/java/android/view/MenuItem.java @@ -261,12 +261,13 @@ public interface MenuItem { /** * Change both the numeric and alphabetic shortcut associated with this * item. Note that the shortcut will be triggered when the key that - * generates the given character is pressed along with the ctrl key. - * Also note that case is not significant and that alphabetic shortcut - * characters will be displayed in lower case. + * generates the given character is pressed along with the corresponding + * modifier key. The default modifier is {@link KeyEvent#META_CTRL_ON} in + * case nothing is specified. Also note that case is not significant and + * that alphabetic shortcut characters will be handled in lower case. *
* See {@link Menu} for the menu types that support shortcuts. - * + * * @param numericChar The numeric shortcut key. This is the shortcut when * using a numeric (e.g., 12-key) keyboard. * @param alphaChar The alphabetic shortcut key. This is the shortcut when @@ -275,6 +276,39 @@ public interface MenuItem { */ public MenuItem setShortcut(char numericChar, char alphaChar); + /** + * Change both the numeric and alphabetic shortcut associated with this + * item. Note that the shortcut will be triggered when the key that + * generates the given character is pressed along with the corresponding + * modifier key. Also note that case is not significant and that alphabetic + * shortcut characters will be handled in lower case. + *
+ * See {@link Menu} for the menu types that support shortcuts. + * + * @param numericChar The numeric shortcut key. This is the shortcut when + * using a numeric (e.g., 12-key) keyboard. + * @param numericModifiers The numeric modifier associated with the shortcut. It should + * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON}, + * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON}, + * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}. + * @param alphaChar The alphabetic shortcut key. This is the shortcut when + * using a keyboard with alphabetic keys. + * @param alphaModifiers The alphabetic modifier associated with the shortcut. It should + * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON}, + * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON}, + * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}. + * @return This Item so additional setters can be called. + */ + default public MenuItem setShortcut(char numericChar, char alphaChar, int numericModifiers, + int alphaModifiers) { + if ((alphaModifiers & Menu.SUPPORTED_MODIFIERS_MASK) == KeyEvent.META_CTRL_ON + && (numericModifiers & Menu.SUPPORTED_MODIFIERS_MASK) == KeyEvent.META_CTRL_ON) { + return setShortcut(numericChar, alphaChar); + } else { + return this; + } + } + /** * Change the numeric shortcut associated with this item. *
@@ -286,6 +320,27 @@ public interface MenuItem { */ public MenuItem setNumericShortcut(char numericChar); + /** + * Change the numeric shortcut and modifiers associated with this item. + *
+ * See {@link Menu} for the menu types that support shortcuts. + * + * @param numericChar The numeric shortcut key. This is the shortcut when + * using a 12-key (numeric) keyboard. + * @param numericModifiers The modifier associated with the shortcut. It should + * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON}, + * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON}, + * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}. + * @return This Item so additional setters can be called. + */ + default public MenuItem setNumericShortcut(char numericChar, int numericModifiers) { + if ((numericModifiers & Menu.SUPPORTED_MODIFIERS_MASK) == KeyEvent.META_CTRL_ON) { + return setNumericShortcut(numericChar); + } else { + return this; + } + } + /** * Return the char for this menu item's numeric (12-key) shortcut. * @@ -293,22 +348,63 @@ public interface MenuItem { */ public char getNumericShortcut(); + /** + * Return the modifiers for this menu item's numeric (12-key) shortcut. + * The modifier is a combination of {@link KeyEvent#META_META_ON}, + * {@link KeyEvent#META_CTRL_ON}, {@link KeyEvent#META_ALT_ON}, + * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_SYM_ON}, + * {@link KeyEvent#META_FUNCTION_ON}. + * For example, {@link KeyEvent#META_FUNCTION_ON}|{@link KeyEvent#META_CTRL_ON} + * + * @return Modifier associated with the numeric shortcut. + */ + default public int getNumericModifiers() { + return KeyEvent.META_CTRL_ON; + } + /** * Change the alphabetic shortcut associated with this item. The shortcut * will be triggered when the key that generates the given character is - * pressed along with the ctrl key. Case is not significant and shortcut - * characters will be displayed in lower case. Note that menu items with - * the characters '\b' or '\n' as shortcuts will get triggered by the - * Delete key or Carriage Return key, respectively. + * pressed along with the corresponding modifier key. The default modifier + * is {@link KeyEvent#META_CTRL_ON} in case nothing is specified. Case is + * not significant and shortcut characters will be displayed in lower case. + * Note that menu items with the characters '\b' or '\n' as shortcuts will + * get triggered by the Delete key or Carriage Return key, respectively. *
* See {@link Menu} for the menu types that support shortcuts. - * + * * @param alphaChar The alphabetic shortcut key. This is the shortcut when * using a keyboard with alphabetic keys. * @return This Item so additional setters can be called. */ public MenuItem setAlphabeticShortcut(char alphaChar); + /** + * Change the alphabetic shortcut associated with this item. The shortcut + * will be triggered when the key that generates the given character is + * pressed along with the modifier keys. Case is not significant and shortcut + * characters will be displayed in lower case. Note that menu items with + * the characters '\b' or '\n' as shortcuts will get triggered by the + * Delete key or Carriage Return key, respectively. + *
+ * See {@link Menu} for the menu types that support shortcuts. + * + * @param alphaChar The alphabetic shortcut key. This is the shortcut when + * using a keyboard with alphabetic keys. + * @param alphaModifiers The modifier associated with the shortcut. It should + * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON}, + * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON}, + * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}. + * @return This Item so additional setters can be called. + */ + default public MenuItem setAlphabeticShortcut(char alphaChar, int alphaModifiers) { + if ((alphaModifiers & Menu.SUPPORTED_MODIFIERS_MASK) == KeyEvent.META_CTRL_ON) { + return setAlphabeticShortcut(alphaChar); + } else { + return this; + } + } + /** * Return the char for this menu item's alphabetic shortcut. * @@ -316,6 +412,20 @@ public interface MenuItem { */ public char getAlphabeticShortcut(); + /** + * Return the modifier for this menu item's alphabetic shortcut. + * The modifier is a combination of {@link KeyEvent#META_META_ON}, + * {@link KeyEvent#META_CTRL_ON}, {@link KeyEvent#META_ALT_ON}, + * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_SYM_ON}, + * {@link KeyEvent#META_FUNCTION_ON}. + * For example, {@link KeyEvent#META_FUNCTION_ON}|{@link KeyEvent#META_CTRL_ON} + * + * @return Modifier associated with the keyboard shortcut. + */ + default public int getAlphabeticModifiers() { + return KeyEvent.META_CTRL_ON; + } + /** * Control whether this item can display a check mark. Setting this does * not actually display a check mark (see {@link #setChecked} for that); @@ -323,7 +433,7 @@ public interface MenuItem { * check mark. *
* See {@link Menu} for the menu types that support check marks.
- *
+ *
* @param checkable Set to true to allow a check mark, false to
* disallow. The default is false.
* @see #setChecked
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index cb29053e51a6f..bdc3e7f468c9d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -4479,9 +4479,9 @@ public final class ViewRootImpl implements ViewParent,
}
}
- // If the Control modifier is held, try to interpret the key as a shortcut.
+ // If a modifier is held, try to interpret the key as a shortcut.
if (event.getAction() == KeyEvent.ACTION_DOWN
- && event.isCtrlPressed()
+ && !KeyEvent.metaStateHasNoModifiers(event.getMetaState())
&& event.getRepeatCount() == 0
&& !KeyEvent.isModifierKey(event.getKeyCode())
&& groupNavigationDirection == 0) {
diff --git a/core/java/com/android/internal/view/menu/ActionMenu.java b/core/java/com/android/internal/view/menu/ActionMenu.java
index 3d44ebc24d749..c657b872e71e3 100644
--- a/core/java/com/android/internal/view/menu/ActionMenu.java
+++ b/core/java/com/android/internal/view/menu/ActionMenu.java
@@ -38,7 +38,7 @@ public class ActionMenu implements Menu {
private boolean mIsQwerty;
private ArrayList