Merge pull request #325 from mahkoh/jorth/ei-cancel
ei: implement ei_touchscreen v2
This commit is contained in:
commit
a218a57e80
7 changed files with 74 additions and 20 deletions
|
|
@ -3,6 +3,7 @@
|
|||
- Various bugfixes.
|
||||
- Add support fo ext-data-control-v1.
|
||||
- Implement wl-fixes.
|
||||
- Implement ei_touchscreen v2.
|
||||
|
||||
# 1.7.0 (2024-10-25)
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -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],
|
||||
|
|
@ -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) => {
|
||||
|
|
@ -233,6 +233,7 @@ impl EiDeviceRequestHandler for EiDevice {
|
|||
seat.touch_motion_at(time, id, x, y);
|
||||
}
|
||||
TouchChange::Up => seat.touch_up(time, id),
|
||||
TouchChange::Cancel => seat.touch_cancel(time, id),
|
||||
}
|
||||
}
|
||||
seat.touch_frame(time);
|
||||
|
|
|
|||
|
|
@ -197,6 +197,19 @@ impl EiSeat {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn handle_touch_cancel(&self, id: u32) {
|
||||
if self.is_sender() {
|
||||
return;
|
||||
}
|
||||
if let Some(b) = self.touchscreen.get() {
|
||||
if self.client.versions.ei_touchscreen() >= EiVersion(2) {
|
||||
b.send_cancel(id);
|
||||
} else {
|
||||
b.send_up(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_touch_frame(&self, time_usec: u64) {
|
||||
if self.is_sender() {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -7,15 +7,16 @@ use {
|
|||
},
|
||||
fixed::Fixed,
|
||||
leaks::Tracker,
|
||||
utils::clonecell::UnsafeCellCloneSafe,
|
||||
wire_ei::{
|
||||
ei_touchscreen::{
|
||||
ClientDown, ClientMotion, ClientUp, EiTouchscreenRequestHandler, Release,
|
||||
ServerDown, ServerMotion, ServerUp,
|
||||
ClientCancel, ClientDown, ClientMotion, ClientUp, EiTouchscreenRequestHandler,
|
||||
Release, ServerCancel, ServerDown, ServerMotion, ServerUp,
|
||||
},
|
||||
EiTouchscreenId,
|
||||
},
|
||||
},
|
||||
std::rc::Rc,
|
||||
std::{collections::hash_map::Entry, rc::Rc},
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
|
|
@ -32,8 +33,11 @@ pub enum TouchChange {
|
|||
Down(f32, f32),
|
||||
Motion(f32, f32),
|
||||
Up,
|
||||
Cancel,
|
||||
}
|
||||
|
||||
unsafe impl UnsafeCellCloneSafe for TouchChange {}
|
||||
|
||||
ei_device_interface!(EiTouchscreen, ei_touchscreen, touchscreen);
|
||||
|
||||
impl EiTouchscreen {
|
||||
|
|
@ -61,6 +65,35 @@ impl EiTouchscreen {
|
|||
touchid,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn send_cancel(&self, touchid: u32) {
|
||||
self.client.event(ServerCancel {
|
||||
self_id: self.id,
|
||||
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)
|
||||
| (Cancel, Cancel) => {
|
||||
o.insert(event);
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(EiTouchscreenError::InvalidEventCombination),
|
||||
}
|
||||
}
|
||||
Entry::Vacant(v) => {
|
||||
v.insert(event);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EiTouchscreenRequestHandler for EiTouchscreen {
|
||||
|
|
@ -72,24 +105,19 @@ 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)
|
||||
}
|
||||
|
||||
fn client_cancel(&self, req: ClientCancel, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.set_client_event(req.touchid, TouchChange::Cancel)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,5 +132,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);
|
||||
|
|
|
|||
|
|
@ -761,9 +761,9 @@ impl WlSeatGlobal {
|
|||
self.touch_owner.motion(self, time_usec, id, x, y);
|
||||
}
|
||||
|
||||
fn touch_cancel(self: &Rc<Self>, time_usec: u64, id: i32) {
|
||||
pub fn touch_cancel(self: &Rc<Self>, time_usec: u64, id: i32) {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_touch_up(id as _);
|
||||
ei_seat.handle_touch_cancel(id as _);
|
||||
});
|
||||
self.state.for_each_seat_tester(|t| {
|
||||
t.send_touch_cancel(self.id, time_usec, id);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ request client_up (sender) {
|
|||
touchid: u32,
|
||||
}
|
||||
|
||||
request client_cancel (sender, since = 2) {
|
||||
touchid: u32,
|
||||
}
|
||||
|
||||
event destroyed {
|
||||
serial: u32,
|
||||
}
|
||||
|
|
@ -36,3 +40,7 @@ event server_motion (receiver) {
|
|||
event server_up (receiver) {
|
||||
touchid: u32,
|
||||
}
|
||||
|
||||
event server_cancel (receiver, since = 2) {
|
||||
touchid: u32,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue