Capslock: Key::CapsLock-Event und heuristischer caps_lock()-Zustand
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
8c647d3700
commit
0df016d69c
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user