mirror of
https://github.com/emilk/egui.git
synced 2026-06-26 14:49:06 -04:00
## Problem winit has always delivered distinct physical variants for every keyboard key — \`KeyCode::ShiftLeft\` vs \`KeyCode::ShiftRight\`, \`KeyCode::ControlLeft\`/\`ControlRight\`, \`AltLeft\`/\`AltRight\`, \`SuperLeft\`/\`SuperRight\`, plus the ISO 102nd key \`KeyCode::IntlBackslash\` (the one between LShift and Z, labelled \`<>|\` on French AZERTY and \`\\|\` on UK QWERTY). Today none of these reach egui: - Pressing Shift / Ctrl / Alt alone produces *no* \`Event::Key\` at all. \`key_from_key_code\` and \`key_from_named_key\` both return \`None\` for modifiers, so the \`if let Some(active_key)\` branch in \`on_keyboard_input\` is skipped. The collapsed \`Modifiers\` bools are the only trace of the press, and they don't distinguish left vs right. - \`KeyCode::IntlBackslash\` has no arm in \`key_from_key_code\`, so on French / UK ISO keyboards the \`<>|\` key is completely invisible to egui apps — neither \`key\` nor \`physical_key\` is ever set. ## Who hits this - Games / kiosk frontends / pincab UIs that bind \`LeftFlipper = LShift\` vs \`RightFlipper = RShift\` (or \`LeftMagna = LCtrl\` vs \`RightMagna = RCtrl\`) — currently impossible inside egui without shelling out to platform APIs (\`device_query\`, raw X11, etc.). - Anyone on an ISO keyboard who wants to capture the 102nd key in an input-binding UI. Previously discussed: context in #2977 (closed by #3649 which added \`physical_key\`, but only for keys already in \`egui::Key\`). ## Change Two small additions, no behaviour change for existing code: **\`crates/egui/src/data/key.rs\`** — new variants at the end of \`Key\`: - \`ShiftLeft\`, \`ShiftRight\`, \`ControlLeft\`, \`ControlRight\`, \`AltLeft\`, \`AltRight\`, \`SuperLeft\`, \`SuperRight\` - \`IntlBackslash\` plus their entries in \`Key::ALL\`, \`Key::from_name\`, and \`Key::name\` (the \`key_from_name\` roundtrip test at the bottom of the file still passes). **\`crates/egui-winit/src/lib.rs\`** — new arms in \`key_from_key_code\`: \`\`\`rust KeyCode::ShiftLeft => Key::ShiftLeft, KeyCode::ShiftRight => Key::ShiftRight, // ...ControlLeft/Right, AltLeft/Right, SuperLeft/Right... KeyCode::IntlBackslash => Key::IntlBackslash, \`\`\` The existing \`Modifiers\` struct is untouched — shortcut matching (\"Ctrl+C\"), \`consume_shortcut\`, etc. still see the collapsed state. The new variants are purely additive and only surface as physical \`Event::Key\` presses when someone is specifically looking for them. ## Test - Existing \`test_key_from_name\` test still passes (updated the sentinel to \`Key::IntlBackslash as usize + 1\`). - Manual smoke test: pressing left vs right Shift, Ctrl, Alt each produces an \`Event::Key { key: Key::ShiftLeft/Right/..., physical_key: Some(Key::ShiftLeft/Right/...), ... }\`; pressing the AZERTY 102nd key yields \`Key::IntlBackslash\`. Character-key behaviour and \`Modifiers\` bools are unchanged. ## Not included - **Web backend** (\`eframe_web\`): \`PhysicalKey\` isn't fully exposed there yet per the existing \`physical_key\` docs, so these new variants are only emitted on native. Happy to extend to web in a follow-up if wanted. - \`ModifiersSymmetric\` / per-side sticky state: would be a bigger API change in \`Modifiers\`. This PR stays at the minimum: forward what winit already gives us for the event path. Closes no issue directly but addresses the underlying gap noted in the thread of #2977 (scancode forwarding) for the modifier / Intl-key subset.