Skip to content

Commit

Permalink
ei: make handling of touchscreen events stricter
Browse files Browse the repository at this point in the history
  • Loading branch information
mahkoh committed Nov 28, 2024
1 parent 558fe3d commit 5d3b8a9
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 16 deletions.
6 changes: 3 additions & 3 deletions src/ei/ei_ifs/ei_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use {
leaks::Tracker,
rect::Rect,
scale::Scale,
utils::syncqueue::SyncQueue,
utils::{copyhashmap::CopyHashMap, syncqueue::SyncQueue},
wire_ei::{
ei_device::{
ClientFrame, ClientStartEmulating, ClientStopEmulating, Destroyed, DeviceType,
Expand All @@ -37,7 +37,7 @@ pub struct EiDevice {
pub seat: Rc<EiSeat>,

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_v120: [Cell<Option<i32>>; 2],
pub scroll_stop: [Cell<Option<bool>>; 2],
Expand Down Expand Up @@ -219,7 +219,7 @@ impl EiDeviceRequestHandler for EiDevice {
}
}
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;
match change {
TouchChange::Down(x, y) => {
Expand Down
41 changes: 28 additions & 13 deletions src/ei/ei_ifs/ei_touchscreen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use {
},
fixed::Fixed,
leaks::Tracker,
utils::clonecell::UnsafeCellCloneSafe,
wire_ei::{
ei_touchscreen::{
ClientDown, ClientMotion, ClientUp, EiTouchscreenRequestHandler, Release,
Expand All @@ -15,7 +16,7 @@ use {
EiTouchscreenId,
},
},
std::rc::Rc,
std::{collections::hash_map::Entry, rc::Rc},
thiserror::Error,
};

Expand All @@ -34,6 +35,8 @@ pub enum TouchChange {
Up,
}

unsafe impl UnsafeCellCloneSafe for TouchChange {}

ei_device_interface!(EiTouchscreen, ei_touchscreen, touchscreen);

impl EiTouchscreen {
Expand Down Expand Up @@ -61,6 +64,25 @@ impl EiTouchscreen {
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 {
Expand All @@ -72,24 +94,15 @@ impl EiTouchscreenRequestHandler for EiTouchscreen {
}

fn client_down(&self, req: ClientDown, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.device
.touch_changes
.push((req.touchid, TouchChange::Down(req.x, req.y)));
Ok(())
self.set_client_event(req.touchid, TouchChange::Down(req.x, req.y))
}

fn client_motion(&self, req: ClientMotion, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.device
.touch_changes
.push((req.touchid, TouchChange::Motion(req.x, req.y)));
Ok(())
self.set_client_event(req.touchid, TouchChange::Motion(req.x, req.y))
}

fn client_up(&self, req: ClientUp, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.device
.touch_changes
.push((req.touchid, TouchChange::Up));
Ok(())
self.set_client_event(req.touchid, TouchChange::Up)
}
}

Expand All @@ -104,5 +117,7 @@ impl EiObject for EiTouchscreen {}
pub enum EiTouchscreenError {
#[error(transparent)]
EiClientError(Box<EiClientError>),
#[error("Touch frame contains an invalid combination of events")]
InvalidEventCombination,
}
efrom!(EiTouchscreenError, EiClientError);
1 change: 1 addition & 0 deletions src/utils/syncqueue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl<T> SyncQueue<T> {
unsafe { self.el.get().deref_mut().is_empty() }
}

#[expect(dead_code)]
pub fn is_not_empty(&self) -> bool {
!self.is_empty()
}
Expand Down

0 comments on commit 5d3b8a9

Please sign in to comment.