keyboard/state: handle repeat rate 0, let widgets see Escape
- wl_keyboard.repeat_info with rate 0 means "no repeat"; we divided by it. - an unknown keymap format hit unreachable!() instead of being ignored. - raw keycode 1 (Escape) returned before widgets were dispatched, so the launcher's Escape handler (which saves the prompt for Ctrl+R) never ran. Dispatch first, then fall back to quitting. - always lay out on the first layer-surface configure, even when the compositor hands us exactly the placeholder dimensions. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
450a20bf63
commit
8c319cffc6
+5
-2
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
default::Default,
|
default::Default,
|
||||||
os::unix::io::{AsRawFd, OwnedFd},
|
os::unix::io::OwnedFd,
|
||||||
};
|
};
|
||||||
|
|
||||||
use wayland_client::{protocol::wl_keyboard, WEnum};
|
use wayland_client::{protocol::wl_keyboard, WEnum};
|
||||||
@@ -31,6 +31,7 @@ pub use self::state::ModifiersState;
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct KeyEvent {
|
pub struct KeyEvent {
|
||||||
|
#[allow(dead_code)]
|
||||||
pub rawkey: u32,
|
pub rawkey: u32,
|
||||||
pub keysym: u32,
|
pub keysym: u32,
|
||||||
pub state: WEnum<wl_keyboard::KeyState>,
|
pub state: WEnum<wl_keyboard::KeyState>,
|
||||||
@@ -77,7 +78,9 @@ impl Keyboard {
|
|||||||
WEnum::Value(wl_keyboard::KeymapFormat::NoKeymap) => {
|
WEnum::Value(wl_keyboard::KeymapFormat::NoKeymap) => {
|
||||||
// TODO: how to handle this (hopefully never occuring) case?
|
// TODO: how to handle this (hopefully never occuring) case?
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
// Unknown format from a newer protocol version: ignore rather than
|
||||||
|
// abort the whole process.
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,12 @@ impl EventSource for KeyRepeatSource {
|
|||||||
_ => (),
|
_ => (),
|
||||||
},
|
},
|
||||||
RepeatMessage::RepeatInfo((new_rate, new_delay)) => {
|
RepeatMessage::RepeatInfo((new_rate, new_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);
|
*rate = Duration::from_micros(1_000_000 / new_rate as u64);
|
||||||
*delay = Duration::from_millis(new_delay as u64);
|
*delay = Duration::from_millis(new_delay as u64);
|
||||||
*disabled = false;
|
*disabled = false;
|
||||||
@@ -96,6 +102,7 @@ impl EventSource for KeyRepeatSource {
|
|||||||
timer.set_deadline(now + *delay);
|
timer.set_deadline(now + *delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
channel::Event::Closed => {
|
channel::Event::Closed => {
|
||||||
|
|||||||
+12
-5
@@ -461,12 +461,15 @@ impl Dispatch<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1, ()> for State {
|
|||||||
(width, height) = (640, 480);
|
(width, height) = (640, 480);
|
||||||
}
|
}
|
||||||
layer_surface.ack_configure(serial);
|
layer_surface.ack_configure(serial);
|
||||||
|
let first_configure = !state.configured;
|
||||||
state.configured = true;
|
state.configured = true;
|
||||||
state.dirty = true;
|
state.dirty = true;
|
||||||
|
|
||||||
let dim = (width as i32, height as i32);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
state.bufmgr.clear_buffers();
|
state.bufmgr.clear_buffers();
|
||||||
@@ -656,17 +659,21 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for State {
|
|||||||
state: kbstate,
|
state: kbstate,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if key == 1 {
|
|
||||||
state.running = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state.keyboard.resolve();
|
state.keyboard.resolve();
|
||||||
let k = state.keyboard.key(key, kbstate);
|
let k = state.keyboard.key(key, kbstate);
|
||||||
let repeats = k.repeats;
|
let repeats = k.repeats;
|
||||||
let ev = Event::KeyEvent(k);
|
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() {
|
for widget in state.widgets.iter_mut() {
|
||||||
widget.event(&ev);
|
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 repeats {
|
||||||
if let Event::KeyEvent(k) = ev {
|
if let Event::KeyEvent(k) = ev {
|
||||||
state
|
state
|
||||||
|
|||||||
Reference in New Issue
Block a user