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

Commit 07084924 authored by Vladislav Kaznacheev's avatar Vladislav Kaznacheev
Browse files

Respect PopupWindow.setOverlapAnchor when above anchor

Currently if a popup menu is shown above the anchor, it
is anchored to the anchor's top edge regardless of the value of
mOverlapAnchor.

Fixing the vertical offset correction and the computation of the
vertical space available above the anchor.

Bug: 36000552
Test: android.widget.cts.PopupWindowTest#testOverlapAnchor
Change-Id: Ifb71ff1fc0aa0df58e4919fd229c2623a2bcbe3d
parent e20f8fb5
Loading
Loading
Loading
Loading
+20 −5
Original line number Original line Diff line number Diff line
@@ -1620,17 +1620,32 @@ public class PopupWindow {
            int anchorHeight, int drawingLocationY, int screenLocationY, int displayFrameTop,
            int anchorHeight, int drawingLocationY, int screenLocationY, int displayFrameTop,
            int displayFrameBottom, boolean allowResize) {
            int displayFrameBottom, boolean allowResize) {
        final int winOffsetY = screenLocationY - drawingLocationY;
        final int winOffsetY = screenLocationY - drawingLocationY;
        final int anchorTopInScreen = outParams.y + winOffsetY;
        final int popupScreenTop = outParams.y + winOffsetY;
        final int spaceBelow = displayFrameBottom - anchorTopInScreen;
        final int spaceBelow = displayFrameBottom - popupScreenTop;
        if (anchorTopInScreen >= 0 && height <= spaceBelow) {
        if (popupScreenTop >= 0 && height <= spaceBelow) {
            return true;
            return true;
        }
        }


        final int spaceAbove = anchorTopInScreen - anchorHeight - displayFrameTop;
        final int popupScreenBottom;
        if (mOverlapAnchor) {
            // popupScreenTop equals the anchor's top at this point.
            // When shown above the anchor, an overlapping popup's bottom should be aligned with
            // the anchor's bottom.
            popupScreenBottom = popupScreenTop + anchorHeight;
        } else {
            // popupScreenTop equals the anchor's bottom at this point.
            // When shown above the anchor, a non-overlapping popup's bottom is aligned with
            // the anchor's top.
            popupScreenBottom = popupScreenTop - anchorHeight;
        }
        final int spaceAbove = popupScreenBottom - displayFrameTop;
        if (height <= spaceAbove) {
        if (height <= spaceAbove) {
            // Move everything up.
            // Move everything up.
            if (mOverlapAnchor) {
            if (mOverlapAnchor) {
                yOffset += anchorHeight;
                // Add one anchorHeight to compensate for the correction made at the start of
                // findDropDownPosition, and another to account for being aligned to the anchor's
                // bottom, not top.
                yOffset += anchorHeight * 2;
            }
            }
            outParams.y = drawingLocationY - height + yOffset;
            outParams.y = drawingLocationY - height + yOffset;