Skip to content

Commit bd485f2

Browse files
core: Improve spurious key ignoring logic
1 parent 1aaa320 commit bd485f2

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

core/src/input.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ impl ClickEventData {
7272
}
7373

7474
pub struct InputManager {
75-
key_descriptors_down: HashSet<KeyDescriptor>,
75+
/// Tracks which physical keys (identified by physical key + location) are currently pressed.
76+
/// This allows us to match key-up events even when the logical key changes
77+
/// due to modifier state changes (e.g., shift pressed/released).
78+
keys_down_phys_loc: HashSet<(PhysicalKey, KeyLocation)>,
7679

7780
keys_down: HashSet<KeyCode>,
7881
keys_toggled: HashSet<KeyCode>,
@@ -89,7 +92,7 @@ pub struct InputManager {
8992
impl InputManager {
9093
pub fn new(gamepad_button_mapping: HashMap<GamepadButton, KeyCode>) -> Self {
9194
Self {
92-
key_descriptors_down: HashSet::new(),
95+
keys_down_phys_loc: HashSet::new(),
9396
keys_down: HashSet::new(),
9497
keys_toggled: HashSet::new(),
9598
last_key: KeyCode::UNKNOWN,
@@ -156,7 +159,11 @@ impl InputManager {
156159
}
157160

158161
PlayerEvent::KeyDown { key } => {
159-
self.key_descriptors_down.insert(key);
162+
// Track the physical key + location, so we can match key-up events
163+
// even when the logical key changes due to modifier state changes
164+
// (e.g., shift pressed/released).
165+
let physical_location = (key.physical_key, key.key_location);
166+
self.keys_down_phys_loc.insert(physical_location);
160167

161168
let key_code = self.map_to_key_code(key)?;
162169
let key_char = self.map_to_key_char(key);
@@ -168,10 +175,17 @@ impl InputManager {
168175
}
169176
}
170177
PlayerEvent::KeyUp { key } => {
171-
if !self.key_descriptors_down.remove(&key) {
178+
// Match key-up events by physical key and location, not the exact
179+
// KeyDescriptor. This handles cases where modifier state changes
180+
// between key-down and key-up (e.g., shift pressed/released),
181+
// which would change the logical key (e.g., 'w' -> 'W').
182+
if !self
183+
.keys_down_phys_loc
184+
.remove(&(key.physical_key, key.key_location))
185+
{
172186
// Ignore spurious KeyUp events that may happen e.g. during IME.
173187
// We assume that in order for a key to generate KeyUp, it had to
174-
// generate KeyDown for the same exact KeyDescriptor.
188+
// generate KeyDown for the same physical key and location.
175189

176190
// TODO Apparently this behavior is platform-dependent and
177191
// doesn't happen on Windows. We cannot remove it fully

0 commit comments

Comments
 (0)