wl_keyboard: don't send key-up events for keys that are not logically down
This commit is contained in:
parent
abaeed4c01
commit
53c38bdd68
9 changed files with 68 additions and 27 deletions
|
|
@ -52,11 +52,14 @@ impl EiKeyboard {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn send_key(&self, key: u32, state: u32) {
|
||||
pub fn send_key(&self, key: u32, state: KeyState) {
|
||||
self.client.event(ServerKey {
|
||||
self_id: self.id,
|
||||
key,
|
||||
state,
|
||||
state: match state {
|
||||
KeyState::Released => 0,
|
||||
KeyState::Pressed => 1,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ impl EiSeat {
|
|||
self: &Rc<Self>,
|
||||
time_usec: u64,
|
||||
key: u32,
|
||||
state: u32,
|
||||
state: KeyState,
|
||||
kb_state: &KeyboardState,
|
||||
) {
|
||||
if self.is_sender() {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use {
|
|||
wl_seat::{
|
||||
tablet::{TabletPad, TabletPadId, TabletTool, TabletToolId},
|
||||
text_input::TextDisconnectReason,
|
||||
wl_keyboard::{self, WlKeyboard},
|
||||
wl_keyboard::WlKeyboard,
|
||||
wl_pointer::{
|
||||
self, PendingScroll, WlPointer, AXIS_DISCRETE_SINCE_VERSION,
|
||||
AXIS_RELATIVE_DIRECTION_SINCE_VERSION, AXIS_SOURCE_SINCE_VERSION,
|
||||
|
|
@ -873,22 +873,18 @@ impl WlSeatGlobal {
|
|||
}
|
||||
}
|
||||
self.send_components(&mut components_changed, &kbvm_state);
|
||||
let state = match key_state {
|
||||
KeyState::Released => wl_keyboard::RELEASED,
|
||||
KeyState::Pressed => wl_keyboard::PRESSED,
|
||||
};
|
||||
match self.input_method_grab.get() {
|
||||
Some(g) => g.on_key(time_usec, kc.to_evdev(), state, &kbvm_state.kb_state),
|
||||
Some(g) => g.on_key(time_usec, kc.to_evdev(), key_state, &kbvm_state.kb_state),
|
||||
_ => self.keyboard_node.get().node_on_key(
|
||||
self,
|
||||
time_usec,
|
||||
kc.to_evdev(),
|
||||
state,
|
||||
key_state,
|
||||
&kbvm_state.kb_state,
|
||||
),
|
||||
}
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_key(time_usec, kc.to_evdev(), state, &kbvm_state.kb_state);
|
||||
ei_seat.handle_key(time_usec, kc.to_evdev(), key_state, &kbvm_state.kb_state);
|
||||
});
|
||||
update_pressed_keys(&mut kbvm_state);
|
||||
}
|
||||
|
|
@ -1339,7 +1335,7 @@ impl WlSeatGlobal {
|
|||
surface: &WlSurface,
|
||||
time_usec: u64,
|
||||
key: u32,
|
||||
state: u32,
|
||||
state: KeyState,
|
||||
kb_state: &KeyboardState,
|
||||
) {
|
||||
let serial = surface.client.next_serial();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
backend::KeyState,
|
||||
client::{Client, ClientError},
|
||||
ifs::wl_seat::{text_input::zwp_input_method_v2::ZwpInputMethodV2, wl_keyboard},
|
||||
keyboard::{KeyboardState, KeyboardStateId},
|
||||
|
|
@ -48,7 +49,7 @@ impl ZwpInputMethodKeyboardGrabV2 {
|
|||
self.kb_state_id.set(kb_state.id);
|
||||
}
|
||||
|
||||
pub fn on_key(&self, time_usec: u64, key: u32, state: u32, kb_state: &KeyboardState) {
|
||||
pub fn on_key(&self, time_usec: u64, key: u32, state: KeyState, kb_state: &KeyboardState) {
|
||||
let serial = self.client.next_serial();
|
||||
if self.kb_state_id.get() != kb_state.id {
|
||||
self.update_state(serial, kb_state);
|
||||
|
|
@ -56,13 +57,16 @@ impl ZwpInputMethodKeyboardGrabV2 {
|
|||
self.send_key(serial, time_usec, key, state);
|
||||
}
|
||||
|
||||
fn send_key(&self, serial: u64, time_usec: u64, key: u32, state: u32) {
|
||||
fn send_key(&self, serial: u64, time_usec: u64, key: u32, state: KeyState) {
|
||||
self.client.event(Key {
|
||||
self_id: self.id,
|
||||
serial: serial as _,
|
||||
time: (time_usec / 1000) as _,
|
||||
key,
|
||||
state,
|
||||
state: match state {
|
||||
KeyState::Released => wl_keyboard::RELEASED,
|
||||
KeyState::Pressed => wl_keyboard::PRESSED,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
use {
|
||||
crate::{
|
||||
backend::KeyState,
|
||||
client::ClientError,
|
||||
ifs::wl_seat::WlSeat,
|
||||
keyboard::{KeyboardError, KeyboardState, KeyboardStateId},
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
utils::errorfmt::ErrorFmt,
|
||||
utils::{errorfmt::ErrorFmt, vecset::VecSet},
|
||||
wire::{wl_keyboard::*, WlKeyboardId, WlSurfaceId},
|
||||
},
|
||||
kbvm::Components,
|
||||
std::{cell::Cell, rc::Rc},
|
||||
std::{
|
||||
cell::{Cell, RefCell},
|
||||
rc::Rc,
|
||||
},
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
|
|
@ -26,6 +30,7 @@ pub struct WlKeyboard {
|
|||
id: WlKeyboardId,
|
||||
seat: Rc<WlSeat>,
|
||||
kb_state_id: Cell<KeyboardStateId>,
|
||||
pressed_keys: RefCell<VecSet<u32>>,
|
||||
pub tracker: Tracker<Self>,
|
||||
}
|
||||
|
||||
|
|
@ -35,6 +40,7 @@ impl WlKeyboard {
|
|||
id,
|
||||
seat: seat.clone(),
|
||||
kb_state_id: Cell::new(KeyboardStateId::from_raw(0)),
|
||||
pressed_keys: Default::default(),
|
||||
tracker: Default::default(),
|
||||
}
|
||||
}
|
||||
|
|
@ -89,6 +95,11 @@ impl WlKeyboard {
|
|||
}
|
||||
|
||||
fn send_enter(&self, serial: u64, surface: WlSurfaceId, keys: &[u32]) {
|
||||
{
|
||||
let pk = &mut self.pressed_keys.borrow_mut();
|
||||
pk.clear();
|
||||
pk.extend(keys);
|
||||
}
|
||||
self.seat.client.event(Enter {
|
||||
self_id: self.id,
|
||||
serial: serial as _,
|
||||
|
|
@ -110,7 +121,7 @@ impl WlKeyboard {
|
|||
serial: u64,
|
||||
time: u32,
|
||||
key: u32,
|
||||
state: u32,
|
||||
state: KeyState,
|
||||
surface: WlSurfaceId,
|
||||
kb_state: &KeyboardState,
|
||||
) {
|
||||
|
|
@ -120,13 +131,31 @@ impl WlKeyboard {
|
|||
self.send_key(serial, time, key, state);
|
||||
}
|
||||
|
||||
fn send_key(&self, serial: u64, time: u32, key: u32, state: u32) {
|
||||
fn send_key(&self, serial: u64, time: u32, key: u32, state: KeyState) {
|
||||
{
|
||||
let pk = &mut self.pressed_keys.borrow_mut();
|
||||
match state {
|
||||
KeyState::Released => {
|
||||
if !pk.remove(&key) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
KeyState::Pressed => {
|
||||
if !pk.insert(key) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.seat.client.event(Key {
|
||||
self_id: self.id,
|
||||
serial: serial as _,
|
||||
time,
|
||||
key,
|
||||
state,
|
||||
state: match state {
|
||||
KeyState::Released => RELEASED,
|
||||
KeyState::Pressed => PRESSED,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
backend::KeyState,
|
||||
client::{Client, ClientError},
|
||||
clientmem::{ClientMem, ClientMemError},
|
||||
ifs::{
|
||||
|
|
@ -90,14 +91,14 @@ impl ZwpVirtualKeyboardV1RequestHandler for ZwpVirtualKeyboardV1 {
|
|||
fn key(&self, req: Key, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
let kb_state = &mut *self.kb_state.borrow_mut();
|
||||
let contains = kb_state.pressed_keys.contains(&req.key);
|
||||
let valid = match req.state {
|
||||
wl_keyboard::RELEASED => contains,
|
||||
wl_keyboard::PRESSED => !contains,
|
||||
let (state, valid) = match req.state {
|
||||
wl_keyboard::RELEASED => (KeyState::Released, contains),
|
||||
wl_keyboard::PRESSED => (KeyState::Pressed, !contains),
|
||||
_ => return Err(ZwpVirtualKeyboardV1Error::UnknownState(req.state)),
|
||||
};
|
||||
if valid {
|
||||
self.for_each_kb(|serial, surface, kb| {
|
||||
kb.on_key(serial, req.time, req.key, req.state, surface.id, kb_state);
|
||||
kb.on_key(serial, req.time, req.key, state, surface.id, kb_state);
|
||||
});
|
||||
match req.state {
|
||||
wl_keyboard::RELEASED => kb_state.pressed_keys.remove(&req.key),
|
||||
|
|
|
|||
|
|
@ -1741,7 +1741,7 @@ impl Node for WlSurface {
|
|||
seat: &WlSeatGlobal,
|
||||
time_usec: u64,
|
||||
key: u32,
|
||||
state: u32,
|
||||
state: KeyState,
|
||||
kb_state: &KeyboardState,
|
||||
) {
|
||||
seat.key_surface(self, time_usec, key, state, kb_state);
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ pub trait Node: 'static {
|
|||
seat: &WlSeatGlobal,
|
||||
time_usec: u64,
|
||||
key: u32,
|
||||
state: u32,
|
||||
state: KeyState,
|
||||
kb_state: &KeyboardState,
|
||||
) {
|
||||
let _ = seat;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ impl<T> Deref for VecSet<T> {
|
|||
}
|
||||
|
||||
impl<T> VecSet<T> {
|
||||
#[expect(dead_code)]
|
||||
pub fn clear(&mut self) {
|
||||
self.vec.clear();
|
||||
}
|
||||
|
|
@ -47,4 +46,13 @@ impl<T: PartialEq> VecSet<T> {
|
|||
pub fn pop(&mut self) -> Option<T> {
|
||||
self.vec.pop()
|
||||
}
|
||||
|
||||
pub fn extend(&mut self, vals: &[T])
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
for v in vals.iter().copied() {
|
||||
self.insert(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue