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

Commit 24a0b71a authored by Ken Wakasa's avatar Ken Wakasa Committed by Android (Google) Code Review
Browse files

Merge "Clip touch event at SoftInputWindow to handle the event from Inset" into honeycomb

parents 03855bbe 7bd6c20f
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -19,11 +19,16 @@ package android.inputmethodservice;
import android.app.Dialog;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
import android.os.IBinder;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import java.lang.Math;

/**
 * A SoftInputWindow is a Dialog that is intended to be used for a top-level input
 * method window.  It will be displayed along the edge of the screen, moving
@@ -32,6 +37,7 @@ import android.view.WindowManager;
 */
class SoftInputWindow extends Dialog {
    final KeyEvent.DispatcherState mDispatcherState;
    private final Rect mBounds = new Rect();
    
    public void setToken(IBinder token) {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
@@ -64,6 +70,13 @@ class SoftInputWindow extends Dialog {
        mDispatcherState.reset();
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        getWindow().getDecorView().getHitRect(mBounds);
        final MotionEvent event = clipMotionEvent(ev, mBounds);
        return super.dispatchTouchEvent(event);
    }

    /**
     * Get the size of the DockWindow.
     * 
@@ -150,4 +163,48 @@ class SoftInputWindow extends Dialog {
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    }

    private static MotionEvent clipMotionEvent(MotionEvent me, Rect bounds) {
        final int pointerCount = me.getPointerCount();
        boolean shouldClip = false;
        for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
            final int x = (int)me.getX(pointerIndex);
            final int y = (int)me.getY(pointerIndex);
            if (!bounds.contains(x, y)) {
                shouldClip = true;
                break;
            }
        }
        if (!shouldClip)
            return me;

        if (pointerCount == 1) {
            final int x = (int)me.getX();
            final int y = (int)me.getY();
            me.setLocation(
                    Math.max(bounds.left, Math.min(x, bounds.right - 1)),
                    Math.max(bounds.top, Math.min(y, bounds.bottom - 1)));
            return me;
        }

        final int[] pointerIds = new int[pointerCount];
        final MotionEvent.PointerCoords[] pointerCoords =
            new MotionEvent.PointerCoords[pointerCount];
        for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
            pointerIds[pointerIndex] = me.getPointerId(pointerIndex);
            final MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
            me.getPointerCoords(pointerIndex, coords);
            pointerCoords[pointerIndex] = coords;
            final int x = (int)coords.x;
            final int y = (int)coords.y;
            if (!bounds.contains(x, y)) {
                coords.x = Math.max(bounds.left, Math.min(x, bounds.right - 1));
                coords.y = Math.max(bounds.top, Math.min(y, bounds.bottom - 1));
            }
        }
        return MotionEvent.obtain(
                me.getDownTime(), me.getEventTime(), me.getAction(), pointerCount, pointerIds,
                pointerCoords, me.getMetaState(), me.getXPrecision(), me.getYPrecision(),
                me.getDeviceId(), me.getEdgeFlags(), me.getSource(), me.getFlags());
    }
}