diff options
3 files changed, 54 insertions, 30 deletions
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index e40556446a39..f6b8e918e61a 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -17,11 +17,13 @@ package com.android.internal.policy; import com.android.internal.R; +import com.android.internal.policy.PhoneWindow.PhoneWindowMenuCallback; import com.android.internal.view.FloatingActionMode; import com.android.internal.view.RootViewSurfaceTaker; import com.android.internal.view.StandaloneActionMode; import com.android.internal.view.menu.ContextMenuBuilder; import com.android.internal.view.menu.MenuHelper; +import com.android.internal.view.menu.MenuPresenter; import com.android.internal.widget.ActionBarContextView; import com.android.internal.widget.BackgroundFallback; import com.android.internal.widget.DecorCaptionView; @@ -684,9 +686,10 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind } // Reuse the context menu builder. + final PhoneWindowMenuCallback callback = mWindow.mContextMenuCallback; if (mWindow.mContextMenu == null) { mWindow.mContextMenu = new ContextMenuBuilder(getContext()); - mWindow.mContextMenu.setCallback(mWindow.mContextMenuCallback); + mWindow.mContextMenu.setCallback(callback); } else { mWindow.mContextMenu.clearAll(); } @@ -698,9 +701,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind helper = mWindow.mContextMenu.showDialog(originalView, originalView.getWindowToken()); } - if (helper != null) { - helper.setPresenterCallback(mWindow.mContextMenuCallback); - } + // If it's a dialog, the callback needs to handle showing sub-menus. + // Either way, the callback is required for propagating selection to + // Context.onContextMenuItemSelected(). + callback.setShowDialogForSubmenu(!isPopup); + helper.setPresenterCallback(callback); mWindow.mContextMenuHelper = helper; return helper != null; diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 86bd7824fc4d..1e9035bac3ae 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -127,7 +127,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { * Simple callback used by the context menu and its submenus. The options * menu submenus do not use this (their behavior is more complex). */ - final DialogMenuCallback mContextMenuCallback = new DialogMenuCallback(FEATURE_CONTEXT_MENU); + final PhoneWindowMenuCallback mContextMenuCallback = new PhoneWindowMenuCallback(this); final TypedValue mMinWidthMajor = new TypedValue(); final TypedValue mMinWidthMinor = new TypedValue(); @@ -3592,27 +3592,34 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { * <li> Calls back to the callback's onMenuItemSelected when an item is * selected. */ - private final class DialogMenuCallback implements MenuBuilder.Callback, MenuPresenter.Callback { - private int mFeatureId; + public static final class PhoneWindowMenuCallback + implements MenuBuilder.Callback, MenuPresenter.Callback { + private static final int FEATURE_ID = FEATURE_CONTEXT_MENU; + + private final PhoneWindow mWindow; + private MenuDialogHelper mSubMenuHelper; - public DialogMenuCallback(int featureId) { - mFeatureId = featureId; + private boolean mShowDialogForSubmenu; + + public PhoneWindowMenuCallback(PhoneWindow window) { + mWindow = window; } + @Override public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { if (menu.getRootMenu() != menu) { onCloseSubMenu(menu); } if (allMenusAreClosing) { - Callback callback = getCallback(); - if (callback != null && !isDestroyed()) { - callback.onPanelClosed(mFeatureId, menu); + final Callback callback = mWindow.getCallback(); + if (callback != null && !mWindow.isDestroyed()) { + callback.onPanelClosed(FEATURE_ID, menu); } - if (menu == mContextMenu) { - dismissContextMenu(); + if (menu == mWindow.mContextMenu) { + mWindow.dismissContextMenu(); } // Dismiss the submenu, if it is showing @@ -3623,33 +3630,45 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } } - public void onCloseSubMenu(MenuBuilder menu) { - Callback callback = getCallback(); - if (callback != null && !isDestroyed()) { - callback.onPanelClosed(mFeatureId, menu.getRootMenu()); + private void onCloseSubMenu(MenuBuilder menu) { + final Callback callback = mWindow.getCallback(); + if (callback != null && !mWindow.isDestroyed()) { + callback.onPanelClosed(FEATURE_ID, menu.getRootMenu()); } } + @Override public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { - Callback callback = getCallback(); - return (callback != null && !isDestroyed()) - && callback.onMenuItemSelected(mFeatureId, item); + final Callback callback = mWindow.getCallback(); + return callback != null && !mWindow.isDestroyed() + && callback.onMenuItemSelected(FEATURE_ID, item); } + @Override public void onMenuModeChange(MenuBuilder menu) { } + @Override public boolean onOpenSubMenu(MenuBuilder subMenu) { - if (subMenu == null) return false; + if (subMenu == null) { + return false; + } // Set a simple callback for the submenu subMenu.setCallback(this); - // The window manager will give us a valid window token - mSubMenuHelper = new MenuDialogHelper(subMenu); - mSubMenuHelper.show(null); + if (mShowDialogForSubmenu) { + // The window manager will give us a valid window token + mSubMenuHelper = new MenuDialogHelper(subMenu); + mSubMenuHelper.show(null); + return true; + } - return true; + return false; + } + + public void setShowDialogForSubmenu(boolean enabled) { + mShowDialogForSubmenu = enabled; } } diff --git a/core/java/com/android/internal/view/menu/StandardMenuPopup.java b/core/java/com/android/internal/view/menu/StandardMenuPopup.java index 6a5f6d844a41..c2adc42cb824 100644 --- a/core/java/com/android/internal/view/menu/StandardMenuPopup.java +++ b/core/java/com/android/internal/view/menu/StandardMenuPopup.java @@ -242,13 +242,13 @@ final class StandardMenuPopup extends MenuPopup implements OnDismissListener, On @Override public boolean onSubMenuSelected(SubMenuBuilder subMenu) { if (subMenu.hasVisibleItems()) { - MenuPopupHelper subPopup = new MenuPopupHelper( - mContext, subMenu, mShownAnchorView, mOverflowOnly, mPopupStyleAttr, - mPopupStyleRes); + final MenuPopupHelper subPopup = new MenuPopupHelper(mContext, subMenu, + mShownAnchorView, mOverflowOnly, mPopupStyleAttr, mPopupStyleRes); subPopup.setPresenterCallback(mPresenterCallback); subPopup.setForceShowIcon(mAdapter.getForceShowIcon()); - if (subPopup.tryShow()) { + // Show the new sub-menu popup at the same location as this popup. + if (subPopup.tryShow(mXOffset, mYOffset)) { if (mPresenterCallback != null) { mPresenterCallback.onOpenSubMenu(subMenu); } |