fix(host/windows): layout-correct keyboard injection - semantic vs positional VKs
First-party punktfunk clients send US-positional VKs (the physical key's US-layout VK), GameStream/Moonlight clients send layout-semantic VKs (Sunshine's model). The SendInput injector previously resolved everything through the SYSTEM service's layout - on a German host that is the y/z swap and u-umlaut-on-o-umlaut scramble. GameStream ingest now tags its key events KEY_FLAG_SEMANTIC_VK (stripped from punktfunk/1 wire events so a network client can't flip the convention); the injector maps semantic VKs under the foreground app's layout and positional VKs through a fixed scancode table. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1015,8 +1015,19 @@ async fn serve_session(
|
||||
if rich_tx.send(rich).is_err() {
|
||||
break;
|
||||
}
|
||||
} else if let Some(ev) = InputEvent::decode(&d) {
|
||||
} else if let Some(mut ev) = InputEvent::decode(&d) {
|
||||
input_count += 1;
|
||||
// Wire hygiene: KEY_FLAG_SEMANTIC_VK is an in-process tag (GameStream ingest
|
||||
// only) — strip it from network events so a client can't flip the host's
|
||||
// key-decoding convention. Other kinds keep flags verbatim (MouseMoveAbs packs
|
||||
// its reference extent there).
|
||||
if matches!(
|
||||
ev.kind,
|
||||
punktfunk_core::input::InputKind::KeyDown
|
||||
| punktfunk_core::input::InputKind::KeyUp
|
||||
) {
|
||||
ev.flags &= !crate::inject::KEY_FLAG_SEMANTIC_VK;
|
||||
}
|
||||
if input_tx.send(ev).is_err() {
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user