From 327763e5181fe73a1d6d806a57e2456c84159f2a Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka" <takaoka@google.com>
Date: Mon, 30 May 2011 20:05:50 +0900
Subject: [PATCH] Adaptive keyboard width/position parser

This change introduces the following features to Keyboard XML format.

 * "keyXPos" can specify the key X coordinate directly.
 * "keyXPos" can be negative. The X coordinate will be calcluated from
    the right edge of the keyboard toward left.
 * "keyWidth" can be zero to be filled up to the right side.
 * "keyWidth can be negative. The key will be filled up to both sides.
 * Spacer's horizontalGap is renamed as keyWidth, and can be inherited
   from key-style.
 * Spacer can have keyXPos attribute.

Using these syntax, all keyboard layouts have been re-written.

Cherry-Pick: I314b2e8ca2aa145ff9506cbf927140a15685af42
Bug: 4442045
Change-Id: I048fe5eaef020d8472ab577e9d326042bae2f3fa
---
 java/res/values/attrs.xml                     |  15 ++-
 java/res/xml-sw768dp/kbd_ar_rows.xml          |  24 ++--
 java/res/xml-sw768dp/kbd_azerty_rows.xml      |  19 +--
 java/res/xml-sw768dp/kbd_iw_rows.xml          |  19 +--
 java/res/xml-sw768dp/kbd_number.xml           | 112 +++++++---------
 java/res/xml-sw768dp/kbd_phone.xml            |  75 +++++------
 java/res/xml-sw768dp/kbd_phone_symbols.xml    |  83 +++++-------
 java/res/xml-sw768dp/kbd_qwerty_row1.xml      |   7 +-
 java/res/xml-sw768dp/kbd_qwerty_row2.xml      |   7 +-
 java/res/xml-sw768dp/kbd_qwerty_row3.xml      |   7 +-
 java/res/xml-sw768dp/kbd_qwerty_row4.xml      |  21 +--
 .../kbd_qwerty_rows_scandinavia.xml           |  14 +-
 java/res/xml-sw768dp/kbd_qwertz_rows.xml      |  14 +-
 java/res/xml-sw768dp/kbd_ru_rows.xml          |  46 +++----
 java/res/xml-sw768dp/kbd_sr_rows.xml          |  51 ++++---
 java/res/xml-sw768dp/kbd_symbols.xml          |  42 +++---
 java/res/xml-sw768dp/kbd_symbols_shift.xml    |  39 +++---
 java/res/xml/kbd_ar_rows.xml                  |   5 +-
 java/res/xml/kbd_azerty_rows.xml              |   4 +-
 java/res/xml/kbd_iw_rows.xml                  |  10 +-
 java/res/xml/kbd_key_styles.xml               |  14 +-
 java/res/xml/kbd_number.xml                   |  18 ++-
 java/res/xml/kbd_phone.xml                    |   8 +-
 java/res/xml/kbd_phone_symbols.xml            |   8 +-
 java/res/xml/kbd_qwerty_row1.xml              |   1 +
 java/res/xml/kbd_qwerty_row2.xml              |   4 +-
 java/res/xml/kbd_qwerty_row3.xml              |   2 +-
 java/res/xml/kbd_qwerty_row4.xml              | 124 +++++++-----------
 java/res/xml/kbd_qwerty_rows_scandinavia.xml  |   4 +-
 java/res/xml/kbd_qwertz_rows.xml              |   3 +-
 java/res/xml/kbd_ru_rows.xml                  |   6 +-
 java/res/xml/kbd_sr_rows.xml                  |   4 +-
 java/res/xml/kbd_symbols.xml                  |   4 +-
 java/res/xml/kbd_symbols_row4.xml             |  89 ++++++-------
 java/res/xml/kbd_symbols_shift.xml            |   4 +-
 java/res/xml/kbd_symbols_shift_row4.xml       |  81 +++++-------
 .../com/android/inputmethod/keyboard/Key.java |  45 ++++++-
 .../inputmethod/keyboard/KeyboardId.java      |   2 +-
 .../inputmethod/keyboard/KeyboardParser.java  |  54 +++++---
 39 files changed, 537 insertions(+), 552 deletions(-)

diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index feb955e860..7473b42ec0 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -94,8 +94,16 @@
         <!-- Minimum keyboard height represented in pixels, percentage of display height if fraction
              is positive, or percentage of display width if fraction is negative. -->
         <attr name="minKeyboardHeight" format="dimension|fraction" />
-        <!-- Default width of a key, in pixels or percentage of display width. -->
-        <attr name="keyWidth" format="dimension|fraction" />
+        <!-- Default width of a key, in pixels or percentage of display width.
+             If the value is zero, the actual key width will be determined to fill out the area up
+             to the right edge of the keyboard.
+             If the value is negative, the actual key width will be determined to fill out the
+             area between the nearest key on the left hand side and the right edge of the keyboard.
+             -->
+        <attr name="keyWidth" format="dimension|fraction|enum">
+            <enum name="fillRight" value="0" />
+            <enum name="fillBoth" value="-1" />
+        </attr>
         <!-- Default height of a row (key height + vertical gap), in pixels or percentage of
              keyboard height. -->
         <attr name="rowHeight" format="dimension|fraction" />
@@ -161,6 +169,9 @@
         <!-- Visual insets -->
         <attr name="visualInsetsLeft" format="dimension|fraction" />
         <attr name="visualInsetsRight" format="dimension|fraction" />
+        <!-- The X-coordinate of upper right corner of this key including horizontal gap.
+             If the value is negative, the origin is the right edge of the keyboard. -->
+        <attr name="keyXPos" format="dimension|fraction" />
     </declare-styleable>
 
     <declare-styleable name="Keyboard_Row">
diff --git a/java/res/xml-sw768dp/kbd_ar_rows.xml b/java/res/xml-sw768dp/kbd_ar_rows.xml
index e84aae6b59..daaa38e4d9 100644
--- a/java/res/xml-sw768dp/kbd_ar_rows.xml
+++ b/java/res/xml-sw768dp/kbd_ar_rows.xml
@@ -27,12 +27,12 @@
     <include
         latin:keyboardLayout="@xml/kbd_key_styles" />
     <Row
-        latin:keyWidth="7.49%p"
+        latin:keyWidth="7.579%p"
     >
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="ض" />
@@ -61,16 +61,17 @@
             latin:popupCharacters="ج,چ" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="9.331%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="7.49%p"
+        latin:keyWidth="7.500%p"
     >
         <Key
             latin:keyStyle="toSymbolKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="9.219%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="Ø´" />
@@ -100,15 +101,19 @@
             latin:keyLabel="Ø·" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="8.593%p"
+            latin:keyXPos="-15.704%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.042%p"
+        latin:keyWidth="7.500%p"
     >
         <Key
-            latin:keyLabel="ئ"
+            latin:keyStyle="shiftKeyStyle"
+            latin:keyWidth="9.219%p"
             latin:keyEdgeFlags="left" />
+        <Key
+            latin:keyLabel="ئ" />
         <Key
             latin:keyLabel="Ø¡" />
         <Key
@@ -132,7 +137,8 @@
             latin:keyLabel="د" />
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="11.736%p"
+            latin:keyXPos="-13.750%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
diff --git a/java/res/xml-sw768dp/kbd_azerty_rows.xml b/java/res/xml-sw768dp/kbd_azerty_rows.xml
index 564f776290..5288ccf91d 100644
--- a/java/res/xml-sw768dp/kbd_azerty_rows.xml
+++ b/java/res/xml-sw768dp/kbd_azerty_rows.xml
@@ -24,12 +24,12 @@
     <include
         latin:keyboardLayout="@xml/kbd_key_styles" />
     <Row
-        latin:keyWidth="8.272%p"
+        latin:keyWidth="8.282%p"
     >
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="a"
@@ -63,11 +63,12 @@
             latin:popupCharacters="@string/alternates_for_p" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="9.331%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.157%p"
+        latin:keyWidth="8.125%p"
     >
         <Key
             latin:keyStyle="toSymbolKeyStyle"
@@ -103,15 +104,16 @@
             latin:keyEdgeFlags="right" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="8.593%p"
+            latin:keyXPos="-15.704%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.042%p"
+        latin:keyWidth="8.047%p"
     >
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="15.192%p"
+            latin:keyWidth="13.829%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="w"
@@ -161,7 +163,8 @@
         </switch>
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="12.530%p"
+            latin:keyXPos="-13.750%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <include
diff --git a/java/res/xml-sw768dp/kbd_iw_rows.xml b/java/res/xml-sw768dp/kbd_iw_rows.xml
index a3a239dbf6..33263f576c 100644
--- a/java/res/xml-sw768dp/kbd_iw_rows.xml
+++ b/java/res/xml-sw768dp/kbd_iw_rows.xml
@@ -24,12 +24,12 @@
     <include
         latin:keyboardLayout="@xml/kbd_key_styles" />
     <Row
-        latin:keyWidth="8.272%p"
+        latin:keyWidth="8.282%p"
     >
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="," />
@@ -53,11 +53,12 @@
             latin:keyLabel="פ" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="9.331%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.157%p"
+        latin:keyWidth="8.125%p"
     >
         <Key
             latin:keyStyle="toSymbolKeyStyle"
@@ -89,15 +90,16 @@
             latin:keyLabel="×£" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="8.593%p"
+            latin:keyXPos="-15.704%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.042%p"
+        latin:keyWidth="8.047%p"
     >
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="15.192%p"
+            latin:keyWidth="13.829%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="×–"
@@ -123,7 +125,8 @@
             latin:popupCharacters="ץ,ץ׳" />
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="12.530%p"
+            latin:keyXPos="-13.750%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
diff --git a/java/res/xml-sw768dp/kbd_number.xml b/java/res/xml-sw768dp/kbd_number.xml
index 7cb77ea001..01c41a50c7 100644
--- a/java/res/xml-sw768dp/kbd_number.xml
+++ b/java/res/xml-sw768dp/kbd_number.xml
@@ -24,7 +24,7 @@
     latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
     latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
-    latin:keyWidth="11.949%p"
+    latin:keyWidth="11.954%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
@@ -40,42 +40,42 @@
         >
             <!-- This row is intentionally not marked as a top row -->
             <Row>
-                <Spacer
-                    latin:horizontalGap="32.076%p" />
                 <Key
-                    latin:keyStyle="num1KeyStyle" />
+                    latin:keyStyle="tabKeyStyle"
+                    latin:keyLabelOption="alignLeft"
+                    latin:keyWidth="7.969%p"
+                    latin:keyEdgeFlags="left" />
+                <Key
+                    latin:keyStyle="num1KeyStyle"
+                    latin:keyXPos="32.076%p" />
                 <Key
                     latin:keyStyle="num2KeyStyle" />
                 <Key
                     latin:keyStyle="num3KeyStyle" />
