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

Commit 9643e739 authored by Alan Viverette's avatar Alan Viverette Committed by Android (Google) Code Review
Browse files

Merge "Ensure only one context menu is shown at a time"

parents 8b4fce4b 021627eb
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -5505,20 +5505,26 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    }
    /**
     * Bring up the context menu for this view.
     * Shows the context menu for this view.
     *
     * @return Whether a context menu was displayed.
     * @return {@code true} if the context menu was shown, {@code false}
     *         otherwise
     * @see #showContextMenu(float, float)
     */
    public boolean showContextMenu() {
        return getParent().showContextMenuForChild(this);
    }
    /**
     * Bring up the context menu for this view, referring to the item under the specified point.
     * Shows the context menu for this view anchored to the specified
     * view-relative coordinate.
     *
     * @param x The referenced x coordinate.
     * @param y The referenced y coordinate.
     * @return Whether a context menu was displayed.
     * @param x the X coordinate in pixels relative to the view to which the
     *          menu should be anchored
     * @param y the Y coordinate in pixels relative to the view to which the
     *          menu should be anchored
     * @return {@code true} if the context menu was shown, {@code false}
     *         otherwise
     */
    public boolean showContextMenu(float x, float y) {
        return getParent().showContextMenuForChild(this, x, y);
+26 −14
Original line number Diff line number Diff line
@@ -174,26 +174,38 @@ public interface ViewParent {
    public void focusableViewAvailable(View v);

    /**
     * Bring up a context menu for the specified view or its ancestors.
     *
     * <p>In most cases, a subclass does not need to override this.  However, if
     * Shows the context menu for the specified view or its ancestors.
     * <p>
     * In most cases, a subclass does not need to override this. However, if
     * the subclass is added directly to the window manager (for example,
     * {@link ViewManager#addView(View, android.view.ViewGroup.LayoutParams)})
     * then it should override this and show the context menu.</p>
     * then it should override this and show the context menu.
     *
     * @param originalView The source view where the context menu was first invoked
     * @return true if a context menu was displayed
     * @param originalView the source view where the context menu was first
     *                     invoked
     * @return {@code true} if the context menu was shown, {@code false}
     *         otherwise
     * @see #showContextMenuForChild(View, float, float)
     */
    public boolean showContextMenuForChild(View originalView);

    /**
     * Bring up a context menu for the specified view at the given x/y offset from
     * the top left corner.
     *
     * @param originalView
     * @param x The x offset at which to open the menu
     * @param y The y offset at which to open the menu
     * @return true if a context menu was displayed
     * Shows the context menu for the specified view or its ancestors anchored
     * to the specified view-relative coordinate.
     * <p>
     * In most cases, a subclass does not need to override this. However, if
     * the subclass is added directly to the window manager (for example,
     * {@link ViewManager#addView(View, android.view.ViewGroup.LayoutParams)})
     * then it should override this and show the context menu.
     *
     * @param originalView the source view where the context menu was first
     *                     invoked
     * @param x the X coordinate in pixels relative to the original view to
     *          which the menu should be anchored
     * @param y the Y coordinate in pixels relative to the original view to
     *          which the menu should be anchored
     * @return {@code true} if the context menu was shown, {@code false}
     *         otherwise
     */
    public boolean showContextMenuForChild(View originalView, float x, float y);

+2 −2
Original line number Diff line number Diff line
@@ -933,7 +933,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter
            super(context, menu, anchorView, overflowOnly,
                    com.android.internal.R.attr.actionOverflowMenuStyle);
            setGravity(Gravity.END);
            setCallback(mPopupPresenterCallback);
            setPresenterCallback(mPopupPresenterCallback);
        }

        @Override
@@ -956,7 +956,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter
                setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton);
            }

            setCallback(mPopupPresenterCallback);
            setPresenterCallback(mPopupPresenterCallback);
        }

        @Override
