diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 7396f0518fe9c633268c3530b59285f45954be17..24e8926c5c1dd91e8966372d97be9b26c4b7196f 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -196,8 +196,8 @@ public class Key {
         }
 
         // Horizontal gap is divided equally to both sides of the key.
-        this.mX = x + mGap / 2;
-        this.mY = y;
+        mX = x + mGap / 2;
+        mY = y;
 
         final TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
                 R.styleable.Keyboard_Key);
@@ -350,12 +350,13 @@ public class Key {
         final boolean rightEdge = (flags & Keyboard.EDGE_RIGHT) != 0;
         final boolean topEdge = (flags & Keyboard.EDGE_TOP) != 0;
         final boolean bottomEdge = (flags & Keyboard.EDGE_BOTTOM) != 0;
-        final int left = this.mX;
-        final int right = left + this.mWidth;
-        final int top = this.mY;
-        final int bottom = top + this.mHeight;
-        return (x >= left || leftEdge) && (x < right || rightEdge)
-                && (y >= top || topEdge) && (y < bottom || bottomEdge);
+        final int left = mX - mGap / 2;
+        final int right = left + mWidth + mGap;
+        final int top = mY;
+        final int bottom = top + mHeight + mKeyboard.getVerticalGap();
+        // In order to mitigate rounding errors, we use (left <= x <= right) here.
+        return (x >= left || leftEdge) && (x <= right || rightEdge)
+                && (y >= top || topEdge) && (y <= bottom || bottomEdge);
     }
 
     /**
@@ -365,10 +366,10 @@ public class Key {
      * @return the square of the distance of the point from the nearest edge of the key
      */
     public int squaredDistanceToEdge(int x, int y) {
-        final int left = this.mX;
-        final int right = left + this.mWidth;
-        final int top = this.mY;
-        final int bottom = top + this.mHeight;
+        final int left = mX;
+        final int right = left + mWidth;
+        final int top = mY;
+        final int bottom = top + mHeight;
         final int edgeX = x < left ? left : (x > right ? right : x);
         final int edgeY = y < top ? top : (y > bottom ? bottom : y);
         final int dx = x - edgeX;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 1a4f901950a135bc584f2397cd1a3111e91197bb..a7ede5f26ed8bfb88ff0ec86df0e25278846f470 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -81,11 +81,11 @@ public abstract class KeyDetector {
      *
      * @return Allocates and returns an array that can hold all key indices returned by
      *         {@link #getKeyIndexAndNearbyCodes} method. All elements in the returned array are
-     *         initialized by {@link #NOT_A_KEY} value.
+     *         initialized by {@link #NOT_A_CODE} value.
      */
     public int[] newCodeArray() {
         int[] codes = new int[getMaxNearbyKeys()];
-        Arrays.fill(codes, NOT_A_KEY);
+        Arrays.fill(codes, NOT_A_CODE);
         return codes;
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java b/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java
index c3fd1984b05b297f103561b4b4002ae27a7faee2..87f3e149760a9675d93021df810098989a217b1a 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java
@@ -45,13 +45,15 @@ public class ProximityKeyDetector extends KeyDetector {
      *
      * @param keyIndex index of the key.
      * @param distance distance between the key's edge and user touched point.
+     * @param isOnKey true if the point is on the key.
      * @return order of the key in the nearby buffer, 0 if it is the nearest key.
      */
-    private int sortNearbyKeys(int keyIndex, int distance) {
+    private int sortNearbyKeys(int keyIndex, int distance, boolean isOnKey) {
         final int[] distances = mDistances;
         final int[] indices = mIndices;
         for (int insertPos = 0; insertPos < distances.length; insertPos++) {
-            if (distance < distances[insertPos]) {
+            final int comparingDistance = distances[insertPos];
+            if (distance < comparingDistance || (distance == comparingDistance && isOnKey)) {
                 final int nextPos = insertPos + 1;
                 if (nextPos < distances.length) {
                     System.arraycopy(distances, insertPos, distances, nextPos,
@@ -103,7 +105,7 @@ public class ProximityKeyDetector extends KeyDetector {
             final boolean isInside = key.isInside(touchX, touchY);
             final int distance = key.squaredDistanceToEdge(touchX, touchY);
             if (isInside || (mProximityCorrectOn && distance < mProximityThresholdSquare)) {
-                final int insertedPosition = sortNearbyKeys(index, distance);
+                final int insertedPosition = sortNearbyKeys(index, distance, isInside);
                 if (insertedPosition == 0 && isInside)
                     primaryIndex = index;
             }