xmonad: xxkb fix (just use kbdd) and lxpanel for tray

Sometimes xxkb "forgets" last layout of inactive windows and when you focus on them again layout is set to one of last active window. This is annoying and also breaks "two_state" mode.

I have partly resolved this problem by using kbdd (v0.5.1 works perfectly, v0.6 is buggy).

What I have in result:
  • Layouts are remembered for each window;
  • I can switch to any layout I want immediately;
  • I can switch between 2 last used layouts.
Cons:
  • Switching between 2 layouts works only if you switch to some layout in every new window manually first (I've submitted a feature request to fix this). Fixed
  • kbdd do not provide indicator for current layout (fixed by using lxpanel).

Steps to configure kbdd:
  1. Install kbdd. I'm using gentoo and kbdd is available in rion overlay so I just emerged it.
  2. (Optional) Completely disable current "layout-change" keys in xorg.conf/setxkbmap/config_panel. This will allow to use this key/combination for "two_state" layout switch.
    •  You'll need to remap CapsLock to some other key if you use it to change layouts. I remapped it to F13 (I don't have this key on keyboard) and Shift-CapsLock  is set to toggle CAPS.
    • xmodmap -e "keycode  66 = F13 Caps_Lock F13 Caps_Lock F13 Caps_Lock"
      This should be placed in some initialization/autostart script (.xinitrc/.bashrc/.zshrc/.bach_profile etc.)
  3. Install and configure xbindkeys (or any other key binding software)
    • Configure xbindkeys by editing .xbindkeysrc:
      
      "dbus-send --dest=ru.gentoo.KbddService /ru/gentoo/KbddService ru.gentoo.kbdd.set_layout uint32:0"
      Mod1+Shift + 1
      
      #ru layout
      "dbus-send --dest=ru.gentoo.KbddService /ru/gentoo/KbddService ru.gentoo.kbdd.set_layout uint32:1"<
      Mod1+Shift + 2
      
      #ua layout
      "dbus-send --dest=ru.gentoo.KbddService /ru/gentoo/KbddService ru.gentoo.kbdd.set_layout uint32:2"
      Mod1+Shift + 3
      
      "dbus-send --dest=ru.gentoo.KbddService /ru/gentoo/KbddService ru.gentoo.kbdd.prev_layout"
      F13
      
      Alt-Shift-1 is set to activate first layout
      Alt-Shift-2 is set to activate second layout
      Alt-Shift-3 is set to activate third layout
      CapsLock (mapped to F13) is set to activate previously used layout.
  4. Place xbindkeys and kbdd in initialization/autostart script
  5. Exit from X server and relogin.
And now it's time to add some indicator to display current layout. I just installed lxpanel (desktop panel from lxde) and added "Keyboard layout switcher" applet into it (right click on panel...). It is lightweight and very configurable (you can place it almost anywhere, you can remove everything from it, add tray icons to it, add startup menu, etc.)

Screenshot (xmobar+lxpanel+emelFM2):
You can also see numlock indicator applet ("1" digit in gray circle). Useful for wireless keyboards

P.S. You can get key/key-combination names for xbindkeys by running
xbindkeys -mk/code>


P.P.S. There are some usefull keysyms that can be used in xmodmap:
ISO_Next_Group, ISO_Next_Group_Lock, ISO_Prev_Group, ISO_First_Group, ISO_Last_Group
.

ISO_Next_Group
is used when layout switching is configured in xorg.conf.

Run
man xmodmap
for more info:
The first keysym is used when no modifier key is pressed in conjunction with this key, the second with Shift, the third when the Mode_switch key is used with this key and the fourth when both the Mode_switch and Shift keys are used
P.P.P.S. If you'd like to use Shift-CapsLock to cycle through all layouts try this:

xmodmap -e "keycode  66 = F13 ISO_Next_Group F13 ISO_Next_Group F13 ISO_Next_Group"