ei: make handling of touchscreen events stricter
This commit is contained in:
parent
b52d754beb
commit
1495cc1f22
3 changed files with 32 additions and 16 deletions
|
|
@ -11,7 +11,7 @@ use {
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
rect::Rect,
|
rect::Rect,
|
||||||
scale::Scale,
|
scale::Scale,
|
||||||
utils::syncqueue::SyncQueue,
|
utils::{copyhashmap::CopyHashMap, syncqueue::SyncQueue},
|
||||||
wire_ei::{
|
wire_ei::{
|
||||||
ei_device::{
|
ei_device::{
|
||||||
ClientFrame, ClientStartEmulating, ClientStopEmulating, Destroyed, DeviceType,
|
ClientFrame, ClientStartEmulating, ClientStopEmulating, Destroyed, DeviceType,
|
||||||
|
|
@ -37,7 +37,7 @@ pub struct EiDevice {
|
||||||
pub seat: Rc<EiSeat>,
|
pub seat: Rc<EiSeat>,
|
||||||
|
|
||||||
pub button_changes: SyncQueue<(u32, KeyState)>,
|
pub button_changes: SyncQueue<(u32, KeyState)>,
|
||||||
pub touch_changes: SyncQueue<(u32, TouchChange)>,
|
pub touch_changes: CopyHashMap<u32, TouchChange>,
|
||||||
pub scroll_px: [Cell<Option<f32>>; 2],
|
pub scroll_px: [Cell<Option<f32>>; 2],
|
||||||
pub scroll_v120: [Cell<Option<i32>>; 2],
|
pub scroll_v120: [Cell<Option<i32>>; 2],
|
||||||
pub scroll_stop: [Cell<Option<bool>>; 2],
|
pub scroll_stop: [Cell<Option<bool>>; 2],
|
||||||
|
|
@ -219,7 +219,7 @@ impl EiDeviceRequestHandler for EiDevice {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.touch_changes.is_not_empty() {
|
if self.touch_changes.is_not_empty() {
|
||||||
while let Some((touch_id, change)) = self.touch_changes.pop() {
|
for (touch_id, change) in self.touch_changes.lock().drain() {
|
||||||
let id = touch_id as i32;
|
let id = touch_id as i32;
|
||||||
match change {
|
match change {
|
||||||
TouchChange::Down(x, y) => {
|
TouchChange::Down(x, y) => {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use {
|
||||||
},
|
},
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
|
utils::clonecell::UnsafeCellCloneSafe,
|
||||||
wire_ei::{
|
wire_ei::{
|
||||||
ei_touchscreen::{
|
ei_touchscreen::{
|
||||||
ClientDown, ClientMotion, ClientUp, EiTouchscreenRequestHandler, Release,
|
ClientDown, ClientMotion, ClientUp, EiTouchscreenRequestHandler, Release,
|
||||||
|
|
@ -15,7 +16,7 @@ use {
|
||||||
EiTouchscreenId,
|
EiTouchscreenId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
std::rc::Rc,
|
std::{collections::hash_map::Entry, rc::Rc},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -34,6 +35,8 @@ pub enum TouchChange {
|
||||||
Up,
|
Up,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl UnsafeCellCloneSafe for TouchChange {}
|
||||||
|
|
||||||
ei_device_interface!(EiTouchscreen, ei_touchscreen, touchscreen);
|
ei_device_interface!(EiTouchscreen, ei_touchscreen, touchscreen);
|
||||||
|
|
||||||
impl EiTouchscreen {
|
impl EiTouchscreen {
|
||||||
|
|
@ -61,6 +64,25 @@ impl EiTouchscreen {
|
||||||
touchid,
|
touchid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_client_event(&self, touchid: u32, event: TouchChange) -> Result<(), EiTouchscreenError> {
|
||||||
|
match self.device.touch_changes.lock().entry(touchid) {
|
||||||
|
Entry::Occupied(mut o) => {
|
||||||
|
use TouchChange::*;
|
||||||
|
match (o.get(), event) {
|
||||||
|
(Motion(_, _), Motion(_, _)) | (Down(_, _), Down(_, _)) | (Up, Up) => {
|
||||||
|
o.insert(event);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
_ => Err(EiTouchscreenError::InvalidEventCombination),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Entry::Vacant(v) => {
|
||||||
|
v.insert(event);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EiTouchscreenRequestHandler for EiTouchscreen {
|
impl EiTouchscreenRequestHandler for EiTouchscreen {
|
||||||
|
|
@ -72,24 +94,15 @@ impl EiTouchscreenRequestHandler for EiTouchscreen {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn client_down(&self, req: ClientDown, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn client_down(&self, req: ClientDown, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
self.device
|
self.set_client_event(req.touchid, TouchChange::Down(req.x, req.y))
|
||||||
.touch_changes
|
|
||||||
.push((req.touchid, TouchChange::Down(req.x, req.y)));
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn client_motion(&self, req: ClientMotion, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn client_motion(&self, req: ClientMotion, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
self.device
|
self.set_client_event(req.touchid, TouchChange::Motion(req.x, req.y))
|
||||||
.touch_changes
|
|
||||||
.push((req.touchid, TouchChange::Motion(req.x, req.y)));
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn client_up(&self, req: ClientUp, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn client_up(&self, req: ClientUp, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
self.device
|
self.set_client_event(req.touchid, TouchChange::Up)
|
||||||
.touch_changes
|
|
||||||
.push((req.touchid, TouchChange::Up));
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,5 +117,7 @@ impl EiObject for EiTouchscreen {}
|
||||||
pub enum EiTouchscreenError {
|
pub enum EiTouchscreenError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
EiClientError(Box<EiClientError>),
|
EiClientError(Box<EiClientError>),
|
||||||
|
#[error("Touch frame contains an invalid combination of events")]
|
||||||
|
InvalidEventCombination,
|
||||||
}
|
}
|
||||||
efrom!(EiTouchscreenError, EiClientError);
|
efrom!(EiTouchscreenError, EiClientError);
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ impl<T> SyncQueue<T> {
|
||||||
unsafe { self.el.get().deref_mut().is_empty() }
|
unsafe { self.el.get().deref_mut().is_empty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[expect(dead_code)]
|
||||||
pub fn is_not_empty(&self) -> bool {
|
pub fn is_not_empty(&self) -> bool {
|
||||||
!self.is_empty()
|
!self.is_empty()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue