'Less than' (<), 'more than' (>), and 'pipe' (|) can't be typed via VNC

Bug #1738283 reported by Michal Nowak on 2017-12-14
This bug affects 4 people
Affects Status Importance Assigned to Milestone

Bug Description

If I start QEMU 2.11 (from https://build.opensuse.org/package/show/Virtualization/qemu) VM with VNC, I am unable to type following three characters: 'less than' (<), 'more than' (>), and 'pipe' (|) on en_US QWERTY keyboard. Other characters work fine. QEMu version 2.10.1 worked fine.

/usr/bin/qemu-kvm -m 2048 -cpu kvm64 -drive media=cdrom,if=none,id=cd0,format=raw,file=OI-hipster-minimal-20171031.iso -device ide-cd,drive=cd0 -boot once=d,menu=on,splash-time=5000 -device usb-ehci -device usb-tablet -smp 1 -enable-kvm -vnc :91,share=force-shared

The ISO can be downloaded here: https://www.openindiana.org/download/

Also tried Fedora-Server-dvd-x86_64-25-1.3.iso and it's the same situation.

If I run the same command without '-vnc :91,share=force-shared', everything works just fine.

Michal Nowak (michal-nowak-b) wrote :

Should have mention I use openSUSE Leap 42.3 with above mentioned virtualization repo.

Removed the 0026-Fix-tigervnc-long-press-issue patch and rebuilt QEMU but no change.

But I noticed that if I run the ISO via libvirt and connect to it via virt-manager (virt-manager-1.4.1-4.1.noarch), the keys are there as expected:

/usr/bin/qemu-system-x86_64 -machine accel=kvm -name guest=OI,debug-threads=on -S -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-2-OI/master-key.aes -machine pc-i440fx-2.11,accel=kvm,usb=off,vmport=off,dump-guest-core=off -cpu kvm64 -m 2048 -realtime mlock=off -smp 1,sockets=1,cores=1,threads=1 -uuid 5664149e-26ad-4ee8-8170-16701f107b4b -no-user-config -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain-2-OI/monitor.sock,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=localtime,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet -no-shutdown -global PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -boot strict=on -device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x3.0x7 -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x3 -device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x3.0x1 -device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x3.0x2 -drive file=/var/lib/libvirt/images/OI-hipster-minimal-20171031.iso,format=raw,if=none,id=drive-ide0-0-0,readonly=on -device ide-cd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 -vnc -device VGA,id=video0,vgamem_mb=16,bus=pci.0,addr=0x2 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 -msg timestamp=on

Connection via TigerVNC (tigervnc-1.6.0-21.1.x86_64) to the same VM is unable to write those characters.

Michal Nowak (michal-nowak-b) wrote :

Well, if virt-manager is configured to run the VM with `-k en-us` I can't enter <>| even in virt-manager. keycodemapdb?

Daniel Berrange (berrange) wrote :

By default virt-manager will *not* enable the '-k en-us' argument, because that forces use of a specific keyboard layout in QEMU's VNC server. For that to work, the VNC client keymap must exactly match the QEMU VNC server keymap, and must also exactly match the guest OS keymap.

Instead virt-manager leaves off the "-k en-us" argument, which will cause the VNC servers raw scancode extension to be activated with compatible clients. Virt-manager uses GTK-VNC which activates this extension, and so passes raw XT scancodes from virt-manager to QEMU to the guest OS, which generally makes everything "just work"

IOW, if virt-manager works correctly, but tigerVNC does not work correctly, this probably means that tigervnc is not activating the raw scancode extension.


I confirm the same problem on Fedora 27 Server using Source code release 2.11.0

The problem remains no matter if I use the "-k en-us" parameter or not.

Worked fine up to 2.10.1

If the guess is Windows, then when trying to type the "<" character then the pipe ("|") appears.

If the guess is Linux, the same key produces the ">" character.

Both operating systems use the US English keyboard layout.

Thanks a lot for your time and help.


Michal Nowak (michal-nowak-b) wrote :

If I start QEMU with `-k en-gb` at least '<' and '>' work, '|' doesn't (and obviously 'Shift-2' produces '"' not '@').

My host `locale` is 'en_US.UTF-8' top to bottom.

I tried to update TigerVNC to 1.8 but no change. I run `vncviewer` with '-Log *:stderr:100' and QEMU without '-k' option and at least on the VNC client side it reports expected key code names.

Adam Williamson (awilliamson) wrote :

Aha. This looks like my bug!

I'm running into this in what I suspect is the same situation as Michal Nowak: openQA. But in Fedora. openQA (well, its test runner, os-autoinst) works by running virtual machines and interacting with them over VNC. It seems that with qemu 2.11, typing certain characters doesn't work right, where it worked fine with 2.10. The case I ran into is the < case: when os-autoinst intends to type a < (which it does by sending the keysym for shift and then the keysym 60, for <), it winds up typing a > . This winds up causing os-autoinst's test suite to fail when attempting to build the package on Fedora Rawhide. The test suite passes on Fedora 27 (qemu 2.10).

The qemu command in my test is:

/usr/bin/qemu-system-i386 -serial file:serial0 -soundhw ac97 -vga cirrus -m 1024 -netdev user,id=qanet0 -device virtio-net,netdev=qanet0,mac=52:54:00:12:34:56 -device ide-drive,drive=hd1,serial=1 -drive file=raid/l1,cache=unsafe,if=none,id=hd1,format=qcow2 -drive media=cdrom,if=none,id=cd0,format=raw,file=/builddir/build/BUILD/os-autoinst-25191d50d54eaded10b6b26199bb986728dcd5c2/t/data//Core-7.2.iso -device ide-cd,drive=cd0 -boot once=d,menu=on,splash-time=5000 -smp 1 -no-shutdown -vnc :90,share=force-shared -qmp unix:qmp_socket,server,nowait -monitor unix:hmp_socket,server,nowait -S -monitor telnet:,server,nowait

note there doesn't appear to be any explicit keyboard map setting there.

Adam Williamson (awilliamson) wrote :

Note, os-autoinst is its own VNC client. Most of the implementation can be found in https://github.com/os-autoinst/os-autoinst/blob/master/consoles/VNC.pm . The functions relevant to sending key events are `shift_keys`, `init_x11_keymap`, `map_and_send_key`, and `_send_key_event`.

Adam Williamson (awilliamson) wrote :

I also confirm Michal's observation of virt-manager and tigervnc behaving differently with the same VM: I ran a VM set up with VNC display server in virt-manager and can type < from the virt-manager UI fine, but if I connect to the same VM with tigervnc and try to type < , I get > . This is with current Fedora Rawhide qemu, virt-manager and tigervnc:


Adam Williamson (awilliamson) wrote :

I found something interesting using showkey in the VM. This is all assuming en-US everywhere, note. On a US keyboard, "<" is a shifted comma (shift-,), ">" is a shifted period (shift-.), and "|" is a shifted backslash (shift-\).

If I run showkey and try the affected characters in virt-manager, the results are kinda what I'd expect. It reports keycode 42 for the shift key, keycode 51 for comma key, keycode 52 for period key, and keycode 43 for backslash key. If I do shift-, (to get a <), it shows keycode 42 down, keycode 51 down, keycode 51 up, keycode 42 up - just what you'd expect. Ditto for > and |: it shows 42d/52d/52u/42u and 42d/43d/43u/42u in those cases.

But if I do this while typing in tigervnc, it reports something quite different. Just pressing the keys alone gives the right codes - 51, 52, 43. But when I try the shifted combinations, it reports keycode *86* for all three keys. That is, so long as shift is held down, pressing the comma, period or backslash key reports keycode 86 - not 51, 52 or 43. Somehow this results in the generation of a > character, not sure how.

Adam Williamson (awilliamson) wrote :

I note this block in pc-bios/keymaps/en-us with interest:

# evdev 86 (0x56), QKeyCode "less", number 0x56
less 0x56
greater 0x56 shift
bar 0x56 altgr
brokenbar 0x56 shift altgr

That block was added in commit a7815faffb2bd594b92aa3542d7b799cc89c5414 , which I am very suspicious was the cause of this problem. I strongly suspect that removing it will fix the problem. Will test now.

Adam Williamson (awilliamson) wrote :

FWIW, I think this keycode represents the key between the left shift key and the first letter key on the fourth row, if there is one. European keyboards have one, and on e.g. a UK keyboard it types a \ unshifted and a | shifted - this is exactly how it looks in the en-gb keymap file:

# evdev 86 (0x56), QKeyCode "less", number 0x56
backslash 0x56
bar 0x56 shift
bar 0x56 altgr
brokenbar 0x56 shift altgr

The definition that somehow gets into the en-us keymap file appears to be actually how the key is intended to work on *German* keyboards:


Note how the key is labelled with <, > and | characters there. The French layout has the same key labelled with < and > but not |. So basically it seems like that same definition for this key shows up when you ask xkb for an en_US map.

Bonus historical note: modern US keyboards don't have a key there at all, they're 101/104-key keyboards, where the left shift key is very wide and the key next to it is the first letter key. But *old* US keyboards, specifically the 83-key 'XT' layout, *DID* have a key there!


From that picture, the key was labelled with \ and | characters, like a modern UK keyboard (presumably this is where the modern UK keyboard derived its use for the key from). I wonder if there's a keyboard nerd out there somewhere with a working US XT keyboard who we could ask to press that key and see what keycode it generates...:) I suppose if it's this keycode, we could arguably report a bug in xkb that for en_US, that keycode should work like a modern UK keyboard (backslash / bar / bar / brokenbar), not a modern German keyboard...:)

