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

Commit 0d9fdbad authored by Adam Powell's avatar Adam Powell
Browse files

Explicitly track consumed state for WindowInsets

Treating 0-insets as fully consumed is incorrect since it means that
you can't dispatch empty insets down the view hierarchy - traversal
terminates immediately. Track consumed state independent of actual
values. Replacing a given set of insets with all zeroes will mark it
consumed.

Bug 15341653

Change-Id: I55b33b7dfbf4cae1e906a82140537156cffdbf47
parent 91b7d2b4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6105,7 +6105,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            // apply insets path and take things from there.
            try {
                mPrivateFlags3 |= PFLAG3_FITTING_SYSTEM_WINDOWS;
                return !dispatchApplyWindowInsets(new WindowInsets(insets)).hasInsets();
                return dispatchApplyWindowInsets(new WindowInsets(insets)).isConsumed();
            } finally {
                mPrivateFlags3 &= ~PFLAG3_FITTING_SYSTEM_WINDOWS;
            }
+2 −2
Original line number Diff line number Diff line
@@ -5574,11 +5574,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    @Override
    public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
        insets = super.dispatchApplyWindowInsets(insets);
        if (insets.hasInsets()) {
        if (!insets.isConsumed()) {
            final int count = getChildCount();
            for (int i = 0; i < count; i++) {
                insets = getChildAt(i).dispatchApplyWindowInsets(insets);
                if (!insets.hasInsets()) {
                if (insets.isConsumed()) {
                    break;
                }
            }
+40 −6
Original line number Diff line number Diff line
@@ -35,6 +35,9 @@ public final class WindowInsets {
    private Rect mTempRect;
    private boolean mIsRound;

    private boolean mSystemWindowInsetsConsumed = false;
    private boolean mWindowDecorInsetsConsumed = false;

    private static final Rect EMPTY_RECT = new Rect(0, 0, 0, 0);

    /**
@@ -52,13 +55,17 @@ public final class WindowInsets {

    /** @hide */
    public WindowInsets(Rect systemWindowInsets, boolean isRound) {
        this(systemWindowInsets, EMPTY_RECT, isRound);
        this(systemWindowInsets, null, isRound);
    }

    /** @hide */
    public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, boolean isRound) {
        mSystemWindowInsets = systemWindowInsets;
        mWindowDecorInsets = windowDecorInsets;
        mSystemWindowInsetsConsumed = systemWindowInsets == null;
        mSystemWindowInsets = mSystemWindowInsetsConsumed ? EMPTY_RECT : systemWindowInsets;

        mWindowDecorInsetsConsumed = windowDecorInsets == null;
        mWindowDecorInsets = mWindowDecorInsetsConsumed ? EMPTY_RECT : windowDecorInsets;

        mIsRound = isRound;
    }

@@ -70,12 +77,14 @@ public final class WindowInsets {
    public WindowInsets(WindowInsets src) {
        mSystemWindowInsets = src.mSystemWindowInsets;
        mWindowDecorInsets = src.mWindowDecorInsets;
        mSystemWindowInsetsConsumed = src.mSystemWindowInsetsConsumed;
        mWindowDecorInsetsConsumed = src.mWindowDecorInsetsConsumed;
        mIsRound = src.mIsRound;
    }

    /** @hide */
    public WindowInsets(Rect systemWindowInsets) {
        this(systemWindowInsets, EMPTY_RECT);
        this(systemWindowInsets, null);
    }

    /**
@@ -237,6 +246,24 @@ public final class WindowInsets {
        return hasSystemWindowInsets() || hasWindowDecorInsets();
    }

    /**
     * Check if these insets have been fully consumed.
     *
     * <p>Insets are considered "consumed" if the applicable <code>consume*</code> methods
     * have been called such that all insets have been set to zero. This affects propagation of
     * insets through the view hierarchy; insets that have not been fully consumed will continue
     * to propagate down to child views.</p>
     *
     * <p>The result of this method is equivalent to the return value of
     * {@link View#fitSystemWindows(android.graphics.Rect)}.</p>
     *
     * @return true if the insets have been fully consumed.
     * @hide Pending API
     */
    public boolean isConsumed() {
        return mSystemWindowInsetsConsumed && mWindowDecorInsetsConsumed;
    }

    /**
     * Returns true if the associated window has a round shape.
     *
@@ -258,7 +285,8 @@ public final class WindowInsets {
     */
    public WindowInsets consumeSystemWindowInsets() {
        final WindowInsets result = new WindowInsets(this);
        result.mSystemWindowInsets = new Rect(0, 0, 0, 0);
        result.mSystemWindowInsets = EMPTY_RECT;
        result.mSystemWindowInsetsConsumed = true;
        return result;
    }

@@ -276,10 +304,12 @@ public final class WindowInsets {
            boolean right, boolean bottom) {
        if (left || top || right || bottom) {
            final WindowInsets result = new WindowInsets(this);
            result.mSystemWindowInsets = new Rect(left ? 0 : mSystemWindowInsets.left,
            result.mSystemWindowInsets = new Rect(
                    left ? 0 : mSystemWindowInsets.left,
                    top ? 0 : mSystemWindowInsets.top,
                    right ? 0 : mSystemWindowInsets.right,
                    bottom ? 0 : mSystemWindowInsets.bottom);
            result.mSystemWindowInsetsConsumed = !hasSystemWindowInsets();
            return result;
        }
        return this;
@@ -299,6 +329,7 @@ public final class WindowInsets {
            int right, int bottom) {
        final WindowInsets result = new WindowInsets(this);
        result.mSystemWindowInsets = new Rect(left, top, right, bottom);
        result.mSystemWindowInsetsConsumed = !hasSystemWindowInsets();
        return result;
    }

@@ -308,6 +339,7 @@ public final class WindowInsets {
    public WindowInsets consumeWindowDecorInsets() {
        final WindowInsets result = new WindowInsets(this);
        result.mWindowDecorInsets.set(0, 0, 0, 0);
        result.mWindowDecorInsetsConsumed = true;
        return result;
    }

@@ -322,6 +354,7 @@ public final class WindowInsets {
                    top ? 0 : mWindowDecorInsets.top,
                    right ? 0 : mWindowDecorInsets.right,
                    bottom ? 0 : mWindowDecorInsets.bottom);
            result.mWindowDecorInsetsConsumed = !hasWindowDecorInsets();
            return result;
        }
        return this;
@@ -333,6 +366,7 @@ public final class WindowInsets {
    public WindowInsets replaceWindowDecorInsets(int left, int top, int right, int bottom) {
        final WindowInsets result = new WindowInsets(this);
        result.mWindowDecorInsets = new Rect(left, top, right, bottom);
        result.mWindowDecorInsetsConsumed = !hasWindowDecorInsets();
        return result;
    }