From: Alexey Gladkov <legion@kernel.org>
To: Nicolas Pitre <nico@fluxnic.net>
Cc: kbd@lists.linux.dev, gladkov.alexey@gmail.com,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: Re: [PATCH v2 0/3] support for the kernel 7.1 modifier-aware KT_CSI keysym type
Date: Thu, 25 Jun 2026 23:40:23 +0200 [thread overview]
Message-ID: <aj2gR0Y7sM6i9s2G@example.org> (raw)
In-Reply-To: <pr219nr8-0p04-onq5-nn6p-q183921r062r@syhkavp.arg>
On Thu, Jun 25, 2026 at 12:28:44PM -0400, Nicolas Pitre wrote:
> On Wed, 24 Jun 2026, Alexey Gladkov wrote:
>
> > On Tue, Jun 23, 2026 at 06:48:55PM -0400, Nicolas Pitre wrote:
> > > Linux kernel 7.1 introduces modifier-aware escape sequence generation
> > > for the console keyboard:
> > >
> > > 4af70f151671 ("vt: add modifier support to cursor keys")
> > > 5cba06c71c71 ("vt: add KT_CSI keysym type for modifier-aware CSI sequences")
> > > c1d2deb6492f ("vt: add fallback to plain map for modifier-aware key types")
> > >
> > > The new KT_CSI keysym type produces xterm-style CSI tilde sequences
> > > (ESC [ n ~, or ESC [ n ; mod ~ when Shift/Alt/Control are held) with
> > > the modifier state encoded at runtime. A single plain map entry covers
> > > all modifier combinations, instead of consuming a func_table string
> > > slot per combination.
> >
> > Here's what's bothering me. These patches disrupt the logic behind how
> > keymaps work.
> >
> > Previously, userspace determined which modifier key should generate which
> > sequence. We had `string F1 = "\033[[A"` and use it in any position:
> > `alt keycode 16 = F1`.
>
> That mechanism is untouched. KT_FN strings behave exactly as before and
> can still be placed in any position. KT_CSI does not replace them; it is
> an additional keysym type alongside them.
I guess I didn't mean it that way. I didn't say you broke KT_FN. You broke
KT_CUR.
> > After your patches, modifier handling has been moved to the kernel.
> > The escape sequence `ESC[11;03~` will be generated only if Csi_F1 is set
> > to `alt keycode 16 = Csi_F1`. So, for Csi_*, the modifier has taken on
> > a special meaning. I can't bind the Alt+Csi_F1 sequence to any other
> > modifier key.
>
> I think this conflates two separate things, and the one that matters
> isn't actually constrained.
>
> 1. Csi_F1 does not take over the modifier columns. The kernel only falls
> back to the plain entry when the modifier-specific slot is empty.
> From c1d2deb6492f ("vt: add fallback to plain map for modifier-aware
> key types"):
>
> if (shift_final && keycode < NR_KEYS &&
> (!key_map || key_map[keycode] == K_HOLE) && key_maps[0]) {
> ...
> if (type - 0xf0 == KT_CUR || type - 0xf0 == KT_CSI)
> key_map = key_maps[0];
> }
>
> As soon as you bind, say, shift keycode 16 = Foo, that slot is no
> longer K_HOLE, the condition is false, and your explicit binding is
> used -- the automatic encoding never runs. The commit log says as
> much: "Explicit modifier bindings still take precedence - the
> fallback only triggers when the modifier-specific entry is empty." So
> the keymap author keeps full control; Csi_F1 in the plain slot is
> merely the default for the modifier combinations you leave unbound.
>
> 2. What you genuinely cannot do is make the Csi_F1 keysym emit an
> encoding that disagrees with the keys physically held -- e.g. get the
> Alt form ESC[11;3~ out of a Control press. That is deliberate: k_csi
> reads the live modifier state, exactly like xterm, foot, kitty and
> every other terminal that speaks these sequences. But if you want a
> fixed, hand-picked sequence on a given modifier, that is precisely
> what KT_FN strings are for, and they still work in any column:
>
> string AltF1 = "\033[11;3~"
> control keycode 16 = AltF1
>
> So nothing that was possible before is lost. KT_CSI is opt-in and
> purely additive: it trades manual per-column control of a CSI
> sequence's modifier field (which strings still give you) for not
> having to enumerate -- and exhaust func_table with -- one string per
> modifier combination. That is the whole reason the kernel side
> exists.
>
> Nor is this a new departure for the keymap model: KT_CUR arrow keys
> already derive their output from runtime state (VC_CKMODE), as does
> KT_PAD (VC_APPLIC), and KT_CONS/KT_SHIFT/dead keys have never been
> userspace strings either. A keysym type with kernel-defined,
> state-dependent behavior is the norm, not the exception; KT_CSI
> simply joins that set.
Yes, the old mechanism (KT_FN) still exists and can still be used.
What I'm trying to say is that Csi_* significantly changes the user
experience. If now the user controls what will be in which position.
However, Csi_F1 changes its output depending on the active modifiers.
KT_CONS is a bad example. KT_CONS is just a separate type. I can even
assign it to Ctrl-X to switch to my especially favorite console. I can use
Console_63 anywhere in the keymap, and it will always take me to console
63 and it will work regardless of any active modifiers.
It's the same story with KT_PAD/KT_DEAD. You can put them anywhere you
like in the keymap and they will behave the same way.
That's not the case with KT_CSI.
Let me give you another example. In the last release, I implemented
initial support for converting xkb keymaps to kernel keymaps. The
conversion generates a keymap on the fly from xkbcommon. xkbsupport
encodes layout/group using KG_SHIFTL and KG_SHIFTR. So a single
combination cycles through several layouts:
- group 1: plain
- group 2: shiftl
- group 3: shiftr
- group 4: shiftl | shiftr
(this idea isn't new. It has been used in debian for a long time in the
console-setup, and also in ubuntu and some others).
This makes it impossible to use Csi_* in it, since Csi_F1 in the second
layout will be recognized by the kernel as "F1 with Shift".
And this seems to apply not only to KT_CSI, but also to the existing
KT_CUR: k_cur() uses the same csi_modifier_param(). If the arrows end up
in a layout group other than the first one via shiftl/shiftr, an extra
Shift modifier will be generated in the escape sequence. And that's a real
regression in userspace.
I hope I've made my concerns more clear.
--
Rgrds, legion
next prev parent reply other threads:[~2026-06-25 21:40 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-23 22:48 [PATCH v2 0/3] support for the kernel 7.1 modifier-aware KT_CSI keysym type Nicolas Pitre
2026-06-23 22:48 ` [PATCH v2 1/3] libkeymap: add support for " Nicolas Pitre
2026-06-23 22:48 ` [PATCH v2 2/3] Add kbd-terminfo-fixup script and systemd service Nicolas Pitre
2026-06-23 22:48 ` [PATCH v2 3/3] keymaps: add opt-in CSI overlay and load it when the kernel supports it Nicolas Pitre
2026-06-24 8:51 ` [PATCH v2 0/3] support for the kernel 7.1 modifier-aware KT_CSI keysym type Alexey Gladkov
2026-06-25 16:28 ` Nicolas Pitre
2026-06-25 21:40 ` Alexey Gladkov [this message]
2026-06-26 2:36 ` Nicolas Pitre
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aj2gR0Y7sM6i9s2G@example.org \
--to=legion@kernel.org \
--cc=gladkov.alexey@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=kbd@lists.linux.dev \
--cc=nico@fluxnic.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.