How to make per-window keyboard layouts with plain XMonad

keyboard-layoutwindowxmonad

I've been using plain XMonad for some time (not combined with KDE/GNome). Currently, I'm switching between keyboard layouts simply by a key combination globally:

[ ((modMask , xK_Scroll_Lock ),
    spawn "setxkbmap -layout us ; xmodmap ~/.Xmodmap")
, ((modMask .|. shiftMask, xK_Scroll_Lock),
    spawn "setxkbmap -layout cz ; xmodmap ~/.Xmodmap") ]

However that's a bit inconvenient. For many windows (i.e. browser, terminal) I need to keep the US layout most of the time. I need the localized layout only for text editors in 99% of cases. And I switch windows/workspaces a lot, so I have to switch the layouts manually almost every time I switch.

Ideally I'd like to achieve:

  • By pressing the key combination I set some kind of flag for the currently focused window.
  • XMonad calls the spawn commands automatically according to the flags when window focus changes.

How to do that (if it's possible)? Thanks for help.

(Bonus: Manage the flags externally by some kind of command from scripts.)

Best Answer

Install kbdd daemon which does the job.

Run this at startup:

kbdd
setxkbmap "us,ua" -option grp:scroll_toggle

That's all!

To display your layout in a widget you can find this Ruby code useful:

  interface = 'ru.gentoo.KbddService'
  member = 'layoutChanged'
  mon = open "| dbus-monitor --monitor \"sender='#{interface}',member='#{member}'\""
  loop do
    str = mon.gets
    if str =~ /layoutChanged/
      lang = mon.gets[/.\Z/] # lang is now either 0 or 1 depending on the current layout
    end
  end
Related Question