diff --git a/Cargo.lock b/Cargo.lock index ba35429..c1cdd72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4188,6 +4188,7 @@ name = "waycrate_xkbkeycode" version = "0.9.5" dependencies = [ "bitflags 2.6.0", + "calloop 0.14.1", "log", "memmap2", "smol_str", diff --git a/layershellev/src/lib.rs b/layershellev/src/lib.rs index 84366ee..218ef54 100644 --- a/layershellev/src/lib.rs +++ b/layershellev/src/lib.rs @@ -1151,12 +1151,26 @@ impl Dispatch for WindowState { } _ => unreachable!(), }, + wl_keyboard::Event::Enter { .. } => { + if let (Some(token), Some(loop_handle)) = ( + keyboard_state.repeat_token.take(), + state.loop_handler.as_ref(), + ) { + loop_handle.remove(token); + } + } wl_keyboard::Event::Leave { .. } => { keyboard_state.current_repeat = None; state.message.push(( surface_id, DispatchMessageInner::ModifiersChanged(ModifiersState::empty()), )); + if let (Some(token), Some(loop_handle)) = ( + keyboard_state.repeat_token.take(), + state.loop_handler.as_ref(), + ) { + loop_handle.remove(token); + } } wl_keyboard::Event::Key { state: keystate, @@ -1196,10 +1210,17 @@ impl Dispatch for WindowState { } keyboard_state.current_repeat = Some(key); + + if let (Some(token), Some(loop_handle)) = ( + keyboard_state.repeat_token.take(), + state.loop_handler.as_ref(), + ) { + loop_handle.remove(token); + } let timer = Timer::from_duration(delay); if let Some(looph) = state.loop_handler.as_ref() { - looph + keyboard_state.repeat_token = looph .insert_source(timer, move |_, _, state| { let keyboard_state = match state.keyboard_state.as_mut() { Some(keyboard_state) => keyboard_state, @@ -1247,6 +1268,12 @@ impl Dispatch for WindowState { && Some(key) == keyboard_state.current_repeat { keyboard_state.current_repeat = None; + if let (Some(token), Some(loop_handle)) = ( + keyboard_state.repeat_token.take(), + state.loop_handler.as_ref(), + ) { + loop_handle.remove(token); + } } } } @@ -1275,6 +1302,12 @@ impl Dispatch for WindowState { keyboard_state.repeat_info = if rate == 0 { // Stop the repeat once we get a disable event. keyboard_state.current_repeat = None; + if let (Some(token), Some(loop_handle)) = ( + keyboard_state.repeat_token.take(), + state.loop_handler.as_ref(), + ) { + loop_handle.remove(token); + } RepeatInfo::Disable } else { let gap = Duration::from_micros(1_000_000 / rate as u64); diff --git a/waycrate_xkbkeycode/Cargo.toml b/waycrate_xkbkeycode/Cargo.toml index 5ca5479..ce5c501 100644 --- a/waycrate_xkbkeycode/Cargo.toml +++ b/waycrate_xkbkeycode/Cargo.toml @@ -17,3 +17,4 @@ bitflags.workspace = true wayland-client.workspace = true wayland-backend.workspace = true log.workspace = true +calloop.workspace = true diff --git a/waycrate_xkbkeycode/src/xkb_keyboard.rs b/waycrate_xkbkeycode/src/xkb_keyboard.rs index 11ec3f1..c922020 100644 --- a/waycrate_xkbkeycode/src/xkb_keyboard.rs +++ b/waycrate_xkbkeycode/src/xkb_keyboard.rs @@ -28,6 +28,8 @@ use xkb::{ use crate::keyboard::{Key, KeyLocation, PhysicalKey}; +use calloop::RegistrationToken; + static RESET_DEAD_KEYS: AtomicBool = AtomicBool::new(false); pub static XKBH: LazyLock<&'static XkbCommon> = LazyLock::new(xkbcommon_handle); @@ -66,6 +68,7 @@ pub struct KeyboardState { pub xkb_context: Context, pub repeat_info: RepeatInfo, + pub repeat_token: Option, pub current_repeat: Option, } @@ -76,6 +79,7 @@ impl KeyboardState { xkb_context: Context::new().unwrap(), repeat_info: RepeatInfo::default(), current_repeat: None, + repeat_token: None, } } }