-                <Spacer
-                    latin:horizontalGap="22.272%p" />
                 <Key
                     latin:keyStyle="deleteKeyStyle"
-                    latin:keyWidth="9.804%p"
+                    latin:keyXPos="-9.219%p"
+                    latin:keyWidth="fillRight"
                     latin:keyEdgeFlags="right" />
             </Row>
             <Row>
-                <Spacer
-                    latin:horizontalGap="32.076%p" />
                 <Key
-                    latin:keyStyle="num4KeyStyle" />
+                    latin:keyStyle="num4KeyStyle"
+                    latin:keyXPos="32.076%p" />
                 <Key
                     latin:keyStyle="num5KeyStyle" />
                 <Key
                     latin:keyStyle="num6KeyStyle" />
-                <Spacer
-                    latin:horizontalGap="17.371%p" />
                 <Key
                     latin:keyStyle="returnKeyStyle"
-                    latin:keyWidth="14.706%p"
+                    latin:keyXPos="-15.704%p"
+                    latin:keyWidth="fillRight"
                     latin:keyEdgeFlags="right" />
             </Row>
             <Row>
-                <Spacer
-                    latin:horizontalGap="32.076%p" />
                 <Key
-                    latin:keyStyle="num7KeyStyle" />
+                    latin:keyStyle="num7KeyStyle"
+                    latin:keyXPos="32.076%p" />
                 <Key
                     latin:keyStyle="num8KeyStyle" />
                 <Key
@@ -87,7 +87,7 @@
             <!-- This row is intentionally not marked as a bottom row -->
             <Row>
                 <Spacer
-                    latin:horizontalGap="44.026%p" />
+                    latin:keyXPos="32.076%p" />
                 <Key
                     latin:keyStyle="num0KeyStyle" />
                 <!-- There is an empty area below the "Enter" key and right of the "#" key. To
@@ -102,79 +102,72 @@
                 <Key
                     latin:keyStyle="tabKeyStyle"
                     latin:keyLabelOption="alignLeft"
+                    latin:keyWidth="7.969%p"
                     latin:keyEdgeFlags="left" />
-                <Spacer
-                    latin:horizontalGap="4.458%p" />
                 <Key
                     latin:keyLabel="-"
-                    latin:keyWidth="8.042%p" />
+                    latin:keyXPos="13.829%p"
+                    latin:keyWidth="8.047%p" />
                 <Key
                     latin:keyLabel="+"
-                    latin:keyWidth="8.042%p" />
+                    latin:keyWidth="8.047%p" />
                 <Key
                     latin:keyLabel="."
-                    latin:keyWidth="8.042%p" />
-                <Spacer
-                    latin:horizontalGap="4.458%p" />
+                    latin:keyWidth="8.047%p" />
                 <Key
-                    latin:keyLabel="1" />
+                    latin:keyLabel="1"
+                    latin:keyXPos="45.000%p" />
                 <Key
                     latin:keyLabel="2" />
                 <Key
                     latin:keyLabel="3" />
-                <Spacer
-                    latin:horizontalGap="9.360%p" />
                 <Key
                     latin:keyStyle="deleteKeyStyle"
-                    latin:keyWidth="9.804%p"
+                    latin:keyXPos="-9.219%p"
+                    latin:keyWidth="fillRight"
                     latin:keyEdgeFlags="right" />
             </Row>
             <Row>
-                <Spacer
-                    latin:horizontalGap="16.406%p" />
                 <Key
                     latin:keyLabel="*"
-                    latin:keyWidth="8.042%p" />
+                    latin:keyXPos="13.829%p"
+                    latin:keyWidth="8.047%p" />
                 <Key
                     latin:keyLabel="/"
-                    latin:keyWidth="8.042%p" />
+                    latin:keyWidth="8.047%p" />
                 <Key
                     latin:keyLabel=","
-                    latin:keyWidth="8.042%p" />
-                <Spacer
-                    latin:horizontalGap="4.458%p" />
+                    latin:keyWidth="8.047%p" />
                 <Key
-                    latin:keyLabel="4" />
+                    latin:keyLabel="4"
+                    latin:keyXPos="45.000%p" />
                 <Key
                     latin:keyLabel="5" />
                 <Key
                     latin:keyLabel="6" />
-                <Spacer
-                    latin:horizontalGap="4.458%p" />
                 <Key
                     latin:keyStyle="returnKeyStyle"
-                    latin:keyWidth="14.706%p"
+                    latin:keyXPos="-15.704%p"
+                    latin:keyWidth="fillRight"
                     latin:keyEdgeFlags="right" />
             </Row>
             <Row>
                 <!-- There is an empty area below the "More" key and left of the "(" key. To
                      ignore the touch event on the area, "(" is intentionally not marked as a left
                      edge key. -->
-                <Spacer
-                    latin:horizontalGap="16.406%p" />
                 <Key
                     latin:keyLabel="("
-                    latin:keyWidth="8.042%p" />
+                    latin:keyXPos="13.829%p"
+                    latin:keyWidth="8.047%p" />
                 <Key
                     latin:keyLabel=")"
-                    latin:keyWidth="8.042%p" />
+                    latin:keyWidth="8.047%p" />
                 <Key
                     latin:keyLabel="="
-                    latin:keyWidth="8.042%p" />
-                <Spacer
-                    latin:horizontalGap="4.458%p" />
+                    latin:keyWidth="8.047%p" />
                 <Key
-                    latin:keyLabel="7" />
+                    latin:keyLabel="7"
+                    latin:keyXPos="45.000%p" />
                 <Key
                     latin:keyLabel="8" />
                 <Key
@@ -185,29 +178,20 @@
             </Row>
             <!-- This row is intentionally not marked as a bottom row -->
             <Row>
-                <!-- There is an empty area below the "More" key and left of the "space" key. To
-                     ignore the touch event on the area, "space" is intentionally not marked as a
-                     left edge key. -->
-                <Spacer
-                    latin:horizontalGap="8.362%p" />
                 <switch>
                     <case latin:hasSettingsKey="true">
                         <Key
                             latin:keyStyle="settingsKeyStyle"
-                            latin:keyWidth="8.042%p" />
+                            latin:keyWidth="8.047%p" />
                     </case>
-                    <default>
-                        <Spacer
-                            latin:horizontalGap="8.042%p" />
-                    </default>
                 </switch>
                 <Key
                     latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
-                    latin:keyWidth="24.127%p" />
-                <Spacer
-                    latin:horizontalGap="4.458%p" />
+                    latin:keyXPos="13.829%p"
+                    latin:keyWidth="24.140%p" />
                 <Key
-                    latin:keyLabel="*" />
+                    latin:keyLabel="*"
+                    latin:keyXPos="45.000%p" />
                 <Key
                     latin:keyLabel="0" />
                 <Key
@@ -218,12 +202,10 @@
                     >
                         <Key
                             latin:keyStyle="micKeyStyle"
-                            latin:keyWidth="8.042%p" />
+                            latin:keyXPos="-8.047%p"
+                            latin:keyWidth="fillRight" />
                     </case>
                 </switch>
-                <!-- There is an empty area below the "Enter" key and right of the "#" key. To
-                     ignore the touch event on the area, "#" is intentionally not marked as a right
-                     edge key. -->
             </Row>
         </default>
     </switch>
diff --git a/java/res/xml-sw768dp/kbd_phone.xml b/java/res/xml-sw768dp/kbd_phone.xml
index 60edcf2bdf..583239afb0 100644
--- a/java/res/xml-sw768dp/kbd_phone.xml
+++ b/java/res/xml-sw768dp/kbd_phone.xml
@@ -24,7 +24,7 @@
     latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
     latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
-    latin:keyWidth="11.949%p"
+    latin:keyWidth="11.954%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
@@ -39,115 +39,101 @@
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <!-- To match one character label size with "Tab", I placed spaces around the char '-'
              and '+'. -->
-        <Spacer
-            latin:horizontalGap="8.470%p" />
         <Key
             latin:code="45"
             latin:keyLabel=" - "
-            latin:keyWidth="8.042%p" />
+            latin:keyXPos="20.400%p"
+            latin:keyWidth="8.047%p" />
         <Key
             latin:code="43"
             latin:keyLabel=" + "
-            latin:keyWidth="8.042%p" />
-        <Spacer
-            latin:horizontalGap="8.479%p" />
+            latin:keyWidth="8.047%p" />
         <Key
-            latin:keyStyle="num1KeyStyle" />
+            latin:keyStyle="num1KeyStyle"
+            latin:keyXPos="45.000%p" />
         <Key
             latin:keyStyle="num2KeyStyle" />
         <Key
             latin:keyStyle="num3KeyStyle" />
-        <Spacer
-            latin:horizontalGap="9.360%p" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="9.804%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
         <Key
             latin:keyStyle="moreKeyStyle"
+            latin:keyWidth="11.172%p"
             latin:keyEdgeFlags="left" />
         <!-- To match one character label size with "More", I placed spaces around the char ','
              and '.'. -->
-        <Spacer
-            latin:horizontalGap="8.470%p" />
         <Key
             latin:code="44"
             latin:keyLabel=" , "
-            latin:keyWidth="8.042%p" />
+            latin:keyXPos="20.400%p"
+            latin:keyWidth="8.047%p" />
         <Key
             latin:code="46"
             latin:keyLabel=" . "
-            latin:keyWidth="8.042%p" />
-        <Spacer
-            latin:horizontalGap="8.479%p" />
+            latin:keyWidth="8.047%p" />
         <Key
-            latin:keyStyle="num4KeyStyle" />
+            latin:keyStyle="num4KeyStyle"
+            latin:keyXPos="45.000%p" />
         <Key
             latin:keyStyle="num5KeyStyle" />
         <Key
             latin:keyStyle="num6KeyStyle" />
-        <Spacer
-            latin:horizontalGap="4.458%p" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="14.706%p"
+            latin:keyXPos="-15.704%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
         <!-- To match one character label size with "More", I placed spaces around the char '('
              and ')'. -->
-        <!-- There is an empty area bellow the "More" key and left of the "(" key.  To ignore
+        <!-- There is an empty area below the "More" key and left of the "(" key.  To ignore
              the touch event on the area, "(" is intentionally not marked as a left edge key. -->
-        <Spacer
-            latin:horizontalGap="20.427%p" />
         <Key
             latin:code="40"
             latin:keyLabel=" ( "
