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.
- Libvirt XML configuration: The virtual machine's definition file controls fundamental input settings
- QEMU/KVM parameters: Underlying virtualization layer's keyboard handling
- VNC server implementation: How the graphical console transmits keycodes
- 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:
- Install SPICE guest tools for better input handling
- 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'/>