Capslock: Key::CapsLock-Event und heuristischer caps_lock()-Zustand
(cherry picked from commit 0df016d)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
2d81471820
commit
a120183f3b
@@ -35,6 +35,7 @@ fn main() {
|
||||
while let Some(ev) = p.poll_event() {
|
||||
match ev {
|
||||
Event::Key { key: Key::Escape, pressed: true, .. } => p.request_close(),
|
||||
Event::Key { key: Key::CapsLock, pressed: true, .. } => eprintln!("CapsLock, Zustand: {:?}", p.caps_lock()),
|
||||
Event::MouseMove { x, y } => mouse = (x, y),
|
||||
Event::MouseBtn { button: MouseButton::Left, pressed } => paint = pressed,
|
||||
_ => {}
|
||||
|
||||
+33
-5
@@ -11,7 +11,7 @@ use winit::event::{
|
||||
DeviceEvent, DeviceId, ElementState, KeyEvent, MouseButton as WinitMouseButton, WindowEvent,
|
||||
};
|
||||
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
||||
use winit::keyboard::{KeyCode, PhysicalKey};
|
||||
use winit::keyboard::{KeyCode, ModifiersState, PhysicalKey};
|
||||
use winit::platform::pump_events::EventLoopExtPumpEvents;
|
||||
use winit::window::{CursorGrabMode, Window, WindowAttributes, WindowId};
|
||||
|
||||
@@ -55,7 +55,7 @@ pub enum Key {
|
||||
Num0, Num1, Num2, Num3, Num4,
|
||||
Num5, Num6, Num7, Num8, Num9,
|
||||
Up, Down, Left, Right,
|
||||
Space, Enter, Escape, Tab, Backspace,
|
||||
Space, Enter, Escape, Tab, Backspace, CapsLock,
|
||||
LShift, RShift, LCtrl, RCtrl, LAlt, RAlt,
|
||||
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
}
|
||||
@@ -119,6 +119,8 @@ pub struct Platform {
|
||||
// Mode-Wechsel/erstem Frame, damit ein Cursor-Sprung keinen Riesen-Delta erzeugt.
|
||||
last_cursor_pos: Option<(f64, f64)>,
|
||||
mouse_delta: (f32, f32),
|
||||
modifiers: ModifiersState,
|
||||
caps_lock: Option<bool>,
|
||||
}
|
||||
|
||||
impl Platform {
|
||||
@@ -247,6 +249,8 @@ impl Platform {
|
||||
mouse_capture: cfg.mouse_capture,
|
||||
last_cursor_pos: None,
|
||||
mouse_delta: (0.0, 0.0),
|
||||
modifiers: ModifiersState::empty(),
|
||||
caps_lock: None,
|
||||
};
|
||||
platform.apply_cursor_mode();
|
||||
platform
|
||||
@@ -286,6 +290,13 @@ impl Platform {
|
||||
std::mem::replace(&mut self.mouse_delta, (0.0, 0.0))
|
||||
}
|
||||
|
||||
/// Capslock-Zustand, soweit bekannt. winit liefert ihn nicht direkt, daher
|
||||
/// abgeleitet: `CapsLock`-Druck toggelt, getippte Buchstaben ohne Modifier
|
||||
/// korrigieren (Groß → an, klein → aus). `None` bis zum ersten Buchstaben.
|
||||
/// Auf macOS meldet winit 0.30 keine `CapsLock`-Key-Events — dort zählen
|
||||
/// nur die Buchstaben.
|
||||
pub fn caps_lock(&self) -> Option<bool> { self.caps_lock }
|
||||
|
||||
pub fn should_close(&self) -> bool { self.close_requested }
|
||||
pub fn request_close(&mut self) { self.close_requested = true; }
|
||||
|
||||
@@ -293,13 +304,13 @@ impl Platform {
|
||||
// Felder destructuren, um disjoint &mut-Borrows in den Handler zu reichen.
|
||||
let Self {
|
||||
event_loop, event_queue, close_requested, last_cursor_pos, mouse_delta,
|
||||
surface, device, config, params, params_buf, queue, content_rect,
|
||||
modifiers, caps_lock, surface, device, config, params, params_buf, queue, content_rect,
|
||||
aspect_ratio, framebuffer_size, mouse_capture, ..
|
||||
} = self;
|
||||
|
||||
let mut handler = Handler {
|
||||
event_queue, close_requested, last_cursor_pos, mouse_delta,
|
||||
surface, device, config, params, params_buf, queue, content_rect,
|
||||
modifiers, caps_lock, surface, device, config, params, params_buf, queue, content_rect,
|
||||
aspect_ratio: *aspect_ratio,
|
||||
framebuffer_size: *framebuffer_size,
|
||||
mouse_capture: *mouse_capture,
|
||||
@@ -423,6 +434,8 @@ struct Handler<'a> {
|
||||
close_requested: &'a mut bool,
|
||||
last_cursor_pos: &'a mut Option<(f64, f64)>,
|
||||
mouse_delta: &'a mut (f32, f32),
|
||||
modifiers: &'a mut ModifiersState,
|
||||
caps_lock: &'a mut Option<bool>,
|
||||
surface: &'a wgpu::Surface<'static>,
|
||||
device: &'a wgpu::Device,
|
||||
config: &'a mut wgpu::SurfaceConfiguration,
|
||||
@@ -458,10 +471,25 @@ impl<'a> ApplicationHandler for Handler<'a> {
|
||||
*self.close_requested = true;
|
||||
self.event_queue.push_back(Event::CloseRequested);
|
||||
}
|
||||
WindowEvent::ModifiersChanged(m) => *self.modifiers = m.state(),
|
||||
WindowEvent::KeyboardInput { event: KeyEvent { physical_key, state, repeat, text, .. }, .. } => {
|
||||
if let PhysicalKey::Code(code) = physical_key
|
||||
&& let Some(key) = from_winit_keycode(code)
|
||||
{
|
||||
if key == Key::CapsLock && state == ElementState::Pressed && !repeat
|
||||
&& let Some(on) = self.caps_lock
|
||||
{
|
||||
*on = !*on;
|
||||
}
|
||||
// Buchstabe ohne Modifier: Groß/klein verrät den Capslock-Zustand.
|
||||
// Nur Tasten A–Z und Zeichen mit Groß/Kleinschreibung (Layout-unabhängig).
|
||||
if state == ElementState::Pressed && self.modifiers.is_empty()
|
||||
&& (Key::A as u8..=Key::Z as u8).contains(&(key as u8))
|
||||
&& let Some(c) = text.as_ref().and_then(|t| t.chars().next())
|
||||
&& (c.is_uppercase() || c.is_lowercase())
|
||||
{
|
||||
*self.caps_lock = Some(c.is_uppercase());
|
||||
}
|
||||
self.event_queue.push_back(Event::Key {
|
||||
key,
|
||||
pressed: state == ElementState::Pressed,
|
||||
@@ -564,7 +592,7 @@ fn from_winit_keycode(k: KeyCode) -> Option<Key> {
|
||||
K::ArrowUp => Key::Up, K::ArrowDown => Key::Down,
|
||||
K::ArrowLeft => Key::Left, K::ArrowRight => Key::Right,
|
||||
K::Space => Key::Space, K::Enter => Key::Enter, K::Escape => Key::Escape,
|
||||
K::Tab => Key::Tab, K::Backspace => Key::Backspace,
|
||||
K::Tab => Key::Tab, K::Backspace => Key::Backspace, K::CapsLock => Key::CapsLock,
|
||||
K::ShiftLeft => Key::LShift, K::ShiftRight => Key::RShift,
|
||||
K::ControlLeft => Key::LCtrl, K::ControlRight => Key::RCtrl,
|
||||
K::AltLeft => Key::LAlt, K::AltRight => Key::RAlt,
|
||||
|
||||
Reference in New Issue
Block a user