Adam Williamson (awilliamson) wrote :

Confirmed that dropping the offending keycode 86 definition out of keymaps/en-us fixes the problem. Scratch build for Fedora Rawhide was https://koji.fedoraproject.org/koji/taskinfo?taskID=23814932 , I'll probably send this out as an official build so I can get os-autoinst built without hacking up the tests, but as the files are generated by qemu-keymap just hand editing the file isn't really the 'right' solution for upstream; someone will need to tweak qemu-keymap, or else leave the keymap alone but somehow tweak the relevant bits in qemu/ui/keymaps.c and fix the problem that way.

Adam Williamson (awilliamson) wrote :

Note: I wondered if specifying a correct model for qemu-keymap to pass to xkb would help. But it doesn't :( That is, these:

qemu-keymap -l us
qemu-keymap -l us -m pc101
qemu-keymap -l us -m pc104
qemu-keymap -l us -m pc105

all produce the same output except for the commented-out 'model' line at the top. It appears xkb doesn't really consider the model when deciding what keycodes to include in the generated keymap.

Michal Nowak (michal-nowak-b) wrote :

I found Adam's patch from Fedora Rawhide (https://src.fedoraproject.org/rpms/qemu/c/f81be8f0261cce74799f946e99f23d57f8db7e17?branch=master) when applied to openSUSE's 2.11.0 QEMU effective in openQA as well as manually with vncviewer.

