Configuring VNC Keyboard Layout Mapping for KVM/libvirt Guests on Debian: Solving fr-ch Input Issues


5 views

When working with KVM/libvirt virtualization on Debian systems, there's a common disconnect between VNC clients and keyboard layout handling. The issue manifests specifically when:

  • virt-viewer connections work perfectly with fr-ch layout
  • Standard VNC clients (TigerVNC, RealVNC, etc.) produce garbled input
  • XML configuration changes via virsh edit don't take effect

The root cause lies in how libvirt/QEMU processes keyboard input differently between SPICE and VNC protocols. For VNC, we need explicit keymap configuration at multiple levels:


# Check available QEMU keymaps
ls /usr/share/qemu/keymaps/

# Typical output shows available maps:
en-us    fr       fr-ch    pt-br    ...

Method 1: Permanent XML Configuration

Edit your VM's configuration with proper VNC settings:


sudo virsh edit your_vm_name

# Add/modify these elements:
<graphics type='vnc' port='-1' autoport='yes' keymap='fr-ch' listen='0.0.0.0'>
  <listen type='address' address='0.0.0.0'/>
</graphics>

Method 2: Runtime VNC Configuration

For temporary sessions or testing:


# Start VM with explicit keymap
virt-install \
  --name testvm \
  --ram 2048 \
  --graphics vnc,keymap=fr-ch \
  --disk path=/var/lib/libvirt/images/testvm.qcow2 \
  --cdrom /path/to/iso

Method 3: Client-Side Workarounds

For stubborn cases where server-side config doesn't work:


# TigerVNC client with layout forcing
vncviewer -SendKeyEvents -Keyboard=fr-ch vm-host:port

# Alternative with xkbcomp
setxkbmap -layout fr -variant ch && \
vncviewer vm-host:port
  • Verify QEMU keymap files exist in /usr/share/qemu/keymaps/
  • Check libvirt logs: journalctl -u libvirtd -f
  • Test raw QEMU with: qemu-system-x86_64 -k fr-ch ...

For unsupported layouts, create custom keymaps:


# Base template from existing map
cp /usr/share/qemu/keymaps/en-us /tmp/fr-custom

# Modify keycodes (example excerpt)
0x02 = "&"    # Normally "1" in en-us
0x03 = "é"     # Normally "2" in en-us

# Reference the custom map
<graphics type='vnc' keymap='/tmp/fr-custom' ... >


Understanding the Keyboard Layout Issue in VNC Connections

When working with KVM/libvirt virtualization on Debian systems, keyboard layout synchronization between VNC clients and guest VMs can be particularly problematic. Unlike virt-viewer which handles keymaps automatically, VNC requires explicit configuration at multiple levels.

  1. Libvirt XML configuration: The virtual machine's definition file controls fundamental input settings
  2. QEMU/KVM parameters: Underlying virtualization layer's keyboard handling
  3. VNC server implementation: How the graphical console transmits keycodes
  4. Client-side mapping: The VNC viewer application's interpretation

Here's the definitive configuration that works for French-Swiss keyboard layout:

<domain type='kvm'>
  ...
  <devices>
    <graphics type='vnc' port='-1' autoport='yes' keymap='fr-ch'/>
    <input type='keyboard' bus='ps2'/>
  </devices>
  <qemu:commandline>
    <qemu:arg value='-k'/>
    <qemu:arg value='fr-ch'/>
  </qemu:commandline>
</domain>

After applying these changes:

# Reload the VM configuration
sudo virsh define /etc/libvirt/qemu/myVmGuest.xml

# Check active keymap settings
sudo virsh dumpxml myVmGuest | grep -i keymap

# Test with different VNC clients
vncviewer -PreferredEncoding=ZRLE myvm:5900

Case 1: If special characters still don't work, check the guest OS configuration:

# On Debian/Ubuntu guests
sudo dpkg-reconfigure keyboard-configuration

Case 2: For Windows guests, additional steps may be needed:

  1. Install SPICE guest tools for better input handling
  2. Set the keyboard layout in Control Panel to match the host

For modern guests (Linux 4.5+ or Windows 10+), consider using virtio input devices which handle keymaps more reliably:

<input type='keyboard' bus='virtio'/>
<input type='mouse' bus='virtio'/>