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

Commit 2b342f0a authored by Adam Powell's avatar Adam Powell
Browse files

Allow ViewGroup to split MotionEvents to multiple targets during dispatch.

Use the layout xml attribute splitMotionEvents="true" or the ViewGroup
method setMotionEventSplittingEnabled(true) to enable motion event
splitting. Rules for splitting are as follows:

* Splitting is enabled per ViewGroup. When splitting is enabled any
  MotionEvent dispatched to that ViewGroup can potentially be split
  into several and dispatched to children independently.

* Each pointer is assigned a target child view when the ACTION_DOWN or
  ACTION_POINTER_DOWN event is received. That will be the pointer's
  target until it goes up, the target returns false from onTouchEvent,
  or the MotionEvents are intercepted.

* Multiple pointers may be assigned to the same target. All pointer
  data sent to a target are bundled into a single MotionEvent. Child
  views do not need to be aware that splitting has occurred.

Change-Id: I993f838e2f6b455da9812f4742a016dfcd1c4cc9
parent 8a44bb23
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -8919,6 +8919,17 @@
 visibility="public"
>
</field>
<field name="splitMotionEvents"
 type="int"
 transient="false"
 volatile="false"
 value="16843567"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="src"
 type="int"
 transient="false"
@@ -199360,6 +199371,17 @@
 visibility="protected"
>
</method>
<method name="isMotionEventSplittingEnabled"
 return="boolean"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="measureChild"
 return="void"
 abstract="false"
@@ -199823,6 +199845,19 @@
<parameter name="animationListener" type="android.view.animation.Animation.AnimationListener">
</parameter>
</method>
<method name="setMotionEventSplittingEnabled"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="split" type="boolean">
</parameter>
</method>
<method name="setOnHierarchyChangeListener"
 return="void"
 abstract="false"
+1 −33
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package android.view;

import android.graphics.Camera;
import com.android.internal.R;
import com.android.internal.view.menu.MenuBuilder;

@@ -25,6 +24,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Interpolator;
import android.graphics.LinearGradient;
@@ -69,7 +69,6 @@ import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.ScrollBarDrawable;

import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -5418,37 +5417,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
        }
    }

    /**
     * This method detects whether the given event is inside the view and, if so,
     * handles it via the dispatchEvent(MotionEvent) method.
     *
     * @param ev The event that is being dispatched.
     * @param parentX The x location of the event in the parent's coordinates.
     * @param parentY The y location of the event in the parent's coordinates.
     * @return true if the event was inside this view, false otherwise.
     */
    boolean dispatchTouchEvent(MotionEvent ev, float parentX, float parentY) {
        float localX = parentX - mLeft;
        float localY = parentY - mTop;
        if (!hasIdentityMatrix() && mAttachInfo != null) {
            // non-identity matrix: transform the point into the view's coordinates
            final float[] localXY = mAttachInfo.mTmpTransformLocation;
            localXY[0] = localX;
            localXY[1] = localY;
            getInverseMatrix().mapPoints(localXY);
            localX = localXY[0];
            localY = localXY[1];
        }
        if (localX >= 0 && localY >= 0 && localX < (mRight - mLeft) && localY < (mBottom - mTop)) {
            // It would be safer to clone the event here but we don't for performance.
            // There are many subtle interactions in touch event dispatch; change at your own risk.
            mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
            ev.setLocation(localX, localY);
            return dispatchTouchEvent(ev);
        }
        return false;
    }

    /**
     * Utility method to determine whether the given point, in local coordinates,
     * is inside the view, where the area of the view is expanded by the slop factor.
+548 −1

File changed.

Preview size limit exceeded, changes collapsed.

+11 −0
Original line number Diff line number Diff line
@@ -1453,6 +1453,17 @@
            <enum name="blocksDescendants" value="2" />
        </attr>

        <!-- Sets whether this ViewGroup should split MotionEvents
             to separate child views during touch event dispatch.
             If false (default), touch events will be dispatched to
             the child view where the first pointer went down until
             the last pointer goes up.
             If true, touch events may be dispatched to multiple children.
             MotionEvents for each pointer will be dispatched to the child
             view where the initial ACTION_DOWN event happened.
             See {@link android.view.ViewGroup#setSplitMotionEvents(boolean)}
             for more information. -->
        <attr name="splitMotionEvents" format="boolean" />
    </declare-styleable>

    <!-- A {@link android.view.ViewStub} lets you lazily include other XML layouts
+1 −0
Original line number Diff line number Diff line
@@ -1324,6 +1324,7 @@
  <public type="attr" name="imeSubtypeLocale" />
  <public type="attr" name="imeSubtypeMode" />
  <public type="attr" name="imeSubtypeExtraValue" />
  <public type="attr" name="splitMotionEvents" />

  <public type="anim" name="animator_fade_in" />
  <public type="anim" name="animator_fade_out" />