Ubuntu – How to add a new keyboard layout (Custom keyboard layout definition)

keyboard-layoutxkb

I want to copy a keyboard layout in /usr/share/X11/xkb/symbols/ and change it and then produce a new layout from it.

How can I add a new keyboard layout (named e.g. "mylayout")?

Update #1:

Files I changed to add a new layout:

  • /usr/share/X11/xkb/symbols/irwinxp (originally the same as ir):

    // Iranian keyboard layout
    
    ////////////////////////////////////////
    // Persian layout,
    // based on
    // Information Technology – Layout of Persian Letters and Symbols on Computer Keyboards
    // ISIRI 9147 – 1st Edition
    // Institute of Standards and Industrial Research of Iran
    // http://www.isiri.org/UserStd/DownloadStd.aspx?id=9147
    // http://behnam.esfahbod.info/standards/isiri-keyboard-9147.pdf
    //
    // Author: Behnam Esfahbod <behnam@esfahbod.info>
    //
    
    default  partial alphanumeric_keys
    xkb_symbols "pes" {
        name[Group1]= "Persian";
    
        include "ir(pes_part_basic)"
        include "ir(pes_part_ext)"
    
        include "nbsp(zwnj2nb3nnb4)"
        include "level3(ralt_switch)"
    };
    
    
    partial alphanumeric_keys
    xkb_symbols "pes_keypad" {
        name[Group1]= "Persian (with Persian Keypad)";
    
        include "ir(pes_part_basic)"
        include "ir(pes_part_keypad)"
    
        include "nbsp(zwnj2nb3nnb4)"
        include "level3(ralt_switch)"
    };
    
    partial hidden alphanumeric_keys
    xkb_symbols "pes_part_basic" {
    
        // Persian digits
        key <AE01> { [ Farsi_1, exclam,     grave           ] };
        key <AE02> { [ Farsi_2, 0x100066c,  at          ] };
        key <AE03> { [ Farsi_3, 0x100066b,  numbersign      ] };
        key <AE04> { [ Farsi_4, 0x100fdfc,  dollar          ] };
        key <AE05> { [ Farsi_5, 0x100066a,  percent         ] };
        key <AE06> { [ Farsi_6, multiply,   asciicircum     ] };
        key <AE07> { [ Farsi_7, Arabic_comma,   ampersand       ] };
        key <AE08> { [ Farsi_8, asterisk,   enfilledcircbullet  ] };
        key <AE09> { [ Farsi_9, parenright, 0x100200e       ] };
        key <AE10> { [ Farsi_0, parenleft,  0x100200f       ] };
    
        // Persian letters and symbols
        key <AD01> { [ Arabic_dad,      Arabic_fathatan,    degree      ] }; // 2: Arabic_sukun
        key <AD02> { [ Arabic_sad,      Arabic_dammatan,    VoidSymbol  ] }; // 2: Arabic_dammatan
        key <AD03> { [ Arabic_theh,     Arabic_kasratan,    0x13a4      ] }; // 2: Arabic_kasratan
        key <AD04> { [ Arabic_qaf,      Arabic_fathatan,    VoidSymbol  ] };
        key <AD05> { [ Arabic_feh,      Arabic_comma,       VoidSymbol  ] }; // 2: Arabic_damma
        key <AD06> { [ Arabic_ghain,    Arabic_semicolon,   VoidSymbol  ] }; // 2: Arabic_kasra
        key <AD07> { [ Arabic_ain,      Arabic_fatha,       VoidSymbol  ] };
        key <AD08> { [ Arabic_heh,      Arabic_hamza_above, 0x100202d   ] }; // 2: Arabic_shadda
        key <AD09> { [ Arabic_khah,     bracketright,       0x100202e   ] };
        key <AD10> { [ Arabic_hah,      bracketleft,        0x100202c   ] };
        key <AD11> { [ Arabic_jeem,     braceright,     0x100202a   ] };
        key <AD12> { [ Arabic_tcheh,    braceleft,      0x100202b   ] };
    
        key <AC01> { [ Arabic_sheen,    Arabic_fatha,       VoidSymbol  ] }; // 2: Arabic_hamzaonwaw
        key <AC02> { [ Arabic_seen,     Arabic_damma,       VoidSymbol  ] }; // 2: Arabic_hamzaonyeh
        key <AC03> { [ Farsi_yeh,       Arabic_kasra,       Arabic_alefmaksura ] }; // 2: Arabic_yeh
        key <AC04> { [ Arabic_beh,      Arabic_shadda,  VoidSymbol  ] }; // 1: Arabic_hamzaunderalef
        key <AC05> { [ Arabic_lam,      0x10006c0,  VoidSymbol  ] };// 2: Arabic_hamzaonalef
        key <AC06> { [ Arabic_alef,     Arabic_maddaonalef, 0x1000671   ] };
        key <AC07> { [ Arabic_teh,      Arabic_tehmarbuta,  VoidSymbol  ] };
        key <AC08> { [ Arabic_noon,     guillemotright,     0x100fd3e   ] };
        key <AC09> { [ Arabic_meem,     guillemotleft,      0x100fd3f   ] };
        key <AC10> { [ Arabic_keheh,    colon,          semicolon   ] };
        key <AC11> { [ Arabic_gaf,      quotedbl,       quotedbl    ] }; // 2: Arabic_semicolon
    
        key <AB01> { [ Arabic_zah,      Arabic_kaf,     VoidSymbol  ] };
        key <AB02> { [ Arabic_tah,      0x1000653,      VoidSymbol  ] };
        key <AB03> { [ Arabic_zain,     Arabic_jeh,     VoidSymbol  ] };
        key <AB04> { [ Arabic_ra,       Arabic_hamzaonwaw   ,0x1000656  ] }; // 2: Arabic_superscript_alef ٰ
        key <AB05> { [ Arabic_thal,     0x100200c,      0x100200d   ] };
        key <AB06> { [ Arabic_dal,      Arabic_hamza_above, Arabic_hamza_below  ] };
        key <AB07> { [ Arabic_hamzaonyeh,   Arabic_hamza,       ellipsis    ] }; // 1: Arabic_peh
        key <AB08> { [ Arabic_waw,      greater,        comma       ] };
        key <AB09> { [ period,      less,           apostrophe  ] };
        key <AB10> { [ slash,       Arabic_question_mark,   question    ] };
    
        key <TLDE> { [ 0x100200d,       division,       asciitilde  ] };
        key <AE11> { [ minus,       Arabic_tatweel,     underscore  ] };
        key <AE12> { [ equal,       plus,           0x1002212   ] };
        key <BKSL> { [ Arabic_peh,      bar,            0x1002010   ] }; // 1: backslash
    };
    
    partial hidden alphanumeric_keys
    xkb_symbols "pes_part_ext" {
    
        // Persian and ASCII digits
        key <AE01> { [ 0x10006f1,   exclam,     grave,          1   ] };
        key <AE02> { [ 0x10006f2,   0x100066c,  at,         2   ] };
        key <AE03> { [ 0x10006f3,   0x100066b,  numbersign,     3   ] };
        key <AE04> { [ 0x10006f4,   0x100fdfc,  dollar,         4   ] };
        key <AE05> { [ 0x10006f5,   0x100066a,  percent,        5   ] };
        key <AE06> { [ 0x10006f6,   multiply,   asciicircum,        6   ] };
        key <AE07> { [ 0x10006f7,   Arabic_comma,   ampersand,      7   ] };
        key <AE08> { [ 0x10006f8,   asterisk,   enfilledcircbullet, 8   ] };
        key <AE09> { [ 0x10006f9,   parenright, 0x100200e,      9   ] };
        key <AE10> { [ 0x10006f0,   parenleft,  0x100200f,      0   ] };
    };
    
    partial hidden alphanumeric_keys
    xkb_symbols "pes_part_keypad" {
    
        // Persian digits and Mathematical operators
        key <KPDV> { [ division,    XF86_Ungrab ] };
        key <KPMU> { [ multiply,    XF86_ClearGrab  ] };
        key <KPSU> { [ 0x1002212,   XF86_Prev_VMode ] };
        key <KPAD> { [ plus,    XF86_Next_VMode ] };
    
        key <KPEN> { [ KP_Enter ] };
        key <KPEQ> { [ equal    ] };
    
        key <KP7>  { [ KP_Home, 0x10006f7   ] };
        key <KP8>  { [ KP_Up,   0x10006f8   ] };
        key <KP9>  { [ KP_Prior,    0x10006f9   ] };
    
        key <KP4>  { [ KP_Left, 0x10006f4   ] };
        key <KP5>  { [ KP_Begin,    0x10006f5   ] };
        key <KP6>  { [ KP_Right,    0x10006f6   ] };
    
        key <KP1>  { [ KP_End,  0x10006f1   ] };
        key <KP2>  { [ KP_Down, 0x10006f2   ] };
        key <KP3>  { [ KP_Next, 0x10006f3   ] };
    
        key <KP0>  { [ KP_Insert,   0x10006f0   ] };
        key <KPDL> { [ KP_Delete,   0x100066b   ] };
    };
    
    
    ////////////////////////////////////////
    // Kurdish Layout
    
    partial alphanumeric_keys
    xkb_symbols "ku" {
        include "tr(ku)"
        name[Group1]= "Kurdish (Iran, Latin Q)";
    };
    
    partial alphanumeric_keys
    xkb_symbols "ku_f" {
        include "tr(ku_f)"
        name[Group1]= "Kurdish (Iran, F)";
    };
    
    partial alphanumeric_keys
    xkb_symbols "ku_alt" {
        include "tr(ku_alt)"
        name[Group1]= "Kurdish (Iran, Latin Alt-Q)";
    };
    
    ////////////////////////////////////////
    // Kurdish Soranî Bahdînî (Arabic) keyboard layout,
    // based on the Kurdî Soranî Bahdînî keyboard from KurdITGroup
    // which is based on National Iranian Keyboard Standard (ISIRI 2901:1994),
    // with additions.
    //
    // Copyright (C) 2006 Erdal Ronahî, published under the GPL v2
    //
    // Special copyright note: author explicitly permitted to license this 
    // layout under MIT/X11 license, for details see
    // https://bugs.freedesktop.org/show_bug.cgi?id=9541
    //
    // Author: Erdal Ronahî  <erdal.ronahi@gmail.com>
    //
    // Kurdish Arabic-Latin Layout for Soranî
    
    partial alphanumeric_keys
    xkb_symbols "ku_ara" {
        name[Group1]= "Kurdish (Iran, Arabic-Latin)";
    
        // Other 3-Level symbols
        key <TLDE> { [ 0x100200d,       division,       asciitilde  ] };
        key <BKSL> { [ backslash,       bar,            ccedilla, Ccedilla  ] };
    
        // Digits
        key <AE01> { [ 1,   exclam,     0x10006f1,  grave       ] };
        key <AE02> { [ 2,   at,         0x10006f2,  at      ] };
        key <AE03> { [ 3,   numbersign, 0x10006f3,  0x100066b   ] };
        key <AE04> { [ 4,   dollar,     0x10006f4,  0x100fdfc   ] };
        key <AE05> { [ 5,   percent,    0x10006f5,  0x100066a   ] };
        key <AE06> { [ 6,   asciicircum,    0x10006f6,  multiply    ] };
        key <AE07> { [ 7,   ampersand,  0x10006f7,  Arabic_comma    ] };
        key <AE08> { [ 8,   asterisk,   0x10006f8,  enfilledcircbullet  ] };
        key <AE09> { [ 9,   parenright, 0x10006f9,  0x100200e   ] };
        key <AE10> { [ 0,   parenleft,  0x10006f0,  0x100200f   ] };
        key <AE11> { [ minus,       Arabic_tatweel,     underscore  ] };
        key <AE12> { [ equal,       plus,           0x1002212   ] };
    
        key <AD01> { [         Arabic_qaf,            X,  q,  Q ] };
        key <AD02> { [         Arabic_waw,            X,  w,  W ] };
        key <AD03> { [          0x10006d5,   Arabic_heh,  e,  E ] };
        key <AD04> { [         Arabic_ra ,    0x1000695,  r,  R ] };
        key <AD05> { [         Arabic_teh,   Arabic_tah,  t,  T ] };
        key <AD06> { [          0x10006cc,    0x10006ce,  y,  Y ] };
        key <AD07> { [  Arabic_hamzaonyeh, Arabic_hamza,  u,  U ] };
        key <AD08> { [         Arabic_hah,   Arabic_ain,  i,  I ] };
        key <AD09> { [          0x10006c6, Arabic_hamzaonwaw,  o,  O ] };
        key <AD10> { [          0x100067e,  Arabic_theh,  p,  P ] };
        key <AD11> { [ bracketright,    braceright, ucircumflex, Ucircumflex    ] };
        key <AD12> { [ bracketleft,     braceleft,  scedilla, Scedilla  ] };
    
        key <AC01> { [ Arabic_alef, Arabic_maddaonalef, a, A    ] };
        key <AC02> { [ Arabic_seen,     Arabic_sheen,   s, S    ] };
        key <AC03> { [  Arabic_dal,     Arabic_thal,    d, D    ] };
        key <AC04> { [  Arabic_feh, Arabic_hamzaunderalef,  f, F    ] };
        key <AC05> { [   0x10006af,     Arabic_ghain,   g, G    ] };
        key <AC06> { [  Arabic_heh,     0x100200c,  h, H    ] };
        key <AC07> { [   0x1000698, Arabic_hamzaonalef, j, J    ] };
        key <AC08> { [   0x10006a9,     Arabic_kaf, k, K    ] };
        key <AC09> { [  Arabic_lam,     0x10006b5,  l, L    ] };
        key <AC10> { [  Arabic_semicolon,   colon,      ecircumflex, Ecircumflex    ] };
        key <AC11> { [  apostrophe,     quotedbl,   icircumflex, Icircumflex    ] };
    
        key <AB01> { [ Arabic_zain,     Arabic_dad, z, Z    ] };
        key <AB02> { [ Arabic_khah,     Arabic_sad, x, X    ] };
        key <AB03> { [ Arabic_jeem,     0x1000686,  c, C    ] };
        key <AB04> { [   0x10006a4,     Arabic_zah, v, V    ] };
        key <AB05> { [ Arabic_beh,      0x1000649,  b, B    ] };
        key <AB06> { [ Arabic_noon, Arabic_tehmarbuta,  n, N    ] };
        key <AB07> { [ Arabic_meem, Arabic_tatweel,     m, M    ] };
        key <AB08> { [ Arabic_comma,    greater,    comma       ] };
        key <AB09> { [ period,      less,       apostrophe  ] };
        key <AB10> { [ slash,       Arabic_question_mark,   question    ] };
    
        include "nbsp(zwnj2nb3)"
        include "level3(ralt_switch)"
    };
    
    // EXTRAS:
    
    /////////////////////////////////////////////////////////////////////////////////
    //
    // Generated keyboard layout file with the Keyboard Layout Editor.
    // For more about the software, see http://code.google.com/p/keyboardlayouteditor
    //
    // Version 0.2, fixed AD09.
    //
    // Layout by Ernst Tremel, http://ubuntuforums.org/showpost.php?p=9365469&postcount=32
    // Creation of this file by Simos Xenitellis.
    
    partial alphanumeric_keys
    xkb_symbols "ave"
    {
        name[Group1] = "Avestan";
    
        key <AB01> { [ U10B30,         U10B32 ] }; // ? ? 
        key <AB02> { [ U10B11,         U10B12 ] }; // ? ? 
        key <AB03> { [ U10B17,          UE102 ] }; // ?  
        key <AB04> { [ U10B2C,         U10B13 ] }; // ? ? 
        key <AB05> { [ U10B20,         U10B21 ] }; // ? ? 
        key <AB06> { [ U10B25,         U10B27 ] }; // ? ? 
        key <AB07> { [ U10B28,         U10B29 ] }; // ? ? 
        key <AB08> { [ U10B3C,         U10B39 ] }; // ? ? 
        key <AB09> { [ U10B3E,         U10B3D ] }; // ? ? 
        key <AB10> { [ U10B3F, periodcentered ] }; // ? · 
    
        key <AC01> { [ U10B00,         U10B01 ] }; // ? ? 
        key <AC02> { [ U10B2F,         U10B31 ] }; // ? ? 
        key <AC03> { [ U10B1B,         U10B1C ] }; // ? ? 
        key <AC04> { [ U10B1F,         U10B16 ] }; // ? ? 
        key <AC05> { [ U10B14,         U10B15 ] }; // ? ? 
        key <AC06> { [ U10B35,          UE100 ] }; // ?  
        key <AC07> { [ U10B18,         U10B24 ] }; // ? ? 
        key <AC08> { [ U10B10,          UE101 ] }; // ?  
        key <AC09> { [ U10B2E,          UE103 ] }; // ?  
        key <AC10> { [ U10B3B,         U10B3A ] }; // ? ? 
        key <AC11> { [ U10B1D                 ] }; // ? 
    
        key <AD01> { [ U10B22,         U10B23 ] }; // ? ? 
        key <AD02> { [ U10B33,         U10B34 ] }; // ? ? 
        key <AD03> { [ U10B08,         U10B09 ] }; // ? ? 
        key <AD04> { [ U10B2D,         U10B26 ] }; // ? ? 
        key <AD05> { [ U10B19,         U10B1A ] }; // ? ? 
        key <AD06> { [ U10B2B,         U10B2A ] }; // ? ? 
        key <AD07> { [ U10B0E,         U10B0F ] }; // ? ? 
        key <AD08> { [ U10B0C,         U10B0D ] }; // ? ? 
        key <AD09> { [ U10B0A,         U10B0B ] }; // ? ?
        key <AD10> { [ U10B1E                 ] }; // ? 
        key <AD11> { [ U10B06,         U10B07 ] }; // ? ? 
        key <AD12> { [ U10B02,         U10B03 ] }; // ? ? 
    
        key <AE01> { [ U10B78                 ] }; // ? 
        key <AE02> { [ U10B79                 ] }; // ? 
        key <AE03> { [ U10B7A                 ] }; // ? 
        key <AE04> { [ U10B7B                 ] }; // ? 
        key <AE05> { [ U10B7C                 ] }; // ? 
        key <AE06> { [ U10B7D                 ] }; // ? 
        key <AE07> { [ U10B7E                 ] }; // ? 
        key <AE08> { [ U10B7F                 ] }; // ? 
    
        key <BKSL> { [ U10B04,         U10B05 ] }; // ? ? 
        key <LSGT> { [ U10B04,         U10B05 ] }; // ? ? 
    };
    
  • Part of /usr/share/X11/xkb/rules/evdev.xml containing all modifications:

    ...
       <layout>
          <configItem>
            <name>ir</name>
    
            <shortDescription>fa</shortDescription>
            <description>Persian</description>
            <languageList>
              <iso639Id>per</iso639Id>
            </languageList>
          </configItem>
          <variantList>
            <variant>
              <configItem>
                <name>pes_keypad</name>
                <description>Persian (with Persian Keypad)</description>
              </configItem>
            </variant>
            <variant>
              <configItem>
                <name>ku</name>
    
                <shortDescription>ku</shortDescription>
                <description>Kurdish (Iran, Latin Q)</description>
                <languageList>
                  <iso639Id>kur</iso639Id>
                </languageList>
              </configItem>
            </variant>
            <variant>
              <configItem>
                <name>ku_f</name>
    
                <shortDescription>ku</shortDescription>
                <description>Kurdish (Iran, F)</description>
                <languageList>
                  <iso639Id>kur</iso639Id>
                </languageList>
              </configItem>
            </variant>
            <variant>
              <configItem>
                <name>ku_alt</name>
    
                <shortDescription>ku</shortDescription>
                <description>Kurdish (Iran, Latin Alt-Q)</description>
                <languageList>
                  <iso639Id>kur</iso639Id>
                </languageList>
              </configItem>
            </variant>
            <variant>
              <configItem>
                <name>ku_ara</name>
    
                <shortDescription>ku</shortDescription>
                <description>Kurdish (Iran, Arabic-Latin)</description>
                <languageList>
                  <iso639Id>kur</iso639Id>
                </languageList>
              </configItem>
            </variant>
          </variantList>
        </layout>    
        <layout>
          <configItem>
            <name>irwinxp</name>
    
            <shortDescription>fa</shortDescription>
            <description>Persian-WinXP</description>
            <languageList>
              <iso639Id>per</iso639Id>
            </languageList>
          </configItem>
          <variantList>
            <variant>
              <configItem>
                <name>pes_keypad</name>
                <description>Persian (with Persian Keypad)</description>
              </configItem>
            </variant>
            <variant>
              <configItem>
                <name>ku</name>
    
                <shortDescription>ku</shortDescription>
                <description>Kurdish (Iran, Latin Q)</description>
                <languageList>
                  <iso639Id>kur</iso639Id>
                </languageList>
              </configItem>
            </variant>
            <variant>
              <configItem>
                <name>ku_f</name>
    
                <shortDescription>ku</shortDescription>
                <description>Kurdish (Iran, F)</description>
                <languageList>
                  <iso639Id>kur</iso639Id>
                </languageList>
              </configItem>
            </variant>
            <variant>
              <configItem>
                <name>ku_alt</name>
    
                <shortDescription>ku</shortDescription>
                <description>Kurdish (Iran, Latin Alt-Q)</description>
                <languageList>
                  <iso639Id>kur</iso639Id>
                </languageList>
              </configItem>
            </variant>
            <variant>
              <configItem>
                <name>ku_ara</name>
    
                <shortDescription>ku</shortDescription>
                <description>Kurdish (Iran, Arabic-Latin)</description>
                <languageList>
                  <iso639Id>kur</iso639Id>
                </languageList>
              </configItem>
            </variant>
          </variantList>
        </layout> 
        <layout>
          <configItem>
            <name>iq</name>
    ...
    

