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.

NetBSD Home
NetBSD PR Database Search

(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.