-            latin:keyWidth="8.042%p" />
+            latin:keyXPos="20.400%p"
+            latin:keyWidth="8.047%p" />
         <Key
             latin:code="41"
             latin:keyLabel=" ) "
-            latin:keyWidth="8.042%p" />
-        <Spacer
-            latin:horizontalGap="8.479%p" />
+            latin:keyWidth="8.047%p" />
         <Key
-            latin:keyStyle="num7KeyStyle" />
+            latin:keyStyle="num7KeyStyle"
+            latin:keyXPos="45.000%p" />
         <Key
             latin:keyStyle="num8KeyStyle" />
         <Key
             latin:keyStyle="num9KeyStyle" />
-        <!-- There is an empty area bellow the "Enter" key and right of the "9" key.  To ignore
+        <!-- There is an empty area below the "Enter" key and right of the "9" key.  To ignore
              the touch event on the area, "9" is intentionally not marked as a right edge key. -->
         </Row>
     <!-- This row is intentionally not marked as a bottom row -->
     <Row>
-        <!-- There is an empty area bellow the "More" key and left of the "space" key.  To ignore
-             the touch event on the area, "space" is intentionally not marked as a left edge key. -->
-        <Spacer
-            latin:horizontalGap="12.340%p" />
         <switch>
             <case latin:hasSettingsKey="true">
                 <Key
                     latin:keyStyle="settingsKeyStyle"
-                    latin:keyWidth="8.042%p" />
+                    latin:keyWidth="8.047%p" />
             </case>
-            <default>
-                <Spacer
-                    latin:horizontalGap="8.042%p" />
-            </default>
         </switch>
         <Key
             latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
+            latin:keyXPos="20.400%p"
             latin:keyWidth="16.084%p" />
-        <Spacer
-            latin:horizontalGap="8.479%p" />
         <Key
-            latin:keyStyle="numStarKeyStyle" />
+            latin:keyStyle="numStarKeyStyle"
+            latin:keyXPos="45.000%p" />
         <Key
             latin:keyStyle="num0KeyStyle" />
         <Key
@@ -158,10 +144,9 @@
             >
                 <Key
                     latin:keyStyle="micKeyStyle"
-                    latin:keyWidth="8.042%p" />
+                    latin:keyXPos="-8.047%p"
+                    latin:keyWidth="fillRight" />
             </case>
         </switch>
-        <!-- There is an empty area bellow the "Enter" key and right of the "#" key.  To ignore
-             the touch event on the area, "#" is intentionally not marked as a right edge key. -->
     </Row>
 </Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_phone_symbols.xml b/java/res/xml-sw768dp/kbd_phone_symbols.xml
index c388a46672..714e5e5f36 100644
--- a/java/res/xml-sw768dp/kbd_phone_symbols.xml
+++ b/java/res/xml-sw768dp/kbd_phone_symbols.xml
@@ -24,7 +24,7 @@
     latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
     latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
-    latin:keyWidth="11.949%p"
+    latin:keyWidth="11.954%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
@@ -39,127 +39,113 @@
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
-        <Spacer
-            latin:horizontalGap="4.458%p" />
         <Key
             latin:code="45"
             latin:keyLabel=" - "
-            latin:keyWidth="8.042%p" />
+            latin:keyXPos="13.829%p"
+            latin:keyWidth="8.047%p" />
         <Key
             latin:code="43"
             latin:keyLabel=" + "
-            latin:keyWidth="8.042%p" />
+            latin:keyWidth="8.047%p" />
         <Key
             latin:code="44"
             latin:keyLabel="@string/label_pause_key"
-            latin:keyWidth="8.042%p" />
+            latin:keyWidth="8.047%p" />
         <!-- To match one character label size with "Tab" and "Pause, I placed spaces around the
              char '-' and '+'. -->
-        <Spacer
-            latin:horizontalGap="4.458%p" />
         <Key
-            latin:keyStyle="num1KeyStyle" />
+            latin:keyStyle="num1KeyStyle"
+            latin:keyXPos="45.000%p" />
         <Key
             latin:keyStyle="num2KeyStyle" />
         <Key
             latin:keyStyle="num3KeyStyle" />
-        <Spacer
-            latin:horizontalGap="9.360%p" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="9.804%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
         <Key
             latin:keyStyle="moreKeyStyle"
+            latin:keyWidth="11.172%p"
             latin:keyEdgeFlags="left" />
-        <Spacer
-            latin:horizontalGap="4.458%p" />
         <Key
             latin:code="44"
             latin:keyLabel=" , "
-            latin:keyWidth="8.042%p" />
+            latin:keyXPos="13.829%p"
+            latin:keyWidth="8.047%p" />
         <Key
             latin:code="46"
             latin:keyLabel=" . "
-            latin:keyWidth="8.042%p" />
+            latin:keyWidth="8.047%p" />
         <Key
             latin:code="59"
             latin:keyLabel="@string/label_wait_key"
-            latin:keyWidth="8.042%p" />
+            latin:keyWidth="8.047%p" />
         <!-- To match one character label size with "More" and "Wait", I placed spaces around the
              char ',' and '.'. -->
-        <Spacer
-            latin:horizontalGap="4.458%p" />
         <Key
-            latin:keyStyle="num4KeyStyle" />
+            latin:keyStyle="num4KeyStyle"
+            latin:keyXPos="45.000%p" />
         <Key
             latin:keyStyle="num5KeyStyle" />
         <Key
             latin:keyStyle="num6KeyStyle" />
-        <Spacer
-            latin:horizontalGap="4.458%p" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="14.706%p"
+            latin:keyXPos="-15.704%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
         <!-- To match one character label size with "More" and etc., I placed spaces around the
              char 'N', '(' and ')'. -->
-        <!-- There is an empty area bellow the "More" key and left of the "(" key.  To ignore
+        <!-- There is an empty area below the "More" key and left of the "(" key.  To ignore
              the touch event on the area, "(" is intentionally not marked as a left edge key. -->
-        <Spacer
-            latin:horizontalGap="16.406%p" />
         <Key
             latin:code="40"
             latin:keyLabel=" ( "
-            latin:keyWidth="8.042%p" />
+            latin:keyXPos="13.829%p"
+            latin:keyWidth="8.047%p" />
         <Key
             latin:code="41"
             latin:keyLabel=" ) "
-            latin:keyWidth="8.042%p" />
+            latin:keyWidth="8.047%p" />
         <Key
             latin:code="78"
             latin:keyLabel=" N "
-            latin:keyWidth="8.042%p" />
-        <Spacer
-            latin:horizontalGap="4.458%p" />
+            latin:keyWidth="8.047%p" />
         <Key
-            latin:keyStyle="num7KeyStyle" />
+            latin:keyStyle="num7KeyStyle"
+            latin:keyXPos="45.000%p" />
         <Key
             latin:keyStyle="num8KeyStyle" />
         <Key
             latin:keyStyle="num9KeyStyle" />
-        <!-- There is an empty area bellow the "Enter" key and right of the "9" key.  To ignore
+        <!-- There is an empty area below the "Enter" key and right of the "9" key.  To ignore
              the touch event on the area, "9" is intentionally not marked as a right edge key. -->
     </Row>
     <!-- This row is intentionally not marked as a bottom row -->
     <Row>
-        <!-- There is an empty area bellow the "More" key and left of the "space" key.  To ignore
-             the touch event on the area, "space" is intentionally not marked as a left edge key. -->
-        <Spacer
-            latin:horizontalGap="8.362%p" />
         <switch>
             <case latin:hasSettingsKey="true">
                 <Key
                     latin:keyStyle="settingsKeyStyle"
-                    latin:keyWidth="8.042%p" />
+                    latin:keyWidth="8.047%p" />
             </case>
-            <default>
-                <Spacer
-                    latin:horizontalGap="8.042%p" />
-            </default>
         </switch>
         <Key
             latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
-            latin:keyWidth="24.127%p" />
-        <Spacer
-            latin:horizontalGap="4.458%p" />
+            latin:keyXPos="13.829%p"
+            latin:keyWidth="24.140%p" />
         <Key
-            latin:keyStyle="numStarKeyStyle" />
+            latin:keyStyle="numStarKeyStyle"
+            latin:keyXPos="45.000%p" />
         <Key
             latin:keyStyle="num0KeyStyle" />
         <Key
@@ -170,10 +156,9 @@
             >
                 <Key
                     latin:keyStyle="micKeyStyle"
-                    latin:keyWidth="8.042%p" />
+                    latin:keyXPos="-8.047%p"
+                    latin:keyWidth="fillRight" />
             </case>
         </switch>
-        <!-- There is an empty area bellow the "Enter" key and right of the "#" key.  To ignore
-             the touch event on the area, "#" is intentionally not marked as a right edge key. -->
     </Row>
 </Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row1.xml b/java/res/xml-sw768dp/kbd_qwerty_row1.xml
index f5135591c3..3727cf34ea 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row1.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_row1.xml
@@ -23,12 +23,12 @@
 >
     <!-- This row is intentionally not marked as a top row -->
     <Row
-        latin:keyWidth="8.272%p"
+        latin:keyWidth="8.282%p"
     >
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="q"
@@ -62,7 +62,8 @@
             latin:popupCharacters="@string/alternates_for_p" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="9.331%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row2.xml b/java/res/xml-sw768dp/kbd_qwerty_row2.xml
index 02bd0a6c99..45af120e23 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row2.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_row2.xml
@@ -22,12 +22,12 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
     <Row
-        latin:keyWidth="8.157%p"
+        latin:keyWidth="8.125%p"
     >
         <Key
             latin:keyStyle="toSymbolKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="11.167%p"
+            latin:keyWidth="11.172%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="a"
@@ -55,7 +55,8 @@
             latin:popupCharacters="@string/alternates_for_l" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="15.750%p"
+            latin:keyXPos="-15.704%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row3.xml b/java/res/xml-sw768dp/kbd_qwerty_row3.xml
index b7e9bcff9a..7d59dfb9eb 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row3.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_row3.xml
@@ -22,11 +22,11 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
     <Row
-        latin:keyWidth="8.042%p"
+        latin:keyWidth="8.047%p"
     >
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="15.192%p"
+            latin:keyWidth="13.829%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="z"
@@ -72,7 +72,8 @@
         </switch>
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="12.530%p"
+            latin:keyXPos="-13.750%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row4.xml b/java/res/xml-sw768dp/kbd_qwerty_row4.xml
index e5bc342ae8..b24ea5e430 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row4.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_row4.xml
@@ -23,20 +23,18 @@
 >
     <!-- This row is intentionally not marked as a bottom row -->
     <Row
