From 5cd732f8c5de6f73529ccf71c942104292d2be46 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 17 Feb 2014 17:36:34 +0900 Subject: [PATCH] Stop overriding InputView.dispatchTouchEvent Bug: 11721001 Bug: 11976254 Change-Id: I950f13ec4084da7fd9c1c25fd7abed1e5d31ed4c --- .../android/inputmethod/latin/InputView.java | 117 ++++++++++-------- 1 file changed, 62 insertions(+), 55 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/InputView.java b/java/src/com/android/inputmethod/latin/InputView.java index 76b0912f6..ea7859e60 100644 --- a/java/src/com/android/inputmethod/latin/InputView.java +++ b/java/src/com/android/inputmethod/latin/InputView.java @@ -31,6 +31,7 @@ public final class InputView extends LinearLayout { private final Rect mInputViewRect = new Rect(); private KeyboardTopPaddingForwarder mKeyboardTopPaddingForwarder; private MoreSuggestionsViewCanceler mMoreSuggestionsViewCanceler; + private MotionEventForwarder mActiveForwarder; public InputView(final Context context, final AttributeSet attrs) { super(context, attrs, 0); @@ -53,42 +54,62 @@ public final class InputView extends LinearLayout { } @Override - public boolean dispatchTouchEvent(final MotionEvent me) { + public boolean onInterceptTouchEvent(final MotionEvent me) { final Rect rect = mInputViewRect; getGlobalVisibleRect(rect); - final int x = (int)me.getX() + rect.left; - final int y = (int)me.getY() + rect.top; + final int index = me.getActionIndex(); + final int x = (int)me.getX(index) + rect.left; + final int y = (int)me.getY(index) + rect.top; - // The touch events that hit the top padding of keyboard should be - // forwarded to {@link SuggestionStripView}. - if (mKeyboardTopPaddingForwarder.dispatchTouchEvent(x, y, me)) { + // The touch events that hit the top padding of keyboard should be forwarded to + // {@link SuggestionStripView}. + if (mKeyboardTopPaddingForwarder.onInterceptTouchEvent(x, y, me)) { + mActiveForwarder = mKeyboardTopPaddingForwarder; return true; } + // To cancel {@link MoreSuggestionsView}, we should intercept a touch event to // {@link MainKeyboardView} and dismiss the {@link MoreSuggestionsView}. - if (mMoreSuggestionsViewCanceler.dispatchTouchEvent(x, y, me)) { + if (mMoreSuggestionsViewCanceler.onInterceptTouchEvent(x, y, me)) { + mActiveForwarder = mMoreSuggestionsViewCanceler; return true; } - return super.dispatchTouchEvent(me); + + mActiveForwarder = null; + return false; + } + + @Override + public boolean onTouchEvent(final MotionEvent me) { + if (mActiveForwarder == null) { + return super.onTouchEvent(me); + } + + final Rect rect = mInputViewRect; + getGlobalVisibleRect(rect); + final int index = me.getActionIndex(); + final int x = (int)me.getX(index) + rect.left; + final int y = (int)me.getY(index) + rect.top; + return mActiveForwarder.onTouchEvent(x, y, me); } /** - * This class forwards series of {@link MotionEvent}s from Forwarder view to - * Receiver view. + * This class forwards series of {@link MotionEvent}s from SenderView to + * ReceiverView. * - * @param a {@link View} that may send a {@link MotionEvent} to . - * @param a {@link View} that receives forwarded {@link MotionEvent} from - * . + * @param a {@link View} that may send a {@link MotionEvent} to . + * @param a {@link View} that receives forwarded {@link MotionEvent} from + * . */ - private static abstract class MotionEventForwarder { - protected final Sender mSenderView; - protected final Receiver mReceiverView; + private static abstract class + MotionEventForwarder { + protected final SenderView mSenderView; + protected final ReceiverView mReceiverView; - private boolean mIsForwardingEvent; protected final Rect mEventSendingRect = new Rect(); protected final Rect mEventReceivingRect = new Rect(); - public MotionEventForwarder(final Sender senderView, final Receiver receiverView) { + public MotionEventForwarder(final SenderView senderView, final ReceiverView receiverView) { mSenderView = senderView; mReceiverView = receiverView; } @@ -96,12 +117,12 @@ public final class InputView extends LinearLayout { // Return true if a touch event of global coordinate x, y needs to be forwarded. protected abstract boolean needsToForward(final int x, final int y); - // Translate global x-coordinate to Receiver local coordinate. + // Translate global x-coordinate to ReceiverView local coordinate. protected int translateX(final int x) { return x - mEventReceivingRect.left; } - // Translate global y-coordinate to Receiver local coordinate. + // Translate global y-coordinate to ReceiverView local coordinate. protected int translateY(final int y) { return y - mEventReceivingRect.top; } @@ -109,49 +130,36 @@ public final class InputView extends LinearLayout { // Callback when a {@link MotionEvent} is forwarded. protected void onForwardingEvent(final MotionEvent me) {} - // Dispatches a {@link MotioneEvent} to Receiver if needed and returns true. - // Otherwise returns false. - public boolean dispatchTouchEvent(final int x, final int y, final MotionEvent me) { - // Forwards a {link MotionEvent} only if both Sender and - // Receiver are visible. + // Returns true if a {@link MotionEvent} is needed to be forwarded to + // ReceiverView. Otherwise returns false. + public boolean onInterceptTouchEvent(final int x, final int y, final MotionEvent me) { + // Forwards a {link MotionEvent} only if both SenderView and + // ReceiverView are visible. if (mSenderView.getVisibility() != View.VISIBLE || mReceiverView.getVisibility() != View.VISIBLE) { return false; } - final Rect sendingRect = mEventSendingRect; - mSenderView.getGlobalVisibleRect(sendingRect); - if (!mIsForwardingEvent && !sendingRect.contains(x, y)) { + mSenderView.getGlobalVisibleRect(mEventSendingRect); + if (!mEventSendingRect.contains(x, y)) { return false; } - boolean shouldForwardToReceiver = false; - - switch (me.getActionMasked()) { - case MotionEvent.ACTION_DOWN: - // If the down event happens in the forwarding area, successive {@link MotionEvent}s - // should be forwarded. + if (me.getActionMasked() == MotionEvent.ACTION_DOWN) { + // If the down event happens in the forwarding area, successive + // {@link MotionEvent}s should be forwarded to ReceiverView. if (needsToForward(x, y)) { - mIsForwardingEvent = true; - shouldForwardToReceiver = true; + return true; } - break; - case MotionEvent.ACTION_MOVE: - shouldForwardToReceiver = mIsForwardingEvent; - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - shouldForwardToReceiver = mIsForwardingEvent; - mIsForwardingEvent = false; - break; } - if (!shouldForwardToReceiver) { - return false; - } + return false; + } - final Rect receivingRect = mEventReceivingRect; - mReceiverView.getGlobalVisibleRect(receivingRect); - // Translate global coordinates to Receiver local coordinates. + // Returns true if a {@link MotionEvent} is forwarded to ReceiverView. + // Otherwise returns false. + public boolean onTouchEvent(final int x, final int y, final MotionEvent me) { + mReceiverView.getGlobalVisibleRect(mEventReceivingRect); + // Translate global coordinates to ReceiverView local coordinates. me.setLocation(translateX(x), translateY(y)); mReceiverView.dispatchTouchEvent(me); onForwardingEvent(me); @@ -189,8 +197,7 @@ public final class InputView extends LinearLayout { protected int translateY(final int y) { final int translatedY = super.translateY(y); if (isInKeyboardTopPadding(y)) { - // The forwarded event should have coordinates that are inside of - // the target. + // The forwarded event should have coordinates that are inside of the target. return Math.min(translatedY, mEventReceivingRect.height() - 1); } return translatedY; @@ -200,8 +207,8 @@ public final class InputView extends LinearLayout { /** * This class forwards {@link MotionEvent}s happened in the {@link MainKeyboardView} to * {@link SuggestionStripView} when the {@link MoreSuggestionsView} is showing. - * {@link SuggestionStripView} dismisses {@link MoreSuggestionsView} when it receives those - * events. + * {@link SuggestionStripView} dismisses {@link MoreSuggestionsView} when it receives any event + * outside of it. */ private static class MoreSuggestionsViewCanceler extends MotionEventForwarder {