But now, with these changes the new Persian-WinXP layout does not obey irwinxp and irwinxp is igored. Instead ir controls Persian-WinXP.

Update #2:

Unity has a problem with my new layout. The new layout icon is dark. But it works well.

dark layout icon

Note: I use Ubuntu 14.04.

Best Answer

Creating custom keyboard layout

For example, I'm looking to add a new modified English (international AltGr dead keys) US layout with swapped r,R & t,T. I will name it XY swapped:RT English (international AltGr dead keys).

  1. Create new symbols file:

    sudo nano /usr/share/X11/xkb/symbols/xy

     default  partial alphanumeric_keys
     xkb_symbols "basic" {
    
        name[Group1]= "XY swapped:RT English (international AltGr dead keys)";
    
        include "us(altgr-intl)"
    
     // my custom changes:
    
        key <AD04> { [        t, T,           ediaeresis,   Ediaeresis      ] };
        key <AD05> { [        r, R,           thorn,        THORN           ] };
    
    
        include "level3(ralt_switch)"
     };
    

    include "us(altgr-intl)" means it inherits all key from that layout only key overridden here.

    You may use Keyboard Layout Editor which is a GUI program that helps create or edit XKB keyboard layouts. Thanks to @Glutanimate

  2. Add the new layout declaration to /usr/share/X11/xkb/rules/evdev.xml (copy & modify us layout section)

    Reference: Make new variant keyboard layout available in Settings?

    sudo gedit /usr/share/X11/xkb/rules/evdev.xml

     ...
     <layout>
       <configItem>
         <name>xy</name>
    
         <shortDescription>en</shortDescription>
         <description>XY swapped:RT English (international AltGr dead keys)</description>
         <languageList>
                  <iso639Id>eng</iso639Id>
                  <iso639Id>fra</iso639Id>
                  <iso639Id>ger</iso639Id>
         </languageList>
       </configItem>
       <variantList>
       </variantList>
     </layout>
     ...
    
  3. Delete xkb cache.

     sudo rm /var/lib/xkb/*.xkm
    

    Notes:

    To load changes to the layouts menu simply restart gnome-keyboard-preferences; relaunching the window manager should not be necessary.

    There is a change in Ubuntu version 13.10 which causes the keyboard settings cache to not refresh after files in "/usr/share/X11/xkb/symbols" are modified. It looks like changes just don't get applied. To force the cache refreshing a one should delete *.xkm files from "/var/lib/xkb".

    Reference: Howto: Custom keyboard layout definitions

    or

     sudo dpkg-reconfigure xkb-data
    

    Reference: Why did 13.10 break my custom keyboard layout?

    Custom keyboard layout

Reply to fix OP modifications

  • (Update #1 wrong parent layout) You have modified xkb_symbols "pes_part_basic" which is in irwinxp file: that's ok.

    but xkb_symbols "pes" in irwinxp file still:

      include "ir(pes_part_basic)"
    

    which should be:

      include "irwinxp(pes_part_basic)"
    
  • (Update #2 custom icon) If <shortDescription>en</shortDescription> changed to <shortDescription>xy</shortDescription>. So the new layout will distinct from En and it will appear as Xy.

    Most probably there will be no icon for it in ubuntu-mono. Then the indicator will dynamically generate new one which may not follow current theme.

    1. Copy any layout icons for dark/light mono themes:

       sudo cp /usr/share/icons/ubuntu-mono-dark/status/22/indicator-keyboard-En.svg /usr/share/icons/ubuntu-mono-dark/status/22/indicator-keyboard-Xy.svg
       sudo cp /usr/share/icons/ubuntu-mono-light/status/22/indicator-keyboard-En.svg /usr/share/icons/ubuntu-mono-light/status/22/indicator-keyboard-Xy.svg
      
    2. SVG files are just XML. Open then for editing and change text value from En to Xy:

       sudo nano /usr/share/icons/ubuntu-mono-dark/status/22/indicator-keyboard-Xy.svg
       sudo nano /usr/share/icons/ubuntu-mono-light/status/22/indicator-keyboard-Xy.svg
      

      Example:

       <?xml version="1.0" encoding="UTF-8" standalone="no"?>
       <svg width="22" xmlns="http://www.w3.org/2000/svg" version="1.1" height="22">
        <defs>
         <mask id="m">
          <rect y="0" x="0" style="fill:#fff" height="22" width="22"/>
          <text y="15.5" x="5" style="font-size:12;font-family:Ubuntu;font-weight:500;fill:black">Xy</text>
         </mask>
        </defs>
        <rect style="fill:#dfdbd2" mask="url(#m)" rx="2" height="20" width="20" y="1" x="1"/>
       </svg>
      
    3. Update theme cache:

       sudo update-icon-caches /usr/share/icons/ubuntu-mono-*/            
      
    4. Logout/login

      new layout with custom icon

Other Helpful References

Related Question