Skip to content

Commit 734faae

Browse files
authored
fix(windows): batch input trace diagnostics (#4146)
refs #3932
1 parent e61206c commit 734faae

1 file changed

Lines changed: 72 additions & 22 deletions

File tree

‎src/client/input/windows_vti.rs‎

Lines changed: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,33 @@ pub(super) fn raw_console_reader_loop(
2424
let mut handoff = WindowsInputHandoff::default();
2525

2626
while !should_quit.load(Ordering::Acquire) {
27-
match windows_console_input_items(handle, &mut mapper) {
27+
let mut trace = windows_input_trace_enabled().then(WindowsInputTraceBatch::default);
28+
match windows_console_input_items(handle, &mut mapper, trace.as_mut()) {
2829
WindowsInputItems::Items(items) => {
29-
process_platform_input_items(items, &mut pump, &mut handoff);
30+
process_platform_input_items(items, &mut pump, &mut handoff, trace.as_mut());
3031
}
3132
WindowsInputItems::Idle => {
32-
process_platform_input_items(mapper.idle(), &mut pump, &mut handoff);
33-
handoff.push(pump.idle());
33+
process_platform_input_items(
34+
mapper.idle(),
35+
&mut pump,
36+
&mut handoff,
37+
trace.as_mut(),
38+
);
39+
push_platform_input_events(pump.idle(), &mut handoff, trace.as_mut());
3440
}
3541
WindowsInputItems::Closed => return,
3642
}
37-
if !handoff.try_flush(&event_tx) {
43+
let handoff_open = handoff.try_flush(&event_tx);
44+
if let Some(trace) = trace
45+
.filter(|trace| !trace.raw_keys.is_empty() || !trace.mapped_event_groups.is_empty())
46+
{
47+
tracing::info!(
48+
raw_keys = ?trace.raw_keys,
49+
mapped_event_groups = ?trace.mapped_event_groups,
50+
"windows input trace: input batch"
51+
);
52+
}
53+
if !handoff_open {
3854
return;
3955
}
4056
}
@@ -45,10 +61,26 @@ fn process_platform_input_items(
4561
items: Vec<PlatformInputItem>,
4662
pump: &mut WindowsInputPump,
4763
handoff: &mut WindowsInputHandoff,
64+
mut trace: Option<&mut WindowsInputTraceBatch>,
4865
) {
4966
for item in items {
50-
handoff.push(pump.process(item));
67+
push_platform_input_events(pump.process(item), handoff, trace.as_deref_mut());
68+
}
69+
}
70+
71+
#[cfg(windows)]
72+
fn push_platform_input_events(
73+
events: Vec<crate::protocol::ClientInputEvent>,
74+
handoff: &mut WindowsInputHandoff,
75+
trace: Option<&mut WindowsInputTraceBatch>,
76+
) {
77+
if events.is_empty() {
78+
return;
5179
}
80+
if let Some(trace) = trace {
81+
trace.mapped_event_groups.push(events.clone());
82+
}
83+
handoff.push(events);
5284
}
5385

5486
#[cfg(windows)]
@@ -81,6 +113,13 @@ enum WindowsInputItems {
81113
Closed,
82114
}
83115

116+
#[cfg(windows)]
117+
#[derive(Default)]
118+
struct WindowsInputTraceBatch {
119+
raw_keys: Vec<WindowsKeyRecord>,
120+
mapped_event_groups: Vec<Vec<crate::protocol::ClientInputEvent>>,
121+
}
122+
84123
#[cfg(windows)]
85124
#[derive(Default)]
86125
struct WindowsInputHandoff {
@@ -94,9 +133,6 @@ impl WindowsInputHandoff {
94133
if events.is_empty() {
95134
return;
96135
}
97-
if windows_input_trace_enabled() {
98-
tracing::info!(?events, "windows input trace: client input events");
99-
}
100136
if self.backpressured {
101137
self.push_backpressured(events);
102138
} else {
@@ -185,6 +221,7 @@ fn windows_mouse_motion_can_replace(
185221
fn windows_console_input_items(
186222
handle: windows_sys::Win32::Foundation::HANDLE,
187223
mapper: &mut WindowsInputMapper,
224+
mut trace: Option<&mut WindowsInputTraceBatch>,
188225
) -> WindowsInputItems {
189226
const WAIT_OBJECT_0: u32 = 0;
190227
const WAIT_TIMEOUT: u32 = 258;
@@ -212,6 +249,9 @@ fn windows_console_input_items(
212249
let mut items = Vec::new();
213250
for record in records.iter().take(read as usize) {
214251
if let Some(record) = windows_console_input_record_from_os(*record) {
252+
if let (Some(trace), WindowsInputRecord::Key(key)) = (trace.as_deref_mut(), record) {
253+
trace.raw_keys.push(key);
254+
}
215255
items.extend(mapper.translate(record));
216256
}
217257
}
@@ -662,18 +702,6 @@ impl WindowsInputMapper {
662702
}
663703

664704
fn translate_key(&mut self, key: WindowsKeyRecord) -> Vec<PlatformInputItem> {
665-
if windows_input_trace_enabled() {
666-
tracing::info!(
667-
key_down = key.key_down,
668-
repeat_count = key.repeat_count,
669-
virtual_key_code = key.virtual_key_code,
670-
virtual_scan_code = key.virtual_scan_code,
671-
unicode = key.unicode,
672-
control_key_state = key.control_key_state,
673-
"windows input trace: console key record"
674-
);
675-
}
676-
677705
if !self.key_record_can_emit_event(key) {
678706
return Vec::new();
679707
}
@@ -1341,7 +1369,7 @@ fn resolve_ctrl_oem_char(key: WindowsKeyRecord) -> Option<char> {
13411369
None
13421370
}
13431371

1344-
#[cfg(any(windows, test))]
1372+
#[cfg(windows)]
13451373
fn windows_input_trace_enabled() -> bool {
13461374
std::env::var_os("HERDR_WINDOWS_INPUT_TRACE").is_some()
13471375
}
@@ -1558,6 +1586,28 @@ mod tests {
15581586
.collect()
15591587
}
15601588

1589+
#[cfg(windows)]
1590+
#[test]
1591+
fn windows_input_trace_preserves_mapped_event_groups() {
1592+
let groups = vec![
1593+
vec![crate::protocol::ClientInputEvent::FocusGained],
1594+
vec![
1595+
crate::protocol::ClientInputEvent::FocusLost,
1596+
crate::protocol::ClientInputEvent::FocusGained,
1597+
],
1598+
];
1599+
let mut trace = WindowsInputTraceBatch::default();
1600+
let mut handoff = WindowsInputHandoff::default();
1601+
1602+
for events in &groups {
1603+
push_platform_input_events(events.clone(), &mut handoff, Some(&mut trace));
1604+
}
1605+
push_platform_input_events(Vec::new(), &mut handoff, Some(&mut trace));
1606+
1607+
assert_eq!(trace.mapped_event_groups, groups);
1608+
assert_eq!(handoff.pending, VecDeque::from(groups));
1609+
}
1610+
15611611
#[cfg(windows)]
15621612
#[test]
15631613
fn windows_input_handoff_keeps_input_while_the_client_queue_is_full() {

0 commit comments

Comments
 (0)