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

Commit 45bee6b2 authored by Vadim Tryshev's avatar Vadim Tryshev
Browse files

For pre-N apps, cascade LOCATION and DROP events.

To restore the pre-N behavior, if a view returns false from its
LOCATION or DROP event handler, the event goes to its parent.

Bug: 31559942
Change-Id: I322099ae1e8a5cbbcf8814f2cd274fbae53b6848
parent ef128115
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -829,6 +829,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    protected static boolean sPreserveMarginParamsInLayoutParamConversion;
    /**
     * Prior to N, when drag enters into child of a view that has already received an
     * ACTION_DRAG_ENTERED event, the parent doesn't get a ACTION_DRAG_EXITED event.
     * ACTION_DRAG_LOCATION and ACTION_DROP were delivered to the parent of a view that returned
     * false from its event handler for these events.
     * Starting from N, the parent will get ACTION_DRAG_EXITED event before the child gets its
     * ACTION_DRAG_ENTERED. ACTION_DRAG_LOCATION and ACTION_DROP are never propagated to the parent.
     * sCascadedDragDrop is true for pre-N apps for backwards compatibility implementation.
     */
    static boolean sCascadedDragDrop;
    /**
     * This view does not want keystrokes. Use with TAKES_FOCUS_MASK when
     * calling setFlags.
@@ -4065,6 +4076,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            // in apps so we target check it to avoid breaking existing apps.
            sPreserveMarginParamsInLayoutParamConversion = targetSdkVersion >= N;
            sCascadedDragDrop = targetSdkVersion < N;
            sCompatibilityDone = true;
        }
    }
+12 −5
Original line number Diff line number Diff line
@@ -1451,7 +1451,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            View target = findFrontmostDroppableChildAt(event.mX, event.mY, localPoint);

            if (target != mCurrentDragChild) {
                if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) {
                if (sCascadedDragDrop) {
                    // For pre-Nougat apps, make sure that the whole hierarchy of views that contain
                    // the drag location is kept in the state between ENTERED and EXITED events.
                    // (Starting with N, only the innermost view will be in that state).
@@ -1494,11 +1494,18 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                    event.mX = tx;
                    event.mY = ty;

                    if (!event.mEventHandlerWasCalled && mIsInterestedInDrag) {
                        // The child didn't invoke any event handler, but this view is interested in
                        // drag, so the event goes to this view.
                    if (mIsInterestedInDrag) {
                        final boolean eventWasConsumed;
                        if (sCascadedDragDrop) {
                            eventWasConsumed = retval;
                        } else {
                            eventWasConsumed = event.mEventHandlerWasCalled;
                        }

                        if (!eventWasConsumed) {
                            retval = super.dispatchDragEvent(event);
                        }
                    }
                } else {
                    retval = super.dispatchDragEvent(event);
                }
+2 −2
Original line number Diff line number Diff line
@@ -5524,7 +5524,7 @@ public final class ViewRootImpl implements ViewParent,
                // A direct EXITED event means that the window manager knows we've just crossed
                // a window boundary, so the current drag target within this one must have
                // just been exited. Send the EXITED notification to the current drag view, if any.
                if (mTargetSdkVersion < Build.VERSION_CODES.N) {
                if (View.sCascadedDragDrop) {
                    mView.dispatchDragEnterExitInPreN(event);
                }
                setDragFocus(null, event);
@@ -5644,7 +5644,7 @@ public final class ViewRootImpl implements ViewParent,
    }

    public void setDragFocus(View newDragTarget, DragEvent event) {
        if (mCurrentDragView != newDragTarget && mTargetSdkVersion >= Build.VERSION_CODES.N) {
        if (mCurrentDragView != newDragTarget && !View.sCascadedDragDrop) {
            // Send EXITED and ENTERED notifications to the old and new drag focus views.

            final float tx = event.mX;