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.client.event(ServerKey {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
key,
|
key,
|
||||||
state,
|
state: match state {
|
||||||
|
KeyState::Released => 0,
|
||||||
|
KeyState::Pressed => 1,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ impl EiSeat {
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
time_usec: u64,
|
time_usec: u64,
|
||||||
key: u32,
|
key: u32,
|
||||||
state: u32,
|
state: KeyState,
|
||||||
kb_state: &KeyboardState,
|
kb_state: &KeyboardState,
|
||||||
) {
|
) {
|
||||||
if self.is_sender() {
|
if self.is_sender() {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ use {
|
||||||
wl_seat::{
|
wl_seat::{
|
||||||
tablet::{TabletPad, TabletPadId, TabletTool, TabletToolId},
|
tablet::{TabletPad, TabletPadId, TabletTool, TabletToolId},
|
||||||
text_input::TextDisconnectReason,
|
text_input::TextDisconnectReason,
|
||||||
wl_keyboard::{self, WlKeyboard},
|
wl_keyboard::WlKeyboard,
|
||||||
wl_pointer::{
|
wl_pointer::{
|
||||||
self, PendingScroll, WlPointer, AXIS_DISCRETE_SINCE_VERSION,
|
self, PendingScroll, WlPointer, AXIS_DISCRETE_SINCE_VERSION,
|
||||||
AXIS_RELATIVE_DIRECTION_SINCE_VERSION, AXIS_SOURCE_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);
|
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() {
|
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.keyboard_node.get().node_on_key(
|
||||||
self,
|
self,
|
||||||
time_usec,
|
time_usec,
|
||||||
kc.to_evdev(),
|
kc.to_evdev(),
|
||||||
state,
|
key_state,
|
||||||
&kbvm_state.kb_state,
|
&kbvm_state.kb_state,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
self.for_each_ei_seat(|ei_seat| {
|
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);
|
update_pressed_keys(&mut kbvm_state);
|
||||||
}
|
}
|
||||||
|
|
@ -1339,7 +1335,7 @@ impl WlSeatGlobal {
|
||||||
surface: &WlSurface,
|
surface: &WlSurface,
|
||||||
time_usec: u64,
|
time_usec: u64,
|
||||||
key: u32,
|
key: u32,
|
||||||
state: u32,
|
state: KeyState,
|
||||||
kb_state: &KeyboardState,
|
kb_state: &KeyboardState,
|
||||||
) {
|
) {
|
||||||
let serial = surface.client.next_serial();
|
let serial = surface.client.next_serial();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
|
backend::KeyState,
|
||||||
client::{Client, ClientError},
|
client::{Client, ClientError},
|
||||||
ifs::wl_seat::{text_input::zwp_input_method_v2::ZwpInputMethodV2, wl_keyboard},
|
ifs::wl_seat::{text_input::zwp_input_method_v2::ZwpInputMethodV2, wl_keyboard},
|
||||||
keyboard::{KeyboardState, KeyboardStateId},
|
keyboard::{KeyboardState, KeyboardStateId},
|
||||||
|
|
@ -48,7 +49,7 @@ impl ZwpInputMethodKeyboardGrabV2 {
|
||||||
self.kb_state_id.set(kb_state.id);
|
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();
|
let serial = self.client.next_serial();
|
||||||
if self.kb_state_id.get() != kb_state.id {
|
if self.kb_state_id.get() != kb_state.id {
|
||||||
self.update_state(serial, kb_state);
|
self.update_state(serial, kb_state);
|
||||||
|
|
@ -56,13 +57,16 @@ impl ZwpInputMethodKeyboardGrabV2 {
|
||||||
self.send_key(serial, time_usec, key, state);
|
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.client.event(Key {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
serial: serial as _,
|
serial: serial as _,
|
||||||
time: (time_usec / 1000) as _,
|
time: (time_usec / 1000) as _,
|
||||||
key,
|
key,
|
||||||
state,
|
state: match state {
|
||||||
|
KeyState::Released => wl_keyboard::RELEASED,
|
||||||
|
KeyState::Pressed => wl_keyboard::PRESSED,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,19 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
|
backend::KeyState,
|
||||||
client::ClientError,
|
client::ClientError,
|
||||||
ifs::wl_seat::WlSeat,
|
ifs::wl_seat::WlSeat,
|
||||||
keyboard::{KeyboardError, KeyboardState, KeyboardStateId},
|
keyboard::{KeyboardError, KeyboardState, KeyboardStateId},
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::{Object, Version},
|
object::{Object, Version},
|
||||||
utils::errorfmt::ErrorFmt,
|
utils::{errorfmt::ErrorFmt, vecset::VecSet},
|
||||||
wire::{wl_keyboard::*, WlKeyboardId, WlSurfaceId},
|
wire::{wl_keyboard::*, WlKeyboardId, WlSurfaceId},
|
||||||
},
|
},
|
||||||
kbvm::Components,
|
kbvm::Components,
|
||||||
std::{cell::Cell, rc::Rc},
|
std::{
|
||||||
|
cell::{Cell, RefCell},
|
||||||
|
rc::Rc,
|
||||||
|
},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -26,6 +30,7 @@ pub struct WlKeyboard {
|
||||||
id: WlKeyboardId,
|
id: WlKeyboardId,
|
||||||
seat: Rc<WlSeat>,
|
seat: Rc<WlSeat>,
|
||||||
kb_state_id: Cell<KeyboardStateId>,
|
kb_state_id: Cell<KeyboardStateId>,
|
||||||
|
pressed_keys: RefCell<VecSet<u32>>,
|
||||||
pub tracker: Tracker<Self>,
|
pub tracker: Tracker<Self>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,6 +40,7 @@ impl WlKeyboard {
|
||||||
id,
|
id,
|
||||||
seat: seat.clone(),
|
seat: seat.clone(),
|
||||||
kb_state_id: Cell::new(KeyboardStateId::from_raw(0)),
|
kb_state_id: Cell::new(KeyboardStateId::from_raw(0)),
|
||||||
|
pressed_keys: Default::default(),
|
||||||
tracker: Default::default(),
|
tracker: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -89,6 +95,11 @@ impl WlKeyboard {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_enter(&self, serial: u64, surface: WlSurfaceId, keys: &[u32]) {
|
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.seat.client.event(Enter {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
serial: serial as _,
|
serial: serial as _,
|
||||||
|
|
@ -110,7 +121,7 @@ impl WlKeyboard {
|
||||||
serial: u64,
|
serial: u64,
|
||||||
time: u32,
|
time: u32,
|
||||||
key: u32,
|
key: u32,
|
||||||
state: u32,
|
state: KeyState,
|
||||||
surface: WlSurfaceId,
|
surface: WlSurfaceId,
|
||||||
kb_state: &KeyboardState,
|
kb_state: &KeyboardState,
|
||||||
) {
|
) {
|
||||||
|
|
@ -120,13 +131,31 @@ impl WlKeyboard {
|
||||||
self.send_key(serial, time, key, state);
|
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.seat.client.event(Key {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
serial: serial as _,
|
serial: serial as _,
|
||||||
time,
|
time,
|
||||||
key,
|
key,
|
||||||
state,
|
state: match state {
|
||||||
|
KeyState::Released => RELEASED,
|
||||||
|
KeyState::Pressed => PRESSED,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
|
backend::KeyState,
|
||||||
client::{Client, ClientError},
|
client::{Client, ClientError},
|
||||||
clientmem::{ClientMem, ClientMemError},
|
clientmem::{ClientMem, ClientMemError},
|
||||||
ifs::{
|
ifs::{
|
||||||
|
|
@ -90,14 +91,14 @@ impl ZwpVirtualKeyboardV1RequestHandler for ZwpVirtualKeyboardV1 {
|
||||||
fn key(&self, req: Key, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn key(&self, req: Key, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
let kb_state = &mut *self.kb_state.borrow_mut();
|
let kb_state = &mut *self.kb_state.borrow_mut();
|
||||||
let contains = kb_state.pressed_keys.contains(&req.key);
|
let contains = kb_state.pressed_keys.contains(&req.key);
|
||||||
let valid = match req.state {
|
let (state, valid) = match req.state {
|
||||||
wl_keyboard::RELEASED => contains,
|
wl_keyboard::RELEASED => (KeyState::Released, contains),
|
||||||
wl_keyboard::PRESSED => !contains,
|
wl_keyboard::PRESSED => (KeyState::Pressed, !contains),
|
||||||
_ => return Err(ZwpVirtualKeyboardV1Error::UnknownState(req.state)),
|
_ => return Err(ZwpVirtualKeyboardV1Error::UnknownState(req.state)),
|
||||||
};
|
};
|
||||||
if valid {
|
if valid {
|
||||||
self.for_each_kb(|serial, surface, kb| {
|
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 {
|
match req.state {
|
||||||
wl_keyboard::RELEASED => kb_state.pressed_keys.remove(&req.key),
|
wl_keyboard::RELEASED => kb_state.pressed_keys.remove(&req.key),
|
||||||
|
|
|
||||||
|
|
@ -1741,7 +1741,7 @@ impl Node for WlSurface {
|
||||||
seat: &WlSeatGlobal,
|
seat: &WlSeatGlobal,
|
||||||
time_usec: u64,
|
time_usec: u64,
|
||||||
key: u32,
|
key: u32,
|
||||||
state: u32,
|
state: KeyState,
|
||||||
kb_state: &KeyboardState,
|
kb_state: &KeyboardState,
|
||||||
) {
|
) {
|
||||||
seat.key_surface(self, time_usec, key, state, kb_state);
|
seat.key_surface(self, time_usec, key, state, kb_state);
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ pub trait Node: 'static {
|
||||||
seat: &WlSeatGlobal,
|
seat: &WlSeatGlobal,
|
||||||
time_usec: u64,
|
time_usec: u64,
|
||||||
key: u32,
|
key: u32,
|
||||||
state: u32,
|
state: KeyState,
|
||||||
kb_state: &KeyboardState,
|
kb_state: &KeyboardState,
|
||||||
) {
|
) {
|
||||||
let _ = seat;
|
let _ = seat;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ impl<T> Deref for VecSet<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> VecSet<T> {
|
impl<T> VecSet<T> {
|
||||||
#[expect(dead_code)]
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.vec.clear();
|
self.vec.clear();
|
||||||
}
|
}
|
||||||
|
|
@ -47,4 +46,13 @@ impl<T: PartialEq> VecSet<T> {
|
||||||
pub fn pop(&mut self) -> Option<T> {
|
pub fn pop(&mut self) -> Option<T> {
|
||||||
self.vec.pop()
|
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