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

Commit 15637fdd authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

A brave new world for window insets (10/n)

Rework how dispatching works for apps targeting Q+

(flagged off at the moment behind VRI.USE_NEW_INSETS)

We properly dispatch windows in the hierarchy by fixing the issue
that insets modified by onApplyWindowInsets affected all other
views later in prefix order, including siblings and siblings of
parents.

Furthermore, we get rid of stopping dispatch if they are consumed,
as it gets a lot more complicated with the granular information we
add what consumed actually means.

Test: ViewGroupTest, ViewTest
Bug: 118118435

Change-Id: I9dfb69ebb93b334bb34d17889282293bec94e1af
parent bcf99fff
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -939,6 +939,26 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    private static boolean sAcceptZeroSizeDragShadow;
    /**
     * Prior to Q, {@link #dispatchApplyWindowInsets} had some issues:
     * <ul>
     *     <li>The modified insets changed by {@link #onApplyWindowInsets} were passed to the
     *     entire view hierarchy in prefix order, including siblings as well as siblings of parents
     *     further down the hierarchy. This violates the basic concepts of the view hierarchy, and
     *     thus, the hierarchical dispatching mechanism was hard to use for apps.</li>
     *
     *     <li>Dispatch was stopped after the insets were fully consumed. This is somewhat confusing
     *     for developers, but more importantly, by adding more granular information to
     *     {@link WindowInsets} it becomes really cumbersome to define what consumed actually means
     *     </li>
     * </ul>
     *
     * In order to make window inset dispatching work properly, we dispatch window insets
     * in the view hierarchy in a proper hierarchical manner and don't stop dispatching if the
     * insets are consumed if this flag is set to {@code false}.
     */
    static boolean sBrokenInsetsDispatch;
    /** @hide */
    @IntDef({NOT_FOCUSABLE, FOCUSABLE, FOCUSABLE_AUTO})
    @Retention(RetentionPolicy.SOURCE)
@@ -5108,6 +5128,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            sAcceptZeroSizeDragShadow = targetSdkVersion < Build.VERSION_CODES.P;
            sBrokenInsetsDispatch = !ViewRootImpl.USE_NEW_INSETS
                    || targetSdkVersion < Build.VERSION_CODES.Q;
            sCompatibilityDone = true;
        }
    }
+16 −0
Original line number Diff line number Diff line
@@ -7111,6 +7111,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    @Override
    public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
        insets = super.dispatchApplyWindowInsets(insets);
        if (View.sBrokenInsetsDispatch) {
            return brokenDispatchApplyWindowInsets(insets);
        } else {
            return newDispatchApplyWindowInsets(insets);
        }
    }

    private WindowInsets brokenDispatchApplyWindowInsets(WindowInsets insets) {
        if (!insets.isConsumed()) {
            final int count = getChildCount();
            for (int i = 0; i < count; i++) {
@@ -7123,6 +7131,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        return insets;
    }

    private WindowInsets newDispatchApplyWindowInsets(WindowInsets insets) {
        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            getChildAt(i).dispatchApplyWindowInsets(insets);
        }
        return insets;
    }

    /**
     * Returns the animation listener to which layout animation events are
     * sent.