NetBSD Problem Report #60918
From www@netbsd.org Fri Oct 23 02:48:11 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature RSA-PSS (2048 bits) client-digest SHA256)
(Client CN "mail.netbsd.org", Issuer "YR1" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 860E71A923B
for <gnats-bugs@gnats.NetBSD.org>; Fri, 23 Oct 2026 02:48:11 +0000 (UTC)
Message-Id: <20261023024810.331B31A923C@mollari.NetBSD.org>
Date: Fri, 23 Oct 2026 02:48:10 +0000 (UTC)
From: phil@hagelb.org
Reply-To: phil@hagelb.org
To: gnats-bugs@NetBSD.org
Subject: Keyboard modifier keys are not checked correctly when sent simultaneously
X-Send-Pr-Version: www-1.0
X-From4GNATS: "phil@hagelb.org via gnats" <gnats-admin@NetBSD.org>
>Number: 60918
>Category: kern
>Synopsis: Keyboard modifier keys are not checked correctly when sent simultaneously
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Oct 23 02:50:00 +0000 2026
>Last-Modified: Sun Oct 25 08:30:02 +0000 2026
>Originator: Phil Hagelberg
>Release: 11.0
>Organization:
>Environment:
NetBSD coronacht 11.0 NetBSD 11.0 (GENERIC) #0: Thu Jul 30 15:23:12 UTC 2026 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
When a keyboard sends a shift key pressed in one USB frame followed by an A keypress in another frame, it correctly detects that the shift key is pressed, resulting in "A".
But when a keyboard sends a shift *and* an A keypress in the same frame, the A is checked first, resulting in a lowercase "a".
Since the shift key is down when the A key is pressed, it should result in an "A" being inserted, not "a".
>How-To-Repeat:
I don't know any way to reproduce this without special hardware unfortunately. I'm using an Atreus keyboard with the Menelaus firmware: https://git.sr.ht/~technomancy/menelaus where pressing fn+a sends shift+9 (in other words, an open paren) but it just results in a 9 being inserted.
>Fix:
When a USB frame is received, the modifier state should be checked *before* the non-modifier keys, not after.
>Audit-Trail:
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/60918: Keyboard modifier keys are not checked correctly when sent simultaneously
Date: Fri, 23 Oct 2026 06:50:12 -0000 (UTC)
gnats-admin@NetBSD.org ("phil@hagelb.org via gnats") writes:
>When a keyboard sends a shift key pressed in one USB frame followed by an A keypress in another frame, it correctly detects that the shift key is pressed, resulting in "A".
>But when a keyboard sends a shift *and* an A keypress in the same frame, the A is checked first, resulting in a lowercase "a".
The ukbd driver needs to keep track of the key status (== key is held)
that is transmitted via USB HID reports. It then generates events for keys
that are being pressed or released for wskbd.
When you see a modifier and a regular key pressed at the same time,
you get the regular key press first, because it has a lower keycode
than the modifier.
This needs to be handled differently so that modifier events are
passed first to wskbd.
We have a second decoder for USB HID reports that handles key status
for "Dynamic Variable" (used by modifiers) values separate from
"Selectors" (used by regular keys) and transmits the DV events first.
I'm not sure if that is the correct behaviour, but it solves the
problem.
Another possibility is to generate events for the modifier keycodes
224..231 first, or by simply scanning the keycodes in reverse order.
From: Phil Hagelberg <phil@hagelb.org>
To: "Michael van Elst via gnats" <gnats-admin@NetBSD.org>
Cc: kern-bug-people@netbsd.org, netbsd-bugs@netbsd.org, gnats-bugs@netbsd.org
Subject: Re: kern/60918: Keyboard modifier keys are not checked correctly
when sent simultaneously
Date: Fri, 23 Oct 2026 08:25:12 -0700
--=-=-=
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable
"Michael van Elst via gnats" <gnats-admin@NetBSD.org> writes:
> Another possibility is to generate events for the modifier keycodes
> 224..231 first, or by simply scanning the keycodes in reverse order.
I've tested this, and scanning in reverse order does fix it; see the
patch below.
=2DPhil
From=207b573278d25787b4028d37bce780d815a09345b2 Mon Sep 17 00:00:00 2001
From: Phil Hagelberg <phil@hagelb.org>
Subject: [PATCH] Reverse order of keys added in ukbd_decode.
If a single USB report is received that sets both the shift key and A
at the same time, it should be interpreted as A, but it currently
results in lower-case a, because the A key is handled first, and then
the shift key is handled.
Reversing the order is a little cheesy, but it ensures that the shift
key is handled first.
=2D--
sys/dev/usb/ukbd.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sys/dev/usb/ukbd.c b/sys/dev/usb/ukbd.c
index 4c81c78f5834..d646abe2b231 100644
=2D-- a/sys/dev/usb/ukbd.c
+++ b/sys/dev/usb/ukbd.c
@@ -821,7 +821,9 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
ukbd_translate_keycodes(sc, ud, trtab_apple_iso);
nkeys =3D 0;
=2D for (i =3D 0; i < MAXKEYS; i++) {
+ /* traverse in reverse order so that modifiers are processed first since
+ * they can affect the other keys. */
+ for (i =3D MAXKEYS - 1; i >=3D 0; i--) {
#ifdef GDIUM_KEYBOARD_HACK
if (sc->sc_flags & FLAG_GDIUM_FN && i =3D=3D 0x82) {
if (isset(ud->keys, i))
=2D-
2.55.0
--=-=-=
Content-Type: application/pgp-signature; name="signature.asc"
-----BEGIN PGP SIGNATURE-----
iQJEBAEBCgAuFiEEnRPZQmoIFLM3PPXj2KgkNXenhZ8FAmrbfFgQHHBoaWxAaGFn
ZWxiLm9yZwAKCRDYqCQ1d6eFn8WGEACq5kcHHcPr9VlYsPmpv3/qQIWFx0IpHKn8
/j2jKEF84UH3rmr42Qjy5a1u7bbxuBEq14H4OBnQmEexAT5NbXfrm8eAEekJbsP0
Z1fKNLQv1Ljnfk90LtUSGTu+ZLkhGVab2304YsV7YYMc1wgeulEKwcyqZTYoPE9d
lr66HrbbFIkhVZEuDFK6YyLzg2F+7CSvwwn3cVINaw8fGa4HCWTZZ/X28XPWd8AB
Wd74cPlxU30lm8PmNYsLb9FIHo9HyTwLKxsHdrIFwyRttbxhgr8aCL8Au43AaD0o
ia4n5v46hNY+XtM0f7nYrjuMId6wmR6rRUHb4WXwurXxHabl7i8ctYR0hRJpTrg8
NQ/LCf0dsANzIq6dFbz7lVLaLQxUtQAP6sJKBDoLOwsTnJKv+0y6g19z5GgQEBVA
Q7LW0CHNPF5H1TKqnqG6Kl13ZqPCGSIPhSsXfPutlBLxcFARQAth3sTPF2S8xpKp
M1+GLnRU0OMUmghYjZNGLdz05K5qY3BOL05qdoxEmbz2HAR3FBvvTUXk5Ooqb4jc
Ha09LopjZX2zBVSFKEeJ4Uhf68f+8ZPqXpdpaC1NRifluryY3m8jiuMjchNdz31P
hC2hqQ+0tCgA5QABGFQczJeSO5GE5t6veBjurUtFCM9fN69g0w8MCjmAoHaY3qjo
5mFGRlpnEA==
=ck6u
-----END PGP SIGNATURE-----
--=-=-=--
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/60918: Keyboard modifier keys are not checked correctly when sent simultaneously
Date: Sun, 25 Oct 2026 08:28:49 -0000 (UTC)
gnats-admin@NetBSD.org ("Michael van Elst via gnats") writes:
> We have a second decoder for USB HID reports that handles key status
> for "Dynamic Variable" (used by modifiers) values separate from
> "Selectors" (used by regular keys) and transmits the DV events first.
>
> I'm not sure if that is the correct behaviour, but it solves the
> problem.
>
> Another possibility is to generate events for the modifier keycodes
> 224..231 first, or by simply scanning the keycodes in reverse order.
FreeBSD orders events by 'regular keys up', 'modifier keys up',
'modifier keys down' 'regular keys down'. This is done by scanning
the key status information 4 times. "modifiers" are identified
by their keycode range (224..231). That is similar to the second
method above.
Linux has another method. It sorts processing of usages by the order
they appear in the report descriptor (with some exceptions for other
input devices, in particular Wacom tablets). This is a more refined
version of the first method above.
The standard is unclear. While it specifies that order of keypresses
in a single report is undefined and needs to be resolved by "host software",
it explicitely mentions only the order of keycodes in an array item.
It also defines that modifiers "should" use a bitmask (dynamic flags)
while non-modifiers "must" use an array of keycodes. It also suggests
that keycodes should be interpreted according to the modifiers,
It never gives an example of changing modifiers and keys in an array
at the same time. The standard also suggests that other keys (like
function keys) can be used like modifiers and are sent together in
a keycode array.
So, keyboards shouldn't send multiple events in a single report
because of these ambiguities, and "host software" already uses
different ways to resolve such reports in a meaningful manner.
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.