fix(keyboard): keydown/keyup send full key descriptor so hold-to-move works

`keydown`/`keyup` dispatched a minimal Input.dispatchKeyEvent carrying only
{key}, so games/handlers that read event.code ("KeyD", "ArrowRight") or
event.keyCode saw nothing — a held key set no movement flag and the player
barely moved (dogfood: Dead Cell). They now build the same descriptor `press`
uses (key + code + windows/nativeVirtualKeyCode + printable text on down) via a
shared interaction::dispatch_single_key. Verified live: holding a direction now
drives continuous movement (player ran into an enemy and took damage), where
before it nudged ~80px.
This commit is contained in:
leeguooooo
2026-06-13 23:58:30 +09:00
parent 5b4ffdb2bb
commit 9bf79a4242
2 changed files with 44 additions and 14 deletions
+2 -14
View File
@@ -8785,13 +8785,7 @@ async fn handle_keydown(cmd: &Value, state: &DaemonState) -> Result<Value, Strin
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.ok_or("Missing 'key' parameter")?; .ok_or("Missing 'key' parameter")?;
mgr.client interaction::dispatch_single_key(&mgr.client, &session_id, key, "keyDown").await?;
.send_command(
"Input.dispatchKeyEvent",
Some(json!({ "type": "keyDown", "key": key })),
Some(&session_id),
)
.await?;
Ok(json!({ "keydown": key })) Ok(json!({ "keydown": key }))
} }
@@ -8803,13 +8797,7 @@ async fn handle_keyup(cmd: &Value, state: &DaemonState) -> Result<Value, String>
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.ok_or("Missing 'key' parameter")?; .ok_or("Missing 'key' parameter")?;
mgr.client interaction::dispatch_single_key(&mgr.client, &session_id, key, "keyUp").await?;
.send_command(
"Input.dispatchKeyEvent",
Some(json!({ "type": "keyUp", "key": key })),
Some(&session_id),
)
.await?;
Ok(json!({ "keyup": key })) Ok(json!({ "keyup": key }))
} }
+42
View File
@@ -557,6 +557,48 @@ pub async fn press_key_with_modifiers(
Ok(()) Ok(())
} }
/// Dispatch a SINGLE key event (`keyDown` or `keyUp`) carrying the full key
/// descriptor — `key`, `code`, `windowsVirtualKeyCode`/`nativeVirtualKeyCode`,
/// and (on key-down) printable `text`. Powers the `keydown`/`keyup` commands.
///
/// The previous implementation sent only `{key}`, so games and shortcut handlers
/// that read `event.code` (e.g. `"KeyD"`, `"ArrowRight"`) or `event.keyCode` saw
/// nothing — a held key set no movement flag and did nothing (dogfood: holding a
/// direction in a canvas platformer barely nudged the player). Sending the same
/// descriptor `press` uses makes hold-to-move work regardless of which field the
/// page keys off.
pub async fn dispatch_single_key(
client: &CdpClient,
session_id: &str,
key: &str,
event_type: &str,
) -> Result<(), String> {
let (key_name, code, key_code) = named_key_info(key);
// Printable text is only meaningful on key-down; key-up never inserts.
let text = if event_type == "keyDown" {
key_text(&key_name)
} else {
None
};
client
.send_command_typed::<_, Value>(
"Input.dispatchKeyEvent",
&DispatchKeyEventParams {
event_type: event_type.to_string(),
key: Some(key_name),
code: Some(code),
text: text.clone(),
unmodified_text: text,
windows_virtual_key_code: Some(key_code),
native_virtual_key_code: Some(key_code),
modifiers: None,
},
Some(session_id),
)
.await?;
Ok(())
}
pub async fn scroll( pub async fn scroll(
client: &CdpClient, client: &CdpClient,
session_id: &str, session_id: &str,