diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 3fe6b8e2e3f81..c54ce80631bd2 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -386,6 +386,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ private static final int FLAG_START_ACTION_MODE_FOR_CHILD_IS_NOT_TYPED = 0x10000000; + /** + * When set, indicates that a call to showContextMenuForChild was made with explicit + * coordinates within the initiating child view. + */ + private static final int FLAG_SHOW_CONTEXT_MENU_WITH_COORDS = 0x20000000; + /** * Indicates which types of drawing caches are to be kept in memory. * This field should be made private, so it is hidden from the SDK. @@ -756,11 +762,31 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @Override public boolean showContextMenuForChild(View originalView) { + if (isShowingContextMenuWithCoords()) { + // We're being called for compatibility. Return false and let the version + // with coordinates recurse up. + return false; + } return mParent != null && mParent.showContextMenuForChild(originalView); } + /** + * @hide used internally for compatibility with existing app code only + */ + public final boolean isShowingContextMenuWithCoords() { + return (mGroupFlags & FLAG_SHOW_CONTEXT_MENU_WITH_COORDS) != 0; + } + @Override public boolean showContextMenuForChild(View originalView, float x, float y) { + try { + mGroupFlags |= FLAG_SHOW_CONTEXT_MENU_WITH_COORDS; + if (showContextMenuForChild(originalView)) { + return true; + } + } finally { + mGroupFlags &= ~FLAG_SHOW_CONTEXT_MENU_WITH_COORDS; + } return mParent != null && mParent.showContextMenuForChild(originalView, x, y); } diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java index 1962be86ffb1c..06afef27cee5a 100644 --- a/core/java/android/view/ViewParent.java +++ b/core/java/android/view/ViewParent.java @@ -192,6 +192,9 @@ public interface ViewParent { * 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. + *

+ * If a subclass overrides this method it should also override + * {@link #showContextMenuForChild(View)}. * * @param originalView the source view where the context menu was first * invoked @@ -202,7 +205,7 @@ public interface ViewParent { * @return {@code true} if the context menu was shown, {@code false} * otherwise */ - public boolean showContextMenuForChild(View originalView, float x, float y); + boolean showContextMenuForChild(View originalView, float x, float y); /** * Have the parent populate the specified context menu if it has anything to diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 7b6fa6dab075b..b689564cfe589 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -3247,6 +3247,9 @@ public abstract class AbsListView extends AdapterView implements Te @Override public boolean showContextMenuForChild(View originalView) { + if (isShowingContextMenuWithCoords()) { + return false; + } return showContextMenuForChildInternal(originalView, 0, 0, false); } diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java index a6ef572a2e3a0..7655f3df93f30 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -1160,6 +1160,9 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList @Override public boolean showContextMenuForChild(View originalView) { + if (isShowingContextMenuWithCoords()) { + return false; + } return showContextMenuForChildInternal(originalView, 0, 0, false); }