diff --git a/src/keyboard/mod.rs b/src/keyboard/mod.rs index 4ee4efa..ef3e446 100644 --- a/src/keyboard/mod.rs +++ b/src/keyboard/mod.rs @@ -14,7 +14,7 @@ use std::{ default::Default, - os::unix::io::{AsRawFd, OwnedFd}, + os::unix::io::OwnedFd, }; use wayland_client::{protocol::wl_keyboard, WEnum}; @@ -31,6 +31,7 @@ pub use self::state::ModifiersState; #[derive(Debug, Clone)] pub struct KeyEvent { + #[allow(dead_code)] pub rawkey: u32, pub keysym: u32, pub state: WEnum, @@ -77,7 +78,9 @@ impl Keyboard { WEnum::Value(wl_keyboard::KeymapFormat::NoKeymap) => { // TODO: how to handle this (hopefully never occuring) case? } - _ => unreachable!(), + // Unknown format from a newer protocol version: ignore rather than + // abort the whole process. + _ => (), } } diff --git a/src/keyboard/repeat.rs b/src/keyboard/repeat.rs index 41b984b..991182b 100644 --- a/src/keyboard/repeat.rs +++ b/src/keyboard/repeat.rs @@ -89,11 +89,18 @@ impl EventSource for KeyRepeatSource { _ => (), }, RepeatMessage::RepeatInfo((new_rate, new_delay)) => { - *rate = Duration::from_micros(1_000_000 / new_rate as u64); - *delay = Duration::from_millis(new_delay as u64); - *disabled = false; - if key.is_some() { - timer.set_deadline(now + *delay); + // Per wl_keyboard.repeat_info, a rate of 0 disables + // key repeat entirely. Dividing by it would panic. + if new_rate == 0 { + *disabled = true; + key.take(); + } else { + *rate = Duration::from_micros(1_000_000 / new_rate as u64); + *delay = Duration::from_millis(new_delay as u64); + *disabled = false; + if key.is_some() { + timer.set_deadline(now + *delay); + } } } }, diff --git a/src/state.rs b/src/state.rs index 61a57bd..8abfd82 100644 --- a/src/state.rs +++ b/src/state.rs @@ -461,12 +461,15 @@ impl Dispatch for State { (width, height) = (640, 480); } layer_surface.ack_configure(serial); + let first_configure = !state.configured; state.configured = true; state.dirty = true; let dim = (width as i32, height as i32); - if state.configured && state.dimensions == dim { + // Always lay out on the first configure, even if the + // compositor happens to hand us our placeholder dimensions. + if !first_configure && state.dimensions == dim { return; } state.bufmgr.clear_buffers(); @@ -656,17 +659,21 @@ impl Dispatch for State { state: kbstate, .. } => { - if key == 1 { - state.running = false; - return; - } state.keyboard.resolve(); let k = state.keyboard.key(key, kbstate); let repeats = k.repeats; let ev = Event::KeyEvent(k); + // Widgets see the key first so the launcher gets to save its + // prompt on Escape (the early-return used to swallow it). for widget in state.widgets.iter_mut() { widget.event(&ev); } + // Raw keycode 1 is KEY_ESC: fall back to quitting even when no + // keymap could be loaded and no widget handled it. + if key == 1 && kbstate == WEnum::Value(wl_keyboard::KeyState::Pressed) { + state.running = false; + return; + } if repeats { if let Event::KeyEvent(k) = ev { state