Skip to content

keyboard/printer: release modifiers before pressing new ones (fixes pikvm/pikvm#1549)#229

Open
mawadSur wants to merge 1 commit into
pikvm:masterfrom
mawadSur:fix/1549-paste-modifier-overlap
Open

keyboard/printer: release modifiers before pressing new ones (fixes pikvm/pikvm#1549)#229
mawadSur wants to merge 1 commit into
pikvm:masterfrom
mawadSur:fix/1549-paste-modifier-overlap

Conversation

@mawadSur

@mawadSur mawadSur commented Jul 3, 2026

Copy link
Copy Markdown

♻️ Reopens #224. Auto-closed when I accidentally deleted my fork; the commit (536ae6a) is unchanged, re-pushed from a fresh fork.

Problem

Fixes pikvm/pikvm#1549.

Pasting/typing text via the Web UI Text feature (POST /hid/printtext_to_evdev_keys) breaks the input when two consecutive characters need different modifiers. The classic repro on the Swedish layout is the sequence }":

  • } = AltGr + 0
  • " = Shift + 2

After this sequence, all following input produces wrong characters until a modifier key is tapped. The reporter confirmed it on ~20 layouts: cz, da, de, de-ch, es, fi, fo, fr-ca, fr-ch, hr, hu, is, it, lv, nl, no, pt, pt-br, sl, sv.

Root cause

In text_to_evdev_keys, the Shift modifier block was always handled before the AltGr block. When switching from an AltGr-character to a Shift-character, this pressed KEY_LEFTSHIFT before releasing KEY_RIGHTALT, so for one moment both Shift and AltGr were held at the same time — which selects a different symbol level on these layouts and corrupts subsequent input.

This matches the evtest capture in the issue exactly (LEFTSHIFT down emitted before RIGHTALT up):

RIGHTALT  ↓
KEY_0     ↓ ↑
LEFTSHIFT ↓     <-- pressed while AltGr still held
RIGHTALT  ↑     <-- released too late
KEY_2     ↓ ↑

Fix

Release the modifiers that are no longer needed before pressing the newly required ones, so Shift and AltGr are never held simultaneously across a key switch. Modifiers shared by consecutive characters are still kept pressed (the existing optimization is preserved).

Resulting order for }":

RIGHTALT  ↓
KEY_0     ↓ ↑
RIGHTALT  ↑     <-- released first
LEFTSHIFT ↓
KEY_2     ↓ ↑
LEFTSHIFT ↑

Tests

Adds testenv/tests/keyboard/test_printer.py:

  • test_ok__printer_no_modifier_overlap — invariant (parametrized over several sequences): Shift and AltGr are never held at once, and everything is released at the end.
  • test_ok__printer_release_before_press — asserts the exact corrected event order for }".
  • test_ok__printer_keeps_shared_modifier_pressed — ensures a modifier shared by consecutive characters stays held.

Note: I could not run the Docker testenv (make tox) locally — it requires Linux (evdev/libxkbcommon). The change was validated against the lint configs and via a standalone simulation of the old vs. new ordering. Please run CI to confirm.

🤖 Generated with Claude Code

When typing/pasting text via /hid/print, switching from a character that
needs AltGr (e.g. "}" on the Swedish layout = AltGr+0) to one that needs
Shift (e.g. the double quote = Shift+2) caused Shift to be pressed before
AltGr was released. For one moment both Shift and AltGr were held at once,
which on ~20 layouts (cz, da, de, de-ch, es, fi, fo, fr-ca, fr-ch, hr, hu,
is, it, lv, nl, no, pt, pt-br, sl, sv) produces a wrong symbol and corrupts
all subsequent input.

Fix the ordering so that no-longer-needed modifiers are always released
before the required ones are pressed, eliminating the transient
Shift+AltGr combination. Modifiers shared by consecutive characters are
still kept pressed.

Adds a regression test for the ordering and the no-overlap invariant.

Fixes pikvm/pikvm#1549

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Keyboard Layout Breaks After Pasting }"

2 participants