mirror of
https://github.com/herdrdev/herdr.git
synced 2026-09-21 16:01:04 +00:00
@@ -7,6 +7,7 @@
|
||||
|
||||
### Fixed
|
||||
- OMP integration install, status, and uninstall now respect `PI_CONFIG_DIR` when `PI_CODING_AGENT_DIR` is not set, and installation refuses extension-directory collisions with Pi. (#1696)
|
||||
- Physical Escape key records on native Windows now bypass raw VT report framing, so pane applications receive Escape immediately and reliably. (#1736)
|
||||
|
||||
## [0.7.5] - 2026-07-21
|
||||
|
||||
|
||||
@@ -389,6 +389,7 @@ impl WindowsInputMapper {
|
||||
key_down = key.key_down,
|
||||
repeat_count = key.repeat_count,
|
||||
virtual_key_code = key.virtual_key_code,
|
||||
virtual_scan_code = key.virtual_scan_code,
|
||||
unicode = key.unicode,
|
||||
control_key_state = key.control_key_state,
|
||||
"windows input trace: console key record"
|
||||
@@ -452,8 +453,11 @@ impl WindowsInputMapper {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Physical Escape carries a scan code. Scan-code-zero Escape can
|
||||
// introduce raw VT reports and must stay in the framer.
|
||||
let bare_escape = modifiers.is_empty()
|
||||
&& (key.virtual_key_code == 0x1b || (key.virtual_key_code == 0 && key.unicode == 0x1b));
|
||||
&& ((key.virtual_key_code == 0x1b && key.virtual_scan_code == 0)
|
||||
|| (key.virtual_key_code == 0 && key.unicode == 0x1b));
|
||||
let ctrl_bracket = key.virtual_key_code == 0xdb
|
||||
&& key.unicode == 0x1b
|
||||
&& modifiers == crossterm::event::KeyModifiers::CONTROL;
|
||||
@@ -1338,9 +1342,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vti_escape_key_record_flushes_to_escape_after_idle() {
|
||||
fn vti_scan_code_zero_escape_key_record_flushes_after_idle() {
|
||||
let mut translator = WindowsInputTranslator::default();
|
||||
assert!(translator.translate(key_vk(0x1b, 0)).is_empty());
|
||||
assert!(translator
|
||||
.translate(key_vk_with_scan_unicode(0x1b, 0, '\0', 0))
|
||||
.is_empty());
|
||||
assert_eq!(
|
||||
translator.idle(),
|
||||
vec![crate::protocol::ClientInputEvent::Key {
|
||||
@@ -1351,6 +1357,19 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vti_physical_escape_key_record_is_immediately_semantic() {
|
||||
let mut translator = WindowsInputTranslator::default();
|
||||
assert_eq!(
|
||||
translator.translate(key_vk_with_scan_unicode(0x1b, 0x01, '\x1b', 0)),
|
||||
vec![crate::protocol::ClientInputEvent::Key {
|
||||
code: crate::protocol::ClientKeyCode::Esc,
|
||||
modifiers: 0,
|
||||
kind: crate::protocol::ClientKeyKind::Press,
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vti_repeated_escape_record_stays_semantic() {
|
||||
assert_eq!(
|
||||
@@ -1752,8 +1771,8 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vti_escape_key_record_without_unicode_starts_mouse_sequence() {
|
||||
let records = [key_vk(0x1b, 0)]
|
||||
fn vti_scan_code_zero_escape_starts_mouse_sequence() {
|
||||
let records = [key_vk_with_scan_unicode(0x1b, 0, '\0', 0)]
|
||||
.into_iter()
|
||||
.chain("[<35;48;26M".chars().map(key_char));
|
||||
|
||||
@@ -1768,6 +1787,44 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vti_nonzero_scan_escape_is_immediately_semantic() {
|
||||
let mut translator = WindowsInputTranslator::default();
|
||||
assert_eq!(
|
||||
translator.translate(key_vk_with_scan_unicode(0x1b, 0x02, '\0', 0)),
|
||||
vec![crate::protocol::ClientInputEvent::Key {
|
||||
code: crate::protocol::ClientKeyCode::Esc,
|
||||
modifiers: 0,
|
||||
kind: crate::protocol::ClientKeyKind::Press,
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vti_win32_input_mode_physical_escape_is_immediately_semantic() {
|
||||
let records = win32_input_mode_encoded_record(WindowsKeyRecord {
|
||||
key_down: true,
|
||||
repeat_count: 1,
|
||||
virtual_key_code: 0x1b,
|
||||
virtual_scan_code: 0x01,
|
||||
unicode: 0x1b,
|
||||
control_key_state: 0,
|
||||
});
|
||||
let mut translator = WindowsInputTranslator::default();
|
||||
|
||||
assert_eq!(
|
||||
records
|
||||
.into_iter()
|
||||
.flat_map(|record| translator.translate(record))
|
||||
.collect::<Vec<_>>(),
|
||||
vec![crate::protocol::ClientInputEvent::Key {
|
||||
code: crate::protocol::ClientKeyCode::Esc,
|
||||
modifiers: 0,
|
||||
kind: crate::protocol::ClientKeyKind::Press,
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vti_win32_input_mode_encoded_mouse_sequence() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user