-        latin:keyWidth="8.042%p"
+        latin:keyWidth="8.047%p"
     >
-        <Spacer
-            latin:horizontalGap="8.362%p" />
         <switch>
             <case latin:hasSettingsKey="true">
                 <Key
-                    latin:keyStyle="settingsKeyStyle" />
+                    latin:keyStyle="settingsKeyStyle"
+                    latin:keyWidth="8.047%p" />
             </case>
-            <default>
-                <Spacer
-                    latin:horizontalGap="8.042%p" />
-            </default>
         </switch>
+        <Spacer
+            latin:keyXPos="15.157%p"
+            latin:keyWidth="fillRight" />
         <switch>
             <case
                 latin:languageCode="ru"
@@ -152,7 +150,8 @@
         </switch>
         <Key
             latin:keyStyle="spaceKeyStyle"
-            latin:keyWidth="37.454%p" />
+            latin:keyXPos="31.250%p"
+            latin:keyWidth="37.500%p" />
         <switch>
             <case
                 latin:languageCode="ru"
@@ -251,7 +250,9 @@
                 latin:voiceKeyEnabled="true"
             >
                 <Key
-                    latin:keyStyle="micKeyStyle" />
+                    latin:keyStyle="micKeyStyle"
+                    latin:keyXPos="-8.047%p"
+                    latin:keyWidth="fillRight" />
             </case>
         </switch>
     </Row>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_rows_scandinavia.xml b/java/res/xml-sw768dp/kbd_qwerty_rows_scandinavia.xml
index fb2034fb75..b8875282ce 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_rows_scandinavia.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_rows_scandinavia.xml
@@ -24,12 +24,12 @@
     <include
         latin:keyboardLayout="@xml/kbd_key_styles" />
     <Row
-        latin:keyWidth="7.520%p"
+        latin:keyWidth="7.579%p"
     >
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="q"
@@ -65,16 +65,17 @@
             latin:keyLabel="Ã¥" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="9.331%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="7.520%p"
+        latin:keyWidth="7.500%p"
     >
         <Key
             latin:keyStyle="toSymbolKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="a"
@@ -108,7 +109,8 @@
             latin:popupCharacters="@string/alternates_for_scandinavia_row2_11" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="9.331%p"
+            latin:keyXPos="-15.704%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <include
diff --git a/java/res/xml-sw768dp/kbd_qwertz_rows.xml b/java/res/xml-sw768dp/kbd_qwertz_rows.xml
index 3e99f05113..4e937acdaa 100644
--- a/java/res/xml-sw768dp/kbd_qwertz_rows.xml
+++ b/java/res/xml-sw768dp/kbd_qwertz_rows.xml
@@ -24,12 +24,12 @@
     <include
         latin:keyboardLayout="@xml/kbd_key_styles" />
     <Row
-        latin:keyWidth="8.272%p"
+        latin:keyWidth="8.282%p"
     >
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="q"
@@ -63,17 +63,18 @@
             latin:popupCharacters="@string/alternates_for_p" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="9.331%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_row2" />
     <Row
-        latin:keyWidth="8.042%p"
+        latin:keyWidth="8.047%p"
     >
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="15.192%p"
+            latin:keyWidth="13.829%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="y"
@@ -119,7 +120,8 @@
         </switch>
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="12.530%p"
+            latin:keyXPos="-13.750%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
    <include
diff --git a/java/res/xml-sw768dp/kbd_ru_rows.xml b/java/res/xml-sw768dp/kbd_ru_rows.xml
index c5cd043712..3849141e45 100644
--- a/java/res/xml-sw768dp/kbd_ru_rows.xml
+++ b/java/res/xml-sw768dp/kbd_ru_rows.xml
@@ -25,57 +25,49 @@
         latin:keyboardLayout="@xml/kbd_key_styles" />
     <!-- This row is intentionally not marked as a top row -->
     <Row
-        latin:keyWidth="7.520%p"
+        latin:keyWidth="7.579%p"
     >
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
-            latin:keyLabel="й"
-            latin:popupCharacters="1" />
+            latin:keyLabel="й" />
         <Key
-            latin:keyLabel="ц"
-            latin:popupCharacters="2" />
+            latin:keyLabel="ц" />
         <Key
-            latin:keyLabel="у"
-            latin:popupCharacters="3" />
+            latin:keyLabel="у" />
         <Key
-            latin:keyLabel="к"
-            latin:popupCharacters="4" />
+            latin:keyLabel="к" />
         <Key
             latin:keyLabel="е"
             latin:popupCharacters="@string/alternates_for_cyrillic_e" />
         <Key
-            latin:keyLabel="н"
-            latin:popupCharacters="6" />
+            latin:keyLabel="н" />
         <Key
-            latin:keyLabel="г"
-            latin:popupCharacters="7" />
+            latin:keyLabel="г" />
         <Key
-            latin:keyLabel="ш"
-            latin:popupCharacters="8" />
+            latin:keyLabel="ш" />
         <Key
-            latin:keyLabel="щ"
-            latin:popupCharacters="9" />
+            latin:keyLabel="щ" />
         <Key
-            latin:keyLabel="з"
-            latin:popupCharacters="0" />
+            latin:keyLabel="з" />
         <Key
             latin:keyLabel="Ñ…" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="9.331%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="7.520%p"
+        latin:keyWidth="7.500%p"
     >
         <Key
             latin:keyStyle="toSymbolKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="9.219%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="Ñ„" />
@@ -101,11 +93,12 @@
             latin:keyLabel="э" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="9.331%p"
+            latin:keyXPos="-15.704%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="7.520%p"
+        latin:keyWidth="7.500%p"
     >
         <Key
             latin:keyStyle="shiftKeyStyle"
@@ -138,7 +131,8 @@
             latin:popupCharacters="," />
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="12.400%p"
+            latin:keyXPos="-13.750%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <include
diff --git a/java/res/xml-sw768dp/kbd_sr_rows.xml b/java/res/xml-sw768dp/kbd_sr_rows.xml
index be00585051..fbf1e9b842 100644
--- a/java/res/xml-sw768dp/kbd_sr_rows.xml
+++ b/java/res/xml-sw768dp/kbd_sr_rows.xml
@@ -25,57 +25,48 @@
         latin:keyboardLayout="@xml/kbd_key_styles" />
     <!-- This row is intentionally not marked as a top row -->
     <Row
-        latin:keyWidth="7.520%p"
+        latin:keyWidth="7.579%p"
     >
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="8.640%p"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
-            latin:keyLabel="Ñ™"
-            latin:popupCharacters="1" />
+            latin:keyLabel="Ñ™" />
         <Key
-            latin:keyLabel="Ñš"
-            latin:popupCharacters="2" />
+            latin:keyLabel="Ñš" />
         <Key
-            latin:keyLabel="е"
-            latin:popupCharacters="3" />
+            latin:keyLabel="е" />
         <Key
-            latin:keyLabel="Ñ€"
-            latin:popupCharacters="4" />
+            latin:keyLabel="Ñ€" />
         <Key
-            latin:keyLabel="Ñ‚"
-            latin:popupCharacters="5" />
+            latin:keyLabel="Ñ‚" />
         <Key
-            latin:keyLabel="з"
-            latin:popupCharacters="6" />
+            latin:keyLabel="з" />
         <Key
-            latin:keyLabel="у"
-            latin:popupCharacters="7" />
+            latin:keyLabel="у" />
         <Key
-            latin:keyLabel="и"
-            latin:popupCharacters="8" />
+            latin:keyLabel="и" />
         <Key
-            latin:keyLabel="о"
-            latin:popupCharacters="9" />
+            latin:keyLabel="о" />
         <Key
-            latin:keyLabel="п"
-            latin:popupCharacters="0" />
+            latin:keyLabel="п" />
         <Key
             latin:keyLabel="ш" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="8.640%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="7.520%p"
+        latin:keyWidth="7.500%p"
     >
         <Key
             latin:keyStyle="toSymbolKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="8.640%p"
+            latin:keyWidth="9.219%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="а" />
@@ -101,15 +92,16 @@
             latin:keyLabel="Ñ›" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="8.640%p"
+            latin:keyXPos="-15.704%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="7.520%p"
+        latin:keyWidth="7.500%p"
     >
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="8.640%p"
+            latin:keyWidth="9.219%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="Ñ•" />
@@ -143,7 +135,8 @@
             latin:popupCharacters="\?" />
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="8.640%p"
+            latin:keyXPos="-13.750%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <include
diff --git a/java/res/xml-sw768dp/kbd_symbols.xml b/java/res/xml-sw768dp/kbd_symbols.xml
index 41e8522dc0..26cf1ac705 100644
--- a/java/res/xml-sw768dp/kbd_symbols.xml
+++ b/java/res/xml-sw768dp/kbd_symbols.xml
@@ -35,12 +35,12 @@
         latin:keyboardLayout="@xml/kbd_currency_key_styles" />
     <!-- This row is intentionally not marked as a top row -->
     <Row
-        latin:keyWidth="8.272%p"
+        latin:keyWidth="8.282%p"
     >
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="1"
@@ -71,16 +71,17 @@
             latin:popupCharacters="ⁿ,∅" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="9.331%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.157%p"
+        latin:keyWidth="8.125%p"
     >
         <Key
             latin:keyStyle="toAlphaKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="11.167%p"
+            latin:keyWidth="11.172%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="#" />
@@ -108,15 +109,16 @@
             latin:popupCharacters="],},&gt;" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="15.750%p"
+            latin:keyXPos="-15.704%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.042%p"
+        latin:keyWidth="8.047%p"
     >
         <Key
             latin:keyStyle="moreKeyStyle"
-            latin:keyWidth="15.192%p"
+            latin:keyWidth="13.829%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="&lt;"
@@ -180,32 +182,30 @@
         </switch>
         <Key
             latin:keyStyle="moreKeyStyle"
-            latin:keyWidth="12.530%p"
+            latin:keyXPos="-13.750%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <!-- This row is intentionally not marked as a bottom row -->
     <Row
-        latin:keyWidth="8.042%p"
+        latin:keyWidth="8.047%p"
     >
-        <Spacer
-            latin:horizontalGap="8.362%p" />
         <switch>
             <case latin:hasSettingsKey="true">
                 <Key
-                    latin:keyStyle="settingsKeyStyle" />
+                    latin:keyStyle="settingsKeyStyle"
+                    latin:keyWidth="8.047%p" />
             </case>
-            <default>
-                <Spacer
-                    latin:horizontalGap="8.042%p" />
-            </default>
         </switch>
         <Key