Brian Rak (brak) wrote :

We ran into this as well, using qemu 2.11.0. We're not using the "-k en-us" command line flag, and we're using noVNC as a client (which supports the QEMUExtendedKeyEvent encoding)

Cole Robinson (crobinso) wrote :

FYI this seems to be fixed with qemu.git master, I didn't track down the specific commit but there were several keymap related changes. so qemu 2.12 will be fixed

Changed in qemu:
status: New → Fix Committed
Thomas Huth (th-huth) wrote :

QEMU 2.12 has now been release, so marking this one as "Fix Released".

Changed in qemu:
status: Fix Committed → Fix Released
Adam Williamson (awilliamson) wrote :

Indeed the bug does not exist in this exact form any more, but it seems the stray '86' keymap entry *does* still cause problems in current qemu in one specific case:


basically, if using 'usb-kbd', we still get trouble when openQA (os-autoinst) tries to type a '<' character, because it does this:

shift down
comma down
shift up
comma up

(note it does *not* do shift down, comma down, comma up, shift up), and qemu gets confused and converts that into this sequence of input_event_key_qcode events:

shift down
comma down
shift up
less up

and that seems to mess with the key state and cause any subsequent attempts to type a '<' to go wrong.

Removing the '86' key definition avoids the bug.

Daniel Berrange (berrange) wrote :

Discussing the problem & likely solution here:


Adam Williamson (awilliamson) wrote :

I'm not subscribed there, so will note here: I tried the proposed changes - the commits from https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04819.html , backported to 3.0.0 - and that seems to work. A test which would previously have hit this bug ran OK, without the changes to the en-us keymap.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.