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

Commit b7cc39e1 authored by Tiger's avatar Tiger
Browse files

Always contain window frames in window bounds

Previously, if the window bounds and the safe area of display cutout
don't intersect, we might get invalid window frames.

This CL uses a new method to intersect rectangles which makes sure the
result frame is contained by the window bounds.

Fix: 367461591
Flag: EXEMPT bugfix
Test: atest WindowLayoutTests
Change-Id: I63d28e5dcdcea9f4206f5026c00905a5cb413bd3
parent cd59885b
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -157,10 +157,10 @@ public class WindowLayout {
            // which prevents overlap with the DisplayCutout.
            if (!attachedInParent && !floatingInScreenWindow) {
                mTempRect.set(outParentFrame);
                outParentFrame.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
                intersectOrClamp(outParentFrame, displayCutoutSafeExceptMaybeBars);
                frames.isParentFrameClippedByDisplayCutout = !mTempRect.equals(outParentFrame);
            }
            outDisplayFrame.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
            intersectOrClamp(outDisplayFrame, displayCutoutSafeExceptMaybeBars);
        }

        final boolean noLimits = (attrs.flags & FLAG_LAYOUT_NO_LIMITS) != 0;
@@ -283,6 +283,19 @@ public class WindowLayout {
                + " requestedInvisibleTypes=" + WindowInsets.Type.toString(~requestedVisibleTypes));
    }

    /**
     * If both rectangles intersect, set inOutRect to that intersection. Otherwise, clamp inOutRect
     * to the side (or the corner) that the other rectangle is away from.
     * Unlike {@link Rect#intersectUnchecked(Rect)}, this method guarantees that the new rectangle
     * is valid and contained in inOutRect if rectangles involved are valid.
     */
    private static void intersectOrClamp(Rect inOutRect, Rect other) {
        inOutRect.left = Math.min(Math.max(inOutRect.left, other.left), inOutRect.right);
        inOutRect.top = Math.min(Math.max(inOutRect.top, other.top), inOutRect.bottom);
        inOutRect.right = Math.max(Math.min(inOutRect.right, other.right), inOutRect.left);
        inOutRect.bottom = Math.max(Math.min(inOutRect.bottom, other.bottom), inOutRect.top);
    }

    public static void extendFrameByCutout(Rect displayCutoutSafe,
            Rect displayFrame, Rect inOutFrame, Rect tempRect) {
        if (displayCutoutSafe.contains(inOutFrame)) {
+15 −0
Original line number Diff line number Diff line
@@ -413,4 +413,19 @@ public class WindowLayoutTests {
        assertInsetByTopBottom(0, 0, mFrames.parentFrame);
        assertInsetByTopBottom(0, 0, mFrames.frame);
    }

    @Test
    public void windowBoundsOutsideDisplayCutoutSafe() {
        addDisplayCutout();
        mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
        mWindowBounds.set(0, -1000, DISPLAY_WIDTH, 0);
        computeFrames();

        assertRect(WATERFALL_INSETS.left, 0, DISPLAY_WIDTH - WATERFALL_INSETS.right, 0,
                mFrames.displayFrame);
        assertRect(WATERFALL_INSETS.left, 0, DISPLAY_WIDTH - WATERFALL_INSETS.right, 0,
                mFrames.parentFrame);
        assertRect(WATERFALL_INSETS.left, 0, DISPLAY_WIDTH - WATERFALL_INSETS.right, 0,
                mFrames.frame);
    }
}