-            latin:keyLabel="/" />
+            latin:keyLabel="/"
+            latin:keyXPos="15.157%p" />
         <Key
             latin:keyLabel="\@" />
         <Key
             latin:keyStyle="spaceKeyStyle"
-            latin:keyWidth="37.454%p" />
+            latin:keyXPos="31.250%p"
+            latin:keyWidth="37.500%p" />
         <switch>
             <case
                 latin:languageCode="ru"
@@ -230,7 +230,9 @@
                 latin:voiceKeyEnabled="true"
             >
                 <Key
-                    latin:keyStyle="micKeyStyle" />
+                    latin:keyStyle="micKeyStyle"
+                    latin:keyXPos="-8.047%p"
+                    latin:keyWidth="fillRight" />
             </case>
         </switch>
     </Row>
diff --git a/java/res/xml-sw768dp/kbd_symbols_shift.xml b/java/res/xml-sw768dp/kbd_symbols_shift.xml
index d7f5958b7f..94bd761ba9 100644
--- a/java/res/xml-sw768dp/kbd_symbols_shift.xml
+++ b/java/res/xml-sw768dp/kbd_symbols_shift.xml
@@ -33,12 +33,12 @@
         latin:keyboardLayout="@xml/kbd_key_styles" />
     <!-- This row is intentionally not marked as a top row -->
     <Row
-        latin:keyWidth="8.272%p"
+        latin:keyWidth="8.282%p"
     >
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="7.949%p"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="~" />
@@ -72,16 +72,17 @@
             latin:keyLabel="Δ" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="9.331%p"
+            latin:keyXPos="-9.219%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.157%p"
+        latin:keyWidth="8.125%p"
     >
         <Key
             latin:keyStyle="toAlphaKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="11.167%p"
+            latin:keyWidth="11.172%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyStyle="nonPasswordSymbolKeyStyle"
@@ -112,15 +113,16 @@
             latin:keyLabel="}" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="15.750%p"
+            latin:keyXPos="-15.704%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.042%p"
+        latin:keyWidth="8.047%p"
     >
         <Key
             latin:keyStyle="moreKeyStyle"
-            latin:keyWidth="15.192%p"
+            latin:keyWidth="13.829%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="\\" />
@@ -148,34 +150,33 @@
             latin:keyLabel="¿" />
         <Key
             latin:keyStyle="moreKeyStyle"
-            latin:keyWidth="12.530%p"
+            latin:keyXPos="-13.750%p"
+            latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <!-- This row is intentionally not marked as a bottom row -->
     <Row
-        latin:keyWidth="8.042%p"
+        latin:keyWidth="8.047%p"
     >
-        <Spacer
-            latin:horizontalGap="24.446%p" />
         <switch>
             <case latin:hasSettingsKey="true">
                 <Key
-                    latin:keyStyle="settingsKeyStyle" />
+                    latin:keyStyle="settingsKeyStyle"
+                    latin:keyWidth="8.047%p" />
             </case>
-            <default>
-                <Spacer
-                    latin:horizontalGap="8.042%p" />
-            </default>
         </switch>
         <Key
             latin:keyStyle="spaceKeyStyle"
-            latin:keyWidth="37.454%p" />
+            latin:keyXPos="31.250%p"
+            latin:keyWidth="37.500%p" />
         <switch>
             <case
                 latin:voiceKeyEnabled="true"
             >
                 <Key
-                    latin:keyStyle="micKeyStyle" />
+                    latin:keyStyle="micKeyStyle"
+                    latin:keyXPos="-8.047%p"
+                    latin:keyWidth="fillRight" />
             </case>
         </switch>
     </Row>
diff --git a/java/res/xml/kbd_ar_rows.xml b/java/res/xml/kbd_ar_rows.xml
index b2ea45701c..a548775a4d 100644
--- a/java/res/xml/kbd_ar_rows.xml
+++ b/java/res/xml/kbd_ar_rows.xml
@@ -53,6 +53,7 @@
         <Key
             latin:keyLabel="ج"
             latin:popupCharacters="Ú†"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
@@ -84,6 +85,7 @@
         <Key
             latin:keyLabel="Ùƒ"
             latin:popupCharacters="Ú¯"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
@@ -112,7 +114,8 @@
             latin:keyLabel="Ø«" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="12%p"
+            latin:keyWidth="fillRight"
+            latin:visualInsetsLeft="1%p"
             latin:keyEdgeFlags="right" />
     </Row>
     <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
diff --git a/java/res/xml/kbd_azerty_rows.xml b/java/res/xml/kbd_azerty_rows.xml
index 2f2b054957..9c81aad719 100644
--- a/java/res/xml/kbd_azerty_rows.xml
+++ b/java/res/xml/kbd_azerty_rows.xml
@@ -68,6 +68,7 @@
             latin:keyLabel="p"
             latin:keyHintIcon="@drawable/key_hint_num0"
             latin:popupCharacters="@string/alternates_for_p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
@@ -100,6 +101,7 @@
             latin:popupCharacters="@string/alternates_for_l" />
         <Key
             latin:keyLabel="m"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
@@ -132,7 +134,7 @@
             latin:popupCharacters="‘,’,‚,‛" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="15%p"
+            latin:keyWidth="fillRight"
             latin:visualInsetsLeft="1%p"
             latin:keyEdgeFlags="right" />
     </Row>
diff --git a/java/res/xml/kbd_iw_rows.xml b/java/res/xml/kbd_iw_rows.xml
index fb0c2a9158..af017ad6f1 100644
--- a/java/res/xml/kbd_iw_rows.xml
+++ b/java/res/xml/kbd_iw_rows.xml
@@ -29,10 +29,9 @@
     <Row
         latin:rowEdgeFlags="top"
     >
-        <Spacer
-            latin:horizontalGap="5%p" />
         <Key
             latin:keyLabel="×§"
+            latin:keyXPos="5%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="ר" />
@@ -50,7 +49,7 @@
             latin:keyLabel="פ" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="15%p"
+            latin:keyWidth="fillRight"
             latin:visualInsetsLeft="1%p"
             latin:keyEdgeFlags="right" />
     </Row>
@@ -76,13 +75,13 @@
             latin:keyLabel="ך" />
         <Key
             latin:keyLabel="×£"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
-        <Spacer
-            latin:horizontalGap="5%p" />
         <Key
             latin:keyLabel="×–"
+            latin:keyXPos="5%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="ס" />
@@ -101,6 +100,7 @@
         <Key
             latin:keyLabel="×¥"
             latin:keyEdgeFlags="right" />
+        <!-- Here is 5%p space -->
     </Row>
     <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
 </merge>
diff --git a/java/res/xml/kbd_key_styles.xml b/java/res/xml/kbd_key_styles.xml
index d4d25d4a29..f888b231e5 100644
--- a/java/res/xml/kbd_key_styles.xml
+++ b/java/res/xml/kbd_key_styles.xml
@@ -51,7 +51,7 @@
             <key-style
                 latin:styleName="settingsPopupStyle"
                 latin:keyHintIcon="@drawable/hint_popup"
-                latin:popupCharacters="\@drawable/sym_keyboard_settings|\@integer/key_settings"
+                latin:popupCharacters="\@drawable/sym_keyboard_settings_holo|\@integer/key_settings"
                 latin:parentStyle="functionalKeyStyle" />
         </default>
     </switch>
@@ -101,20 +101,20 @@
             <key-style
                 latin:styleName="settingsKeyStyle"
                 latin:code="@integer/key_settings"
-                latin:keyIcon="@drawable/sym_keyboard_settings"
-                latin:iconPreview="@drawable/sym_keyboard_feedback_settings"
+                latin:keyIcon="@drawable/sym_keyboard_settings_holo"
+                latin:iconPreview="@drawable/sym_keyboard_settings_holo"
                 latin:parentStyle="functionalKeyStyle" />
             <key-style
                 latin:styleName="spaceKeyStyle"
                 latin:code="@integer/key_space"
                 latin:keyIcon="@drawable/sym_keyboard_space"
-                latin:iconPreview="@drawable/sym_keyboard_feedback_space"
+                latin:iconPreview="@drawable/sym_keyboard_space"
                 latin:parentStyle="functionalKeyStyle" />
             <key-style
                 latin:styleName="tabKeyStyle"
                 latin:code="@integer/key_tab"
                 latin:keyIcon="@drawable/sym_keyboard_tab"
-                latin:iconPreview="@drawable/sym_keyboard_feedback_tab"
+                latin:iconPreview="@drawable/sym_keyboard_tab"
                 latin:parentStyle="functionalKeyStyle" />
             <key-style
                 latin:styleName="micKeyStyle"
@@ -128,7 +128,7 @@
                 latin:styleName="nonSpecialBackgroundTabKeyStyle"
                 latin:code="@integer/key_tab"
                 latin:keyIcon="@drawable/sym_keyboard_tab"
-                latin:iconPreview="@drawable/sym_keyboard_feedback_tab" />
+                latin:iconPreview="@drawable/sym_keyboard_tab" />
         </case>
         <case
             latin:colorScheme="black"
@@ -277,7 +277,7 @@
                         latin:styleName="returnKeyStyle"
                         latin:code="@integer/key_return"
                         latin:keyIcon="@drawable/sym_keyboard_return"
-                        latin:iconPreview="@drawable/sym_keyboard_feedback_return"
+                        latin:iconPreview="@drawable/sym_keyboard_return"
                         latin:parentStyle="functionalKeyStyle" />
                 </case>
                 <case
diff --git a/java/res/xml/kbd_number.xml b/java/res/xml/kbd_number.xml
index c5e9d77f8a..23b88a5bdc 100644
--- a/java/res/xml/kbd_number.xml
+++ b/java/res/xml/kbd_number.xml
@@ -68,21 +68,19 @@
                     latin:keyStyle="num9KeyStyle" />
                 <Key
                     latin:keyStyle="deleteKeyStyle"
-                    latin:keyWidth="20%p"
+                    latin:keyWidth="fillRight"
                     latin:keyEdgeFlags="right" />
             </Row>
             <Row
                 latin:rowEdgeFlags="bottom"
             >
-                <Spacer
-                    latin:horizontalGap="26.67%p" />
+                <Spacer />
                 <Key
                     latin:keyStyle="num0KeyStyle" />
-                <Spacer
-                    latin:horizontalGap="26.67%p" />
+                <Spacer />
                 <Key
                     latin:keyStyle="returnKeyStyle"
-                    latin:keyWidth="20%p"
+                    latin:keyWidth="fillRight"
                     latin:keyEdgeFlags="right" />
             </Row>
         </case>
