From a7d71d9aceddcdd6cad5628b6ca18aab89edfa97 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Wed, 27 May 2026 11:30:30 -0400 Subject: [PATCH] chore: modifiers event on keyboard enter and leave --- .../wayland/event_loop/state.rs | 8 +-- .../wayland/handlers/seat/keyboard.rs | 60 +++++++++++++++++-- .../wayland/handlers/seat/seat.rs | 5 +- 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index f99e48ba..e47caa94 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -30,7 +30,6 @@ use std::{ convert::Infallible, fmt::Debug, sync::{Arc, Mutex, atomic::AtomicU32}, - thread::panicking, time::Duration, }; use wayland_backend::client::ObjectId; @@ -71,7 +70,7 @@ use cctk::{ registry::RegistryState, seat::{ SeatState, - keyboard::KeyEvent, + keyboard::{KeyEvent, Modifiers}, pointer::{CursorIcon, PointerData, ThemedPointer}, touch::TouchData, }, @@ -97,7 +96,6 @@ use cctk::{ }; use iced_runtime::{ core::{self, Point, touch}, - keyboard::Modifiers, platform_specific::{ self, wayland::{ @@ -1469,7 +1467,7 @@ impl SctkState { // TODO how to handle this when there's no lock? if let Some((surface, _)) = self.get_lock_surface(id, &output) { let wl_surface = surface.wl_surface(); - + receive_frame(&mut self.frame_status, &wl_surface); } } @@ -1653,7 +1651,7 @@ impl SctkState { bg_effect_mgr.enqueue(id, rectangles.clone()); return Ok(()); } - + let s = if let Some(s) = self.popups.iter().find(|s| s.data.id == id) { s.popup.wl_surface() } else if let Some(s) = self.layer_surfaces.iter().find(|s| s.id == id) { diff --git a/winit/src/platform_specific/wayland/handlers/seat/keyboard.rs b/winit/src/platform_specific/wayland/handlers/seat/keyboard.rs index 5ff7fb4b..f83e1180 100644 --- a/winit/src/platform_specific/wayland/handlers/seat/keyboard.rs +++ b/winit/src/platform_specific/wayland/handlers/seat/keyboard.rs @@ -4,10 +4,46 @@ use crate::platform_specific::wayland::{ }; use cctk::sctk::{ delegate_keyboard, - seat::keyboard::{KeyboardHandler, Keysym}, + seat::keyboard::{KeyboardHandler, Keysym, Modifiers}, }; use cctk::sctk::{reexports::client::Proxy, seat::keyboard::RawModifiers}; +fn modifiers_from_keysyms( + keysyms: &[Keysym], + previous: Modifiers, +) -> Modifiers { + let mut modifiers = Modifiers { + caps_lock: previous.caps_lock, + num_lock: previous.num_lock, + ..Modifiers::default() + }; + + for keysym in keysyms { + match keysym.raw() { + xkeysym::key::Shift_L | xkeysym::key::Shift_R => { + modifiers.shift = true + } + xkeysym::key::Control_L | xkeysym::key::Control_R => { + modifiers.ctrl = true + } + xkeysym::key::Alt_L | xkeysym::key::Alt_R => modifiers.alt = true, + xkeysym::key::Super_L + | xkeysym::key::Super_R + | xkeysym::key::Hyper_L + | xkeysym::key::Hyper_R + | xkeysym::key::Meta_L + | xkeysym::key::Meta_R => modifiers.logo = true, + xkeysym::key::Caps_Lock | xkeysym::key::Shift_Lock => { + modifiers.caps_lock = true + } + xkeysym::key::Num_Lock => modifiers.num_lock = true, + _ => {} + } + } + + modifiers +} + impl KeyboardHandler for SctkState { fn enter( &mut self, @@ -17,9 +53,9 @@ impl KeyboardHandler for SctkState { surface: &cctk::sctk::reexports::client::protocol::wl_surface::WlSurface, _serial: u32, _raw: &[u32], - _keysyms: &[Keysym], + keysyms: &[Keysym], ) { - let (i, mut is_active, seat) = { + let (i, mut is_active, seat, modifiers) = { let (i, is_active, my_seat) = match self.seats.iter_mut().enumerate().find_map(|(i, s)| { if s.kbd.as_ref() == Some(keyboard) { @@ -41,9 +77,11 @@ impl KeyboardHandler for SctkState { surface }; _ = my_seat.kbd_focus.replace(surface.clone()); + let modifiers = modifiers_from_keysyms(keysyms, my_seat._modifiers); + my_seat._modifiers = modifiers; let seat = my_seat.seat.clone(); - (i, is_active, seat) + (i, is_active, seat, modifiers) }; if !is_active && self.seats[0].kbd_focus.is_none() { @@ -73,6 +111,12 @@ impl KeyboardHandler for SctkState { seat_id: seat.clone(), surface: surface.clone(), }); + self.sctk_events.push(SctkEvent::KeyboardEvent { + variant: KeyboardEventVariant::Modifiers(modifiers), + kbd_id: keyboard.clone(), + seat_id: seat.clone(), + surface: surface.clone(), + }); } } } @@ -126,6 +170,7 @@ impl KeyboardHandler for SctkState { if self.windows.iter().any(|w| w.window.id() == id) { continue; } + let modifiers = s._modifiers; self.sctk_events.push(SctkEvent::Winit( id, winit::event::WindowEvent::Focused(true), @@ -137,6 +182,12 @@ impl KeyboardHandler for SctkState { kbd_id: s.kbd.clone().unwrap(), seat_id: s.seat.clone(), surface: surface.clone(), + }); + self.sctk_events.push(SctkEvent::KeyboardEvent { + variant: KeyboardEventVariant::Modifiers(modifiers), + kbd_id: s.kbd.clone().unwrap(), + seat_id: s.seat.clone(), + surface: surface.clone(), }) } } @@ -248,6 +299,7 @@ impl KeyboardHandler for SctkState { }; let seat_id = my_seat.seat.clone(); let kbd_id = keyboard.clone(); + my_seat._modifiers = modifiers; if is_active { if let Some(surface) = my_seat.kbd_focus.clone() { diff --git a/winit/src/platform_specific/wayland/handlers/seat/seat.rs b/winit/src/platform_specific/wayland/handlers/seat/seat.rs index 2901ce8e..ee6b0e6e 100644 --- a/winit/src/platform_specific/wayland/handlers/seat/seat.rs +++ b/winit/src/platform_specific/wayland/handlers/seat/seat.rs @@ -4,10 +4,9 @@ use crate::platform_specific::wayland::{ }; use cctk::sctk::{ delegate_seat, - reexports::client::{protocol::wl_keyboard::WlKeyboard, Proxy}, - seat::{pointer::ThemeSpec, SeatHandler}, + reexports::client::{Proxy, protocol::wl_keyboard::WlKeyboard}, + seat::{SeatHandler, keyboard::Modifiers, pointer::ThemeSpec}, }; -use iced_runtime::keyboard::Modifiers; use std::sync::Arc; impl SeatHandler for SctkState {