From a0537fb4c73dff8beecc328720830af9719d0277 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka" <takaoka@google.com>
Date: Fri, 22 Apr 2011 21:05:30 +0900
Subject: [PATCH] Fix repeat key behavior

Change-Id: Ia7e5b2e9579aa0e5050857cdb14f16fa05a33621
---
 java/res/values/config.xml                    |  4 +--
 .../inputmethod/keyboard/KeyboardView.java    | 22 ++++++++-----
 .../inputmethod/keyboard/PointerTracker.java  | 32 +++++++++++++------
 3 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index a1cd70b1bd..4651de7854 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -49,9 +49,9 @@
     <!-- Showing mini keyboard, just above the touched point if true, aligned to the key if false -->
     <bool name="config_show_mini_keyboard_at_touched_point">false</bool>
     <!-- The language is never displayed if == 0, always displayed if < 0 -->
-    <integer name="config_delay_before_fadeout_language_on_spacebar">-1</integer>
+    <integer name="config_delay_before_fadeout_language_on_spacebar">1200</integer>
     <integer name="config_duration_of_fadeout_language_on_spacebar">50</integer>
-    <integer name="config_final_fadeout_percentage_of_language_on_spacebar">15</integer>
+    <integer name="config_final_fadeout_percentage_of_language_on_spacebar">50</integer>
     <integer name="config_delay_before_preview">0</integer>
     <integer name="config_delay_after_preview">60</integer>
     <integer name="config_mini_keyboard_fadein_anim_time">0</integer>
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 95ecb3bc92..c368952584 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -139,6 +139,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
 
     private final boolean mHasDistinctMultitouch;
     private int mOldPointerCount = 1;
+    private int mOldKeyIndex;
 
     // Accessibility
     private boolean mIsAccessibilityEnabled;
@@ -202,7 +203,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
                     break;
                 case MSG_REPEAT_KEY: {
                     final PointerTracker tracker = (PointerTracker)msg.obj;
-                    tracker.repeatKey(msg.arg1);
+                    tracker.onRepeatKey(msg.arg1);
                     startKeyRepeatTimer(mKeyRepeatInterval, msg.arg1, tracker);
                     break;
                 }
@@ -1270,10 +1271,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         }
 
         if (mHandler.isInKeyRepeat()) {
-            // It will keep being in the key repeating mode while the key is being pressed.
-            if (action == MotionEvent.ACTION_MOVE) {
-                return true;
-            }
             final PointerTracker tracker = getPointerTracker(id);
             // Key repeating timer will be canceled if 2 or more keys are in action, and current
             // event (UP or DOWN) is non-modifier key.
@@ -1291,12 +1288,21 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             PointerTracker tracker = getPointerTracker(0);
             if (pointerCount == 1 && oldPointerCount == 2) {
                 // Multi-touch to single touch transition.
-                // Send a down event for the latest pointer.
-                tracker.onDownEvent(x, y, eventTime, null);
+                // Send a down event for the latest pointer if the key is different from the
+                // previous key.
+                final int newKeyIndex = tracker.getKeyIndexOn(x, y);
+                if (mOldKeyIndex != newKeyIndex) {
+                    tracker.onDownEvent(x, y, eventTime, null);
+                    if (action == MotionEvent.ACTION_UP)
+                        tracker.onUpEvent(x, y, eventTime, null);
+                }
             } else if (pointerCount == 2 && oldPointerCount == 1) {
                 // Single-touch to multi-touch transition.
                 // Send an up event for the last pointer.
-                tracker.onUpEvent(tracker.getLastX(), tracker.getLastY(), eventTime, null);
+                final int lastX = tracker.getLastX();
+                final int lastY = tracker.getLastY();
+                mOldKeyIndex = tracker.getKeyIndexOn(lastX, lastY);
+                tracker.onUpEvent(lastX, lastY, eventTime, null);
             } else if (pointerCount == 1 && oldPointerCount == 1) {
                 tracker.onTouchEvent(action, x, y, eventTime, null);
             } else {
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index d975b39b93..e3161f6107 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -251,6 +251,10 @@ public class PointerTracker {
         return key != null && key.mCode == Keyboard.CODE_SHIFT;
     }
 
+    public int getKeyIndexOn(int x, int y) {
+        return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
+    }
+
     public boolean isSpaceKey(int keyIndex) {
         Key key = getKey(keyIndex);
         return key != null && key.mCode == Keyboard.CODE_SPACE;
@@ -355,14 +359,7 @@ public class PointerTracker {
             if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex), false))
                 keyIndex = mKeyState.onDownKey(x, y, eventTime);
 
-            // Accessibility disables key repeat because users may need to pause on a key to hear
-            // its spoken description.
-            final Key key = getKey(keyIndex);
-            if (key != null && key.mRepeatable && !mIsAccessibilityEnabled) {
-                repeatKey(keyIndex);
-                mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this);
-                mIsRepeatableKey = true;
-            }
+            startRepeatKey(keyIndex);
             startLongPressTimer(keyIndex);
             showKeyPreview(keyIndex);
             setPressedKeyGraphics(keyIndex);
@@ -414,7 +411,8 @@ public class PointerTracker {
                 setReleasedKeyGraphics(oldKeyIndex);
                 callListenerOnRelease(oldKey, oldKey.mCode, true);
                 startSlidingKeyInput(oldKey);
-                mHandler.cancelLongPressTimers();
+                mHandler.cancelKeyTimers();
+                startRepeatKey(keyIndex);
                 if (mIsAllowedSlidingKeyInput) {
                     // This onPress call may have changed keyboard layout. Those cases are detected
                     // at {@link #setKeyboard}. In those cases, we should update keyIndex according
@@ -576,7 +574,21 @@ public class PointerTracker {
         mIsInSlidingKeyInput = false;
     }
 
-    public void repeatKey(int keyIndex) {
+    private void startRepeatKey(int keyIndex) {
+        // Accessibility disables key repeat because users may need to pause on a key to hear
+        // its spoken description.
+        final Key key = getKey(keyIndex);
+        if (key != null && key.mRepeatable && !mIsAccessibilityEnabled) {
+            dismissKeyPreview();
+            onRepeatKey(keyIndex);
+            mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this);
+            mIsRepeatableKey = true;
+        } else {
+            mIsRepeatableKey = false;
+        }
+    }
+
+    public void onRepeatKey(int keyIndex) {
         Key key = getKey(keyIndex);
         if (key != null) {
             detectAndSendKey(keyIndex, key.mX, key.mY);
-- 
GitLab