@@ -101,7 +99,7 @@
                 <Key
                     latin:keyLabel="-"
                     latin:keyStyle="functionalKeyStyle"
-                    latin:keyWidth="20%p"
+                    latin:keyWidth="fillRight"
                     latin:keyEdgeFlags="right" />
             </Row>
             <Row>
@@ -115,7 +113,7 @@
                 <Key
                     latin:keyLabel=","
                     latin:keyStyle="functionalKeyStyle"
-                    latin:keyWidth="20%p"
+                    latin:keyWidth="fillRight"
                     latin:keyEdgeFlags="right" />
             </Row>
             <Row>
@@ -128,7 +126,7 @@
                     latin:keyLabel="9" />
                 <Key
                     latin:keyStyle="deleteKeyStyle"
-                    latin:keyWidth="20%p"
+                    latin:keyWidth="fillRight"
                     latin:keyEdgeFlags="right" />
             </Row>
             <Row
@@ -143,7 +141,7 @@
                     latin:keyLabel="." />
                 <Key
                     latin:keyStyle="returnKeyStyle"
-                    latin:keyWidth="20%p"
+                    latin:keyWidth="fillRight"
                     latin:keyEdgeFlags="right" />
             </Row>
         </default>
diff --git a/java/res/xml/kbd_phone.xml b/java/res/xml/kbd_phone.xml
index ca591c72d3..e1d1ee8d0d 100644
--- a/java/res/xml/kbd_phone.xml
+++ b/java/res/xml/kbd_phone.xml
@@ -47,7 +47,7 @@
         <Key
             latin:keyLabel="-"
             latin:keyStyle="functionalKeyStyle"
-            latin:keyWidth="20%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
@@ -61,7 +61,7 @@
         <Key
             latin:keyLabel="."
             latin:keyStyle="functionalKeyStyle"
-            latin:keyWidth="20%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
@@ -74,7 +74,7 @@
             latin:keyStyle="num9KeyStyle" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="20%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
@@ -89,7 +89,7 @@
             latin:keyStyle="numSpaceKeyStyle" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="20%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
 </Keyboard>
diff --git a/java/res/xml/kbd_phone_symbols.xml b/java/res/xml/kbd_phone_symbols.xml
index 99db23ef1b..2af218cfe2 100644
--- a/java/res/xml/kbd_phone_symbols.xml
+++ b/java/res/xml/kbd_phone_symbols.xml
@@ -47,7 +47,7 @@
         <Key
             latin:keyLabel="-"
             latin:keyStyle="functionalKeyStyle"
-            latin:keyWidth="20%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
@@ -64,7 +64,7 @@
         <Key
             latin:keyLabel="."
             latin:keyStyle="functionalKeyStyle"
-            latin:keyWidth="20%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
@@ -79,7 +79,7 @@
             latin:keyStyle="numPoundKeyStyle" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="20%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
@@ -95,7 +95,7 @@
             latin:keyStyle="numSpaceKeyStyle" />
         <Key
             latin:keyStyle="returnKeyStyle"
-            latin:keyWidth="20%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
 </Keyboard>
diff --git a/java/res/xml/kbd_qwerty_row1.xml b/java/res/xml/kbd_qwerty_row1.xml
index 3964d3c3e6..ba804d3219 100644
--- a/java/res/xml/kbd_qwerty_row1.xml
+++ b/java/res/xml/kbd_qwerty_row1.xml
@@ -66,6 +66,7 @@
             latin:keyLabel="p"
             latin:keyHintIcon="@drawable/key_hint_num0"
             latin:popupCharacters="@string/alternates_for_p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
 </merge>
diff --git a/java/res/xml/kbd_qwerty_row2.xml b/java/res/xml/kbd_qwerty_row2.xml
index 9ed4553c45..57bbad75ab 100644
--- a/java/res/xml/kbd_qwerty_row2.xml
+++ b/java/res/xml/kbd_qwerty_row2.xml
@@ -24,11 +24,10 @@
     <Row
         latin:keyWidth="10%p"
     >
-        <Spacer
-            latin:horizontalGap="5%p" />
         <Key
             latin:keyLabel="a"
             latin:popupCharacters="@string/alternates_for_a"
+            latin:keyXPos="5%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="s"
@@ -52,5 +51,6 @@
             latin:keyLabel="l"
             latin:popupCharacters="@string/alternates_for_l"
             latin:keyEdgeFlags="right" />
+        <!-- Here is 5%p space -->
     </Row>
 </merge>
diff --git a/java/res/xml/kbd_qwerty_row3.xml b/java/res/xml/kbd_qwerty_row3.xml
index 3d106e615a..98f0404c00 100644
--- a/java/res/xml/kbd_qwerty_row3.xml
+++ b/java/res/xml/kbd_qwerty_row3.xml
@@ -49,7 +49,7 @@
             latin:keyLabel="m" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="15%p"
+            latin:keyWidth="fillBoth"
             latin:visualInsetsLeft="1%p"
             latin:keyEdgeFlags="right" />
     </Row>
diff --git a/java/res/xml/kbd_qwerty_row4.xml b/java/res/xml/kbd_qwerty_row4.xml
index a8d150e4bf..21d80eb0b3 100644
--- a/java/res/xml/kbd_qwerty_row4.xml
+++ b/java/res/xml/kbd_qwerty_row4.xml
@@ -27,103 +27,67 @@
     >
         <switch>
             <case
-                latin:hasSettingsKey="false"
+                latin:hasSettingsKey="true"
             >
                 <Key
                     latin:keyStyle="toSymbolKeyStyle"
-                    latin:keyWidth="20%p"
+                    latin:keyWidth="15%p"
                     latin:keyEdgeFlags="left" />
+                <Key
+                    latin:keyStyle="settingsKeyStyle" />
                 <include
                     latin:keyboardLayout="@xml/kbd_qwerty_f1" />
                 <Key
                     latin:keyStyle="spaceKeyStyle"
-                    latin:keyWidth="40%p" />
-                <switch>
-                    <case
-                        latin:webInput="true"
-                    >
-                         <Key
-                            latin:keyHintIcon="@drawable/hint_popup"
-                            latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
-                            latin:maxPopupKeyboardColumn="8"
-                            latin:keyStyle="tabKeyStyle" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyLabel="."
-                            latin:keyHintIcon="@drawable/hint_popup"
-                            latin:popupCharacters="@string/alternates_for_punctuation"
-                            latin:maxPopupKeyboardColumn="7"
-                            latin:keyStyle="functionalKeyStyle" />
-                    </default>
-                </switch>
-                <switch>
-                    <case
-                        latin:mode="im"
-                    >
-                        <Key
-                            latin:keyStyle="smileyKeyStyle"
-                            latin:keyWidth="20%p"
-                            latin:keyEdgeFlags="right" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyStyle="returnKeyStyle"
-                            latin:keyWidth="20%p"
-                            latin:keyEdgeFlags="right" />
-                    </default>
-                </switch>
+                    latin:keyWidth="30%p" />
             </case>
-            <case
-                latin:hasSettingsKey="true"
-            >
+            <!-- latin:hasSettingsKey="false" -->
+            <default>
                 <Key
                     latin:keyStyle="toSymbolKeyStyle"
-                    latin:keyWidth="15%p"
+                    latin:keyWidth="20%p"
                     latin:keyEdgeFlags="left" />
-                <Key
-                    latin:keyStyle="settingsKeyStyle" />
                 <include
                     latin:keyboardLayout="@xml/kbd_qwerty_f1" />
                 <Key
                     latin:keyStyle="spaceKeyStyle"
-                    latin:keyWidth="30%p" />
-                <switch>
-                    <case
-                        latin:webInput="true"
-                    >
-                         <Key
-                            latin:keyHintIcon="@drawable/hint_popup"
-                            latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
-                            latin:maxPopupKeyboardColumn="8"
-                            latin:keyStyle="tabKeyStyle" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyLabel="."
-                            latin:keyHintIcon="@drawable/hint_popup"
-                            latin:popupCharacters="@string/alternates_for_punctuation"
-                            latin:maxPopupKeyboardColumn="7"
-                            latin:keyStyle="functionalKeyStyle" />
-                    </default>
-                </switch>
-                <switch>
-                    <case
-                        latin:mode="im"
-                    >
-                        <Key
-                            latin:keyStyle="smileyKeyStyle"
-                            latin:keyWidth="25%p"
-                            latin:keyEdgeFlags="right" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyStyle="returnKeyStyle"
-                            latin:keyWidth="25%p"
-                            latin:keyEdgeFlags="right" />
-                    </default>
-                </switch>
+                    latin:keyWidth="40%p" />
+            </default>
+        </switch>
+        <switch>
+            <case
+                latin:webInput="true"
+            >
+                <Key
+                    latin:keyHintIcon="@drawable/hint_popup"
+                    latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
+                    latin:maxPopupKeyboardColumn="8"
+                    latin:keyStyle="tabKeyStyle" />
+            </case>
+            <default>
+                <Key
+                    latin:keyLabel="."
+                    latin:keyHintIcon="@drawable/hint_popup"
+                    latin:popupCharacters="@string/alternates_for_punctuation"
+                    latin:maxPopupKeyboardColumn="7"
+                    latin:keyStyle="functionalKeyStyle" />
+            </default>
+        </switch>
+        <switch>
+            <case
+                latin:mode="im"
+            >
+                <Key
+                    latin:keyStyle="smileyKeyStyle"
+                    latin:keyWidth="fillRight"
+                    latin:keyEdgeFlags="right" />
             </case>
+            <default>
+                <Key
+                    latin:keyStyle="returnKeyStyle"
+                    latin:keyWidth="fillRight"
+                    latin:keyEdgeFlags="right" />
+            </default>
         </switch>
     </Row>
 </merge>
diff --git a/java/res/xml/kbd_qwerty_rows_scandinavia.xml b/java/res/xml/kbd_qwerty_rows_scandinavia.xml
index 06bb286a2d..8cb0640e57 100644
--- a/java/res/xml/kbd_qwerty_rows_scandinavia.xml
+++ b/java/res/xml/kbd_qwerty_rows_scandinavia.xml
@@ -71,7 +71,7 @@
             latin:popupCharacters="@string/alternates_for_p" />
         <Key
             latin:keyLabel="Ã¥"
-            latin:keyWidth="8.75%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
@@ -109,7 +109,7 @@
         <Key
             latin:keyLabel="@string/keylabel_for_scandinavia_row2_11"
             latin:popupCharacters="@string/alternates_for_scandinavia_row2_11"
