Search code examples
common-lispclimstumpwm

CLX, stumpwm, McCLIM keyboard layout locked on startup


I'm using CLX+STUMPWM+McCLIM and when I modify the keyboard layout via "setxkbmap us -variant dvorak -option ctrl:nocaps" the keyboard layout fails to update in my CLIM applications, but updates correctly for everything else (thus, to use COLEMAK I run the appropriate shell command prior to starting up CLIM for the first time).

Thoughts on why this might be?


Solution

  • This appears to be a bug in CLX independently affecting McCLIM and stumpwm.

    For instance, I'm testing the difference between

    setxkbmap -layout us
    

    (querty) and

    setxkbmap -layout fr
    

    (azerty). Running those commands doesn't affect neither stumpwm's input bar, nor Climacs. The default querty remains in effect.

    X server sends keycodes to applications. Applications may interpret these keycodes using the keymap table, which they can request from the server.

    It seems that in CLX the keycode to keysym transformation is carried out by the keycode->keysym function defined in translate.lisp. It calls the display-keyboard-mapping function defined right above it:

    (defun display-keyboard-mapping (display)
      (declare (type display display))
      (declare (clx-values (simple-array keysym (display-max-keycode keysyms-per-keycode))))
      (or (display-keysym-mapping display)
          (setf (display-keysym-mapping display) (keyboard-mapping display))))
    

    Apparently, this function only requests the keymap table once and caches it. Changing it to

    (defun display-keyboard-mapping (display)
      (declare (type display display))
      (declare (clx-values (simple-array keysym (display-max-keycode keysyms-per-keycode))))
      (setf (display-keysym-mapping display) (keyboard-mapping display)))
    

    fixes both the input bar and Climacs. CAVEAT: I don't claim this doesn't break anything else.

    NB: If attempting to run a shell command from stumpwm's input bar using the French layout, mind that ! is positioned on /.