Compare commits

...
1 Commits
Author SHA1 Message Date
irrlichtandClaude Opus 5.5 0df016d69c Capslock: Key::CapsLock-Event und heuristischer caps_lock()-Zustand
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:17:59 +02:00
3 changed files with 41 additions and 5 deletions
+7
View File
@@ -20,6 +20,13 @@ durch direktes RGB565-Truecolor. Beide Varianten bleiben unabhängig nutzbar:
- `pbio::rgb565(r: u8, g: u8, b: u8) -> u16` (const fn) — packt 8-Bit-Kanäle - `pbio::rgb565(r: u8, g: u8, b: u8) -> u16` (const fn) — packt 8-Bit-Kanäle
in einen RGB565-Pixelwert. in einen RGB565-Pixelwert.
- `Key::CapsLock` als Tasten-Event (X11, Wayland, Windows — winit 0.30 meldet
Capslock auf macOS nicht als `KeyboardInput`).
- `Platform::caps_lock() -> Option<bool>` — Capslock-Zustand, heuristisch
abgeleitet, da winit ihn nicht plattformübergreifend liefert: `CapsLock`-Druck
toggelt, ein getippter Buchstabe (A–Z-Taste ohne Modifier) setzt ihn anhand
von Groß-/Kleinschreibung. `None`, bis der erste Buchstabe getippt wurde.
### Entfernt ### Entfernt
- `PlatformConfig::palette` sowie `palette()` / `palette_mut()` und das - `PlatformConfig::palette` sowie `palette()` / `palette_mut()` und das
+1
View File
@@ -35,6 +35,7 @@ fn main() {
while let Some(ev) = p.poll_event() { while let Some(ev) = p.poll_event() {
match ev { match ev {
Event::Key { key: Key::Escape, pressed: true, .. } => p.request_close(), 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::MouseMove { x, y } => mouse = (x, y),
Event::MouseBtn { button: MouseButton::Left, pressed } => paint = pressed, Event::MouseBtn { button: MouseButton::Left, pressed } => paint = pressed,
_ => {} _ => {}
+33 -5
View File
@@ -11,7 +11,7 @@ use winit::event::{
DeviceEvent, DeviceId, ElementState, KeyEvent, MouseButton as WinitMouseButton, WindowEvent, DeviceEvent, DeviceId, ElementState, KeyEvent, MouseButton as WinitMouseButton, WindowEvent,
}; };
use winit::event_loop::{ActiveEventLoop, EventLoop}; 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::platform::pump_events::EventLoopExtPumpEvents;
use winit::window::{CursorGrabMode, Window, WindowAttributes, WindowId}; use winit::window::{CursorGrabMode, Window, WindowAttributes, WindowId};
@@ -56,7 +56,7 @@ pub enum Key {
Num0, Num1, Num2, Num3, Num4, Num0, Num1, Num2, Num3, Num4,
Num5, Num6, Num7, Num8, Num9, Num5, Num6, Num7, Num8, Num9,
Up, Down, Left, Right, Up, Down, Left, Right,
Space, Enter, Escape, Tab, Backspace, Space, Enter, Escape, Tab, Backspace, CapsLock,
LShift, RShift, LCtrl, RCtrl, LAlt, RAlt, LShift, RShift, LCtrl, RCtrl, LAlt, RAlt,
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
} }
@@ -117,6 +117,8 @@ pub struct Platform {
// Mode-Wechsel/erstem Frame, damit ein Cursor-Sprung keinen Riesen-Delta erzeugt. // Mode-Wechsel/erstem Frame, damit ein Cursor-Sprung keinen Riesen-Delta erzeugt.
last_cursor_pos: Option<(f64, f64)>, last_cursor_pos: Option<(f64, f64)>,
mouse_delta: (f32, f32), mouse_delta: (f32, f32),
modifiers: ModifiersState,
caps_lock: Option<bool>,
} }
impl Platform { impl Platform {
@@ -233,6 +235,8 @@ impl Platform {
mouse_capture: cfg.mouse_capture, mouse_capture: cfg.mouse_capture,
last_cursor_pos: None, last_cursor_pos: None,
mouse_delta: (0.0, 0.0), mouse_delta: (0.0, 0.0),
modifiers: ModifiersState::empty(),
caps_lock: None,
}; };
platform.apply_cursor_mode(); platform.apply_cursor_mode();
platform platform
@@ -272,6 +276,13 @@ impl Platform {
std::mem::replace(&mut self.mouse_delta, (0.0, 0.0)) 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 should_close(&self) -> bool { self.close_requested }
pub fn request_close(&mut self) { self.close_requested = true; } pub fn request_close(&mut self) { self.close_requested = true; }
@@ -279,13 +290,13 @@ impl Platform {
// Felder destructuren, um disjoint &mut-Borrows in den Handler zu reichen. // Felder destructuren, um disjoint &mut-Borrows in den Handler zu reichen.
let Self { let Self {
event_loop, event_queue, close_requested, last_cursor_pos, mouse_delta, 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, .. aspect_ratio, framebuffer_size, mouse_capture, ..
} = self; } = self;
let mut handler = Handler { let mut handler = Handler {
event_queue, close_requested, last_cursor_pos, mouse_delta, 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, aspect_ratio: *aspect_ratio,
framebuffer_size: *framebuffer_size, framebuffer_size: *framebuffer_size,
mouse_capture: *mouse_capture, mouse_capture: *mouse_capture,
@@ -380,6 +391,8 @@ struct Handler<'a> {
close_requested: &'a mut bool, close_requested: &'a mut bool,
last_cursor_pos: &'a mut Option<(f64, f64)>, last_cursor_pos: &'a mut Option<(f64, f64)>,
mouse_delta: &'a mut (f32, f32), mouse_delta: &'a mut (f32, f32),
modifiers: &'a mut ModifiersState,
caps_lock: &'a mut Option<bool>,
surface: &'a wgpu::Surface<'static>, surface: &'a wgpu::Surface<'static>,
device: &'a wgpu::Device, device: &'a wgpu::Device,
config: &'a mut wgpu::SurfaceConfiguration, config: &'a mut wgpu::SurfaceConfiguration,
@@ -415,10 +428,25 @@ impl<'a> ApplicationHandler for Handler<'a> {
*self.close_requested = true; *self.close_requested = true;
self.event_queue.push_back(Event::CloseRequested); self.event_queue.push_back(Event::CloseRequested);
} }
WindowEvent::ModifiersChanged(m) => *self.modifiers = m.state(),
WindowEvent::KeyboardInput { event: KeyEvent { physical_key, state, repeat, text, .. }, .. } => { WindowEvent::KeyboardInput { event: KeyEvent { physical_key, state, repeat, text, .. }, .. } => {
if let PhysicalKey::Code(code) = physical_key if let PhysicalKey::Code(code) = physical_key
&& let Some(key) = from_winit_keycode(code) && 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 { self.event_queue.push_back(Event::Key {
key, key,
pressed: state == ElementState::Pressed, pressed: state == ElementState::Pressed,
@@ -521,7 +549,7 @@ fn from_winit_keycode(k: KeyCode) -> Option<Key> {
K::ArrowUp => Key::Up, K::ArrowDown => Key::Down, K::ArrowUp => Key::Up, K::ArrowDown => Key::Down,
K::ArrowLeft => Key::Left, K::ArrowRight => Key::Right, K::ArrowLeft => Key::Left, K::ArrowRight => Key::Right,
K::Space => Key::Space, K::Enter => Key::Enter, K::Escape => Key::Escape, 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::ShiftLeft => Key::LShift, K::ShiftRight => Key::RShift,
K::ControlLeft => Key::LCtrl, K::ControlRight => Key::RCtrl, K::ControlLeft => Key::LCtrl, K::ControlRight => Key::RCtrl,
K::AltLeft => Key::LAlt, K::AltRight => Key::RAlt, K::AltLeft => Key::LAlt, K::AltRight => Key::RAlt,