-            latin:keyWidth="8.75%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <include
diff --git a/java/res/xml/kbd_qwertz_rows.xml b/java/res/xml/kbd_qwertz_rows.xml
index 7e8f90e329..603cf351cb 100644
--- a/java/res/xml/kbd_qwertz_rows.xml
+++ b/java/res/xml/kbd_qwertz_rows.xml
@@ -68,6 +68,7 @@
             latin:keyLabel="p"
             latin:keyHintIcon="@drawable/key_hint_num0"
             latin:popupCharacters="@string/alternates_for_p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <include
@@ -100,7 +101,7 @@
             latin:keyLabel="m" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="15%p"
+            latin:keyWidth="fillRight"
             latin:visualInsetsLeft="1%p"
             latin:keyEdgeFlags="right" />
     </Row>
diff --git a/java/res/xml/kbd_ru_rows.xml b/java/res/xml/kbd_ru_rows.xml
index b992599385..76250a303a 100644
--- a/java/res/xml/kbd_ru_rows.xml
+++ b/java/res/xml/kbd_ru_rows.xml
@@ -71,7 +71,7 @@
             latin:popupCharacters="0" />
         <Key
             latin:keyLabel="Ñ…"
-            latin:keyWidth="8.75%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
@@ -101,7 +101,7 @@
             latin:keyLabel="ж" />
         <Key
             latin:keyLabel="э"
-            latin:keyWidth="8.75%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
@@ -132,7 +132,7 @@
             latin:keyLabel="ÑŽ" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="11.75%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <include
diff --git a/java/res/xml/kbd_sr_rows.xml b/java/res/xml/kbd_sr_rows.xml
index 0aa17d5e4c..139af80f59 100644
--- a/java/res/xml/kbd_sr_rows.xml
+++ b/java/res/xml/kbd_sr_rows.xml
@@ -70,6 +70,7 @@
             latin:popupCharacters="0" />
         <Key
             latin:keyLabel="ш"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
@@ -98,6 +99,7 @@
             latin:keyLabel="ч" />
         <Key
             latin:keyLabel="Ñ›"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
@@ -126,7 +128,7 @@
             latin:keyLabel="ж" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="11.00%p"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <include
diff --git a/java/res/xml/kbd_symbols.xml b/java/res/xml/kbd_symbols.xml
index 0a80689912..a58a51874e 100644
--- a/java/res/xml/kbd_symbols.xml
+++ b/java/res/xml/kbd_symbols.xml
@@ -65,6 +65,7 @@
         <Key
             latin:keyLabel="0"
             latin:popupCharacters="ⁿ,∅"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
@@ -95,6 +96,7 @@
         <Key
             latin:keyLabel=")"
             latin:popupCharacters="],},&gt;"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
@@ -126,7 +128,7 @@
             latin:popupCharacters="¿" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="15%p"
+            latin:keyWidth="fillRight"
             latin:visualInsetsLeft="1%p"
             latin:keyEdgeFlags="right" />
     </Row>
diff --git a/java/res/xml/kbd_symbols_row4.xml b/java/res/xml/kbd_symbols_row4.xml
index b330095af5..e701b9cdda 100644
--- a/java/res/xml/kbd_symbols_row4.xml
+++ b/java/res/xml/kbd_symbols_row4.xml
@@ -22,81 +22,72 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
     <Row
+        latin:keyWidth="10%p"
         latin:rowEdgeFlags="bottom"
     >
         <switch>
             <case
-                latin:hasSettingsKey="false"
+                latin:hasSettingsKey="true"
             >
                 <Key
                     latin:keyStyle="toAlphaKeyStyle"
-                    latin:keyWidth="20%p"
+                    latin:keyWidth="15%p"
                     latin:keyEdgeFlags="left" />
+                <Key
+                    latin:keyStyle="settingsKeyStyle" />
                 <include
-                    latin:keyboardLayout="@xml/kbd_symbols_f1" />
+                    latin:keyboardLayout="@xml/kbd_qwerty_f1" />
                 <Key
                     latin:keyStyle="spaceKeyStyle"
-                    latin:keyWidth="40%p" />
-                <Key
-                    latin:keyLabel="."
-                    latin:keyHintIcon="@drawable/hint_popup"
-                    latin:popupCharacters="@string/alternates_for_punctuation"
-                    latin:maxPopupKeyboardColumn="7"
-                    latin:keyStyle="functionalKeyStyle" />
-                <switch>
-                    <case
-                        latin:mode="im"
-                    >
-                        <Key
-                            latin:keyStyle="smileyKeyStyle"
-                            latin:keyWidth="20%p"
-                            latin:keyEdgeFlags="right" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyStyle="returnKeyStyle"
-                            latin:keyWidth="20%p"
-                            latin:keyEdgeFlags="right" />
-                    </default>
-                </switch>
+                    latin:keyWidth="30%p" />
             </case>
-            <case
-                latin:hasSettingsKey="true"
-            >
+            <!-- latin:hasSettingsKey="false" -->
+            <default>
                 <Key
                     latin:keyStyle="toAlphaKeyStyle"
-                    latin:keyWidth="15%p"
+                    latin:keyWidth="20%p"
                     latin:keyEdgeFlags="left" />
-                <Key
-                    latin:keyStyle="settingsKeyStyle" />
                 <include
                     latin:keyboardLayout="@xml/kbd_symbols_f1" />
                 <Key
                     latin:keyStyle="spaceKeyStyle"
-                    latin:keyWidth="30%p" />
+                    latin:keyWidth="40%p" />
+            </default>
+        </switch>
+        <switch>
+            <case
+                latin:webInput="true"
+            >
+                <Key
+                    latin:keyHintIcon="@drawable/hint_popup"
+                    latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
+                    latin:maxPopupKeyboardColumn="8"
+                    latin:keyStyle="tabKeyStyle" />
+            </case>
+            <default>
                 <Key
                     latin:keyLabel="."
                     latin:keyHintIcon="@drawable/hint_popup"
                     latin:popupCharacters="@string/alternates_for_punctuation"
                     latin:maxPopupKeyboardColumn="7"
                     latin:keyStyle="functionalKeyStyle" />
-                <switch>
-                    <case
-                        latin:mode="im"
-                    >
-                        <Key
-                            latin:keyStyle="smileyKeyStyle"
-                            latin:keyWidth="25%p"
-                            latin:keyEdgeFlags="right" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyStyle="returnKeyStyle"
-                            latin:keyWidth="25%p"
-                            latin:keyEdgeFlags="right" />
-                    </default>
-                </switch>
+            </default>
+        </switch>
+        <switch>
+            <case
+                latin:mode="im"
+            >
+                <Key
+                    latin:keyStyle="smileyKeyStyle"
+                    latin:keyWidth="fillRight"
+                    latin:keyEdgeFlags="right" />
             </case>
+            <default>
+                <Key
+                    latin:keyStyle="returnKeyStyle"
+                    latin:keyWidth="fillRight"
+                    latin:keyEdgeFlags="right" />
+            </default>
         </switch>
     </Row>
 </merge>
diff --git a/java/res/xml/kbd_symbols_shift.xml b/java/res/xml/kbd_symbols_shift.xml
index cde07333b5..96e741bbc3 100644
--- a/java/res/xml/kbd_symbols_shift.xml
+++ b/java/res/xml/kbd_symbols_shift.xml
@@ -63,6 +63,7 @@
             latin:keyLabel="{" />
         <Key
             latin:keyLabel="}"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
@@ -94,6 +95,7 @@
             latin:keyLabel="[" />
         <Key
             latin:keyLabel="]"
+            latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row>
@@ -125,7 +127,7 @@
             latin:popupCharacters="≥,»,›" />
         <Key
             latin:keyStyle="deleteKeyStyle"
-            latin:keyWidth="15%p"
+            latin:keyWidth="fillRight"
             latin:visualInsetsLeft="1%p"
             latin:keyEdgeFlags="right" />
     </Row>
diff --git a/java/res/xml/kbd_symbols_shift_row4.xml b/java/res/xml/kbd_symbols_shift_row4.xml
index 4f8567d58a..7376bab176 100644
--- a/java/res/xml/kbd_symbols_shift_row4.xml
+++ b/java/res/xml/kbd_symbols_shift_row4.xml
@@ -22,79 +22,70 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
     <Row
+        latin:keyWidth="10%p"
         latin:rowEdgeFlags="bottom"
     >
         <switch>
             <case
-                latin:hasSettingsKey="false"
+                latin:hasSettingsKey="true"
             >
                 <Key
                     latin:keyStyle="toAlphaKeyStyle"
-                    latin:keyWidth="20%p"
+                    latin:keyWidth="15%p"
                     latin:keyEdgeFlags="left" />
+                <Key
+                    latin:keyStyle="settingsKeyStyle" />
                 <Key
                     latin:keyLabel="„"
                     latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
                     latin:keyStyle="nonPasswordFunctionalKeyStyle" />
                 <Key
                     latin:keyStyle="spaceKeyStyle"
-                    latin:keyWidth="40%p" />
-                <Key
-                    latin:keyLabel="…"
-                    latin:keyStyle="nonPasswordFunctionalKeyStyle" />
-                <switch>
-                    <case
-                        latin:mode="im"
-                    >
-                        <Key
-                            latin:keyStyle="smileyKeyStyle"
-                            latin:keyWidth="20%p"
-                            latin:keyEdgeFlags="right" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyStyle="returnKeyStyle"
-                            latin:keyWidth="20%p"
-                            latin:keyEdgeFlags="right" />
-                    </default>
-                </switch>
+                    latin:keyWidth="30%p" />
             </case>
-            <case
-                latin:hasSettingsKey="true"
-            >
+            <!-- latin:hasSettingsKey="false" -->
+            <default>
                 <Key
                     latin:keyStyle="toAlphaKeyStyle"
-                    latin:keyWidth="15%p"
+                    latin:keyWidth="20%p"
                     latin:keyEdgeFlags="left" />
-                <Key
-                    latin:keyStyle="settingsKeyStyle" />
                 <Key
                     latin:keyLabel="„"
                     latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
                     latin:keyStyle="nonPasswordFunctionalKeyStyle" />
                 <Key
                     latin:keyStyle="spaceKeyStyle"
-                    latin:keyWidth="30%p" />
+                    latin:keyWidth="40%p" />
+            </default>
+        </switch>
+        <switch>
+            <case
+                latin:webInput="true"
+            >
+                <Key
+                    latin:keyStyle="tabKeyStyle" />
+            </case>
+            <default>
                 <Key
                     latin:keyLabel="…"
                     latin:keyStyle="nonPasswordFunctionalKeyStyle" />