+24 −30
Original line number Diff line number Diff line
@@ -21,8 +21,7 @@ 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.MenuDialogHelper;
import com.android.internal.view.menu.MenuPopupHelper;
import com.android.internal.view.menu.MenuHelper;
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.BackgroundFallback;
import com.android.internal.widget.DecorCaptionView;
@@ -659,30 +658,23 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind

    @Override
    public boolean showContextMenuForChild(View originalView) {
        // Reuse the context menu builder
        if (mWindow.mContextMenu == null) {
            mWindow.mContextMenu = new ContextMenuBuilder(getContext());
            mWindow.mContextMenu.setCallback(mWindow.mContextMenuCallback);
        } else {
            mWindow.mContextMenu.clearAll();
        return showContextMenuForChildInternal(originalView, 0, 0, false);
    }

        final MenuDialogHelper helper = mWindow.mContextMenu.show(originalView,
                originalView.getWindowToken());
        if (helper != null) {
            helper.setPresenterCallback(mWindow.mContextMenuCallback);
        } else if (mWindow.mContextMenuHelper != null) {
            // No menu to show, but if we have a menu currently showing it just became blank.
            // Close it.
            mWindow.mContextMenuHelper.dismiss();
    @Override
    public boolean showContextMenuForChild(View originalView, float x, float y) {
        return showContextMenuForChildInternal(originalView, x, y, true);
    }
        mWindow.mContextMenuHelper = helper;
        return helper != null;

    private boolean showContextMenuForChildInternal(View originalView,
            float x, float y, boolean isPopup) {
        // Only allow one context menu at a time.
        if (mWindow.mContextMenuHelper != null) {
            mWindow.mContextMenuHelper.dismiss();
            mWindow.mContextMenuHelper = null;
        }

    @Override
    public boolean showContextMenuForChild(View originalView, float x, float y) {
        // Reuse the context menu builder
        // Reuse the context menu builder.
        if (mWindow.mContextMenu == null) {
            mWindow.mContextMenu = new ContextMenuBuilder(getContext());
            mWindow.mContextMenu.setCallback(mWindow.mContextMenuCallback);
@@ -690,16 +682,18 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
            mWindow.mContextMenu.clearAll();
        }

        final MenuPopupHelper helper = mWindow.mContextMenu.showPopup(
                getContext(), originalView, x, y);
        final MenuHelper helper;
        if (isPopup) {
            helper = mWindow.mContextMenu.showPopup(getContext(), originalView, x, y);
        } else {
            helper = mWindow.mContextMenu.showDialog(originalView, originalView.getWindowToken());
        }

        if (helper != null) {
            helper.setCallback(mWindow.mContextMenuCallback);
        } else if (mWindow.mContextMenuPopupHelper != null) {
            // No menu to show, but if we have a menu currently showing it just became blank.
            // Close it.
            mWindow.mContextMenuPopupHelper.dismiss();
            helper.setPresenterCallback(mWindow.mContextMenuCallback);
        }
        mWindow.mContextMenuPopupHelper = helper;

        mWindow.mContextMenuHelper = helper;
        return helper != null;
    }

+2 −7
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ import com.android.internal.view.menu.IconMenuPresenter;
import com.android.internal.view.menu.ListMenuPresenter;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.view.menu.MenuDialogHelper;
import com.android.internal.view.menu.MenuPopupHelper;
import com.android.internal.view.menu.MenuHelper;
import com.android.internal.view.menu.MenuPresenter;
import com.android.internal.view.menu.MenuView;
import com.android.internal.widget.DecorContentParent;
@@ -232,8 +232,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
    private boolean mAlwaysReadCloseOnTouchAttr = false;

    ContextMenuBuilder mContextMenu;
    MenuDialogHelper mContextMenuHelper;
    MenuPopupHelper mContextMenuPopupHelper;
    MenuHelper mContextMenuHelper;
    private boolean mClosingActionMenu;

    private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
@@ -1103,10 +1102,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
            mContextMenuHelper.dismiss();
            mContextMenuHelper = null;
        }
        if (mContextMenuPopupHelper != null) {
            mContextMenuPopupHelper.dismiss();
            mContextMenuPopupHelper = null;
        }
    }

    @Override
Loading