-                <switch>
-                    <case
-                        latin:mode="im"
-                    >
-                        <Key
-                            latin:keyStyle="smileyKeyStyle"
-                            latin:keyWidth="25%p"
-                            latin:keyEdgeFlags="right" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyStyle="returnKeyStyle"
-                            latin:keyWidth="25%p"
-                            latin:keyEdgeFlags="right" />
-                    </default>
-                </switch>
+            </default>
+        </switch>
+        <switch>
+            <case
+                latin:mode="im"
+            >
+                <Key
+                    latin:keyStyle="smileyKeyStyle"
+                    latin:keyWidth="fillRight"
+                    latin:keyEdgeFlags="right" />
             </case>
+            <default>
+                <Key
+                    latin:keyStyle="returnKeyStyle"
+                    latin:keyWidth="fillRight"
+                    latin:keyEdgeFlags="right" />
+            </default>
         </switch>
     </Row>
 </merge>
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index ef86d66ade..cb529461af 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -101,6 +101,10 @@ public class Key {
     /** Key is enabled and responds on press */
     public boolean mEnabled = true;
 
+    // keyWidth constants
+    private static final int KEYWIDTH_FILL_RIGHT = 0;
+    private static final int KEYWIDTH_FILL_BOTH = -1;
+
     private final static int[] KEY_STATE_NORMAL_ON = {
         android.R.attr.state_checkable,
         android.R.attr.state_checked
@@ -140,7 +144,7 @@ public class Key {
     };
 
     /**
-     * This constructor is being used only for key in mini popup keyboard.
+     * This constructor is being used only for key in popup mini keyboard.
      */
     public Key(Resources res, Keyboard keyboard, CharSequence popupCharacter, int x, int y,
             int width, int height, int edgeFlags) {
@@ -178,6 +182,7 @@ public class Key {
      * @param x the x coordinate of the top-left
      * @param y the y coordinate of the top-left
      * @param parser the XML parser containing the attributes for this key
+     * @param keyStyles active key styles set
      */
     public Key(Resources res, Row row, int x, int y, XmlResourceParser parser,
             KeyStyles keyStyles) {
@@ -185,6 +190,7 @@ public class Key {
 
         final TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
                 R.styleable.Keyboard);
+        int keyWidth;
         try {
             mHeight = KeyboardParser.getDimensionOrFraction(keyboardAttr,
                     R.styleable.Keyboard_rowHeight,
@@ -192,17 +198,13 @@ public class Key {
             mGap = KeyboardParser.getDimensionOrFraction(keyboardAttr,
                     R.styleable.Keyboard_horizontalGap,
                     mKeyboard.getDisplayWidth(), row.mDefaultHorizontalGap);
-            mWidth = KeyboardParser.getDimensionOrFraction(keyboardAttr,
+            keyWidth = KeyboardParser.getDimensionOrFraction(keyboardAttr,
                     R.styleable.Keyboard_keyWidth,
-                    mKeyboard.getDisplayWidth(), row.mDefaultWidth) - mGap;
+                    mKeyboard.getDisplayWidth(), row.mDefaultWidth);
         } finally {
             keyboardAttr.recycle();
         }
 
-        // Horizontal gap is divided equally to both sides of the key.
-        mX = x + mGap / 2;
-        mY = y;
-
         final TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
                 R.styleable.Keyboard_Key);
         try {
@@ -216,6 +218,35 @@ public class Key {
                 style = keyStyles.getEmptyKeyStyle();
             }
 
+            final int keyboardWidth = mKeyboard.getDisplayWidth();
+            int keyXPos = KeyboardParser.getDimensionOrFraction(keyAttr,
+                    R.styleable.Keyboard_Key_keyXPos, keyboardWidth, x);
+            if (keyXPos < 0) {
+                // If keyXPos is negative, the actual x-coordinate will be k + keyXPos.
+                keyXPos += keyboardWidth;
+                if (keyXPos < x) {
+                    // keyXPos shouldn't be less than x because drawable area for this key starts
+                    // at x. Or, this key will overlaps the adjacent key on its left hand side.
+                    keyXPos = x;
+                }
+            }
+            if (keyWidth == KEYWIDTH_FILL_RIGHT) {
+                // If keyWidth is zero, the actual key width will be determined to fill out the
+                // area up to the right edge of the keyboard.
+                keyWidth = keyboardWidth - keyXPos;
+            } else if (keyWidth <= KEYWIDTH_FILL_BOTH) {
+                // If keyWidth is negative, the actual key width will be determined to fill out the
+                // area between the nearest key on the left hand side and the right edge of the
+                // keyboard.
+                keyXPos = x;
+                keyWidth = keyboardWidth - keyXPos;
+            }
+
+            // Horizontal gap is divided equally to both sides of the key.
+            mX = keyXPos + mGap / 2;
+            mY = y;
+            mWidth = keyWidth - mGap;
+
             final CharSequence[] popupCharacters = style.getTextArray(keyAttr,
                     R.styleable.Keyboard_Key_popupCharacters);
             if (res.getBoolean(R.bool.config_digit_popup_characters_enabled)) {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 88d23985a9..7c03ec71e2 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -159,7 +159,7 @@ public class KeyboardId {
 
     @Override
     public String toString() {
-        return String.format("[%s.xml %s %s%d %s %s %s %s%s%s%s%s%s]",
+        return String.format("[%s.xml %s %s%d %s %s %s%s%s%s%s%s%s]",
                 mXmlName,
                 mLocale,
                 (mOrientation == 1 ? "port" : "land"), mWidth,
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
index 43d9f271f2..4ae0113473 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
@@ -280,7 +280,7 @@ public class KeyboardParser {
                 if (TAG_KEY.equals(tag)) {
                     parseKey(parser, row, keys);
                 } else if (TAG_SPACER.equals(tag)) {
-                    parseSpacer(parser, keys);
+                    parseSpacer(parser, row, keys);
                 } else if (TAG_INCLUDE.equals(tag)) {
                     parseIncludeRowContent(parser, row, keys);
                 } else if (TAG_SWITCH.equals(tag)) {
@@ -327,19 +327,32 @@ public class KeyboardParser {
         }
     }
 
-    private void parseSpacer(XmlResourceParser parser, List<Key> keys)
+    private void parseSpacer(XmlResourceParser parser, Row row, List<Key> keys)
             throws XmlPullParserException, IOException {
         if (keys == null) {
             checkEndTag(TAG_SPACER, parser);
         } else {
             if (DEBUG) Log.d(TAG, String.format("<%s />", TAG_SPACER));
-            final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
+            final TypedArray keyboardAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
                     R.styleable.Keyboard);
-            final int gap = getDimensionOrFraction(a, R.styleable.Keyboard_horizontalGap,
-                    mKeyboard.getDisplayWidth(), 0);
-            a.recycle();
+            if (keyboardAttr.hasValue(R.styleable.Keyboard_horizontalGap))
+                throw new IllegalAttribute(parser, "horizontalGap");
+            final int defaultWidth = (row != null) ? row.mDefaultWidth : 0;
+            final int keyWidth = getDimensionOrFraction(keyboardAttr, R.styleable.Keyboard_keyWidth,
+                    mKeyboard.getDisplayWidth(), defaultWidth);
+            keyboardAttr.recycle();
+
+            final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
+                    R.styleable.Keyboard_Key);
+            int keyXPos = KeyboardParser.getDimensionOrFraction(keyAttr,
+                    R.styleable.Keyboard_Key_keyXPos, mKeyboard.getDisplayWidth(), mCurrentX);
+            if (keyXPos < 0) {
+                // If keyXPos is negative, the actual x-coordinate will be display_width + keyXPos.
+                keyXPos += mKeyboard.getDisplayWidth();
+            }
+
             checkEndTag(TAG_SPACER, parser);
-            setSpacer(gap);
+            setSpacer(keyXPos, keyWidth);
         }
     }
 
@@ -566,14 +579,14 @@ public class KeyboardParser {
 
     private void startRow(Row row) {
         mCurrentX = 0;
-        setSpacer(mHorizontalEdgesPadding);
+        setSpacer(mCurrentX, mHorizontalEdgesPadding);
         mCurrentRow = row;
     }
 
     private void endRow() {
         if (mCurrentRow == null)
             throw new InflateException("orphant end row tag");
-        setSpacer(mHorizontalEdgesPadding);
+        setSpacer(mCurrentX, mHorizontalEdgesPadding);
         if (mCurrentX > mMaxRowWidth)
             mMaxRowWidth = mCurrentX;
         mCurrentY += mCurrentRow.mDefaultHeight;
@@ -581,7 +594,7 @@ public class KeyboardParser {
     }
 
     private void endKey(Key key) {
-        mCurrentX += key.mGap + key.mWidth;
+        mCurrentX = key.mX + key.mGap + key.mWidth;
     }
 
     private void endKeyboard(int defaultVerticalGap) {
@@ -589,19 +602,23 @@ public class KeyboardParser {
         mTotalHeight = mCurrentY - defaultVerticalGap;
     }
 
-    private void setSpacer(int gap) {
-        mCurrentX += gap;
+    private void setSpacer(int keyXPos, int width) {
+        mCurrentX = keyXPos + width;
     }
 
     public static int getDimensionOrFraction(TypedArray a, int index, int base, int defValue) {
         final TypedValue value = a.peekValue(index);
         if (value == null)
             return defValue;
-        if (value.type == TypedValue.TYPE_DIMENSION) {
-            return a.getDimensionPixelOffset(index, defValue);
-        } else if (value.type == TypedValue.TYPE_FRACTION) {
+        if (value.type == TypedValue.TYPE_FRACTION) {
             // Round it to avoid values like 47.9999 from getting truncated
             return Math.round(a.getFraction(index, base, base, defValue));
+        } else if (value.type == TypedValue.TYPE_DIMENSION) {
+            return a.getDimensionPixelOffset(index, defValue);
+        } else if (value.type >= TypedValue.TYPE_FIRST_INT
+                && value.type <= TypedValue.TYPE_LAST_INT) {
+            // For enum value.
+            return a.getInt(index, defValue);
         }
         return defValue;
     }
@@ -627,6 +644,13 @@ public class KeyboardParser {
         }
     }
 
+    @SuppressWarnings("serial")
+    private static class IllegalAttribute extends ParseException {
+        public IllegalAttribute(XmlResourceParser parser, String attribute) {
+            super("Tag " + parser.getName() + " has illegal attribute " + attribute, parser);
+        }
+    }
+
     @SuppressWarnings("serial")
     private static class NonEmptyTag extends ParseException {
         public NonEmptyTag(String tag, XmlResourceParser parser) {
-- 
GitLab