2017-11-11 20:03:42 +11:00
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
2018-05-06 03:36:34 +10:00
|
|
|
use {TouchPhase, WindowEvent};
|
2017-11-11 20:03:42 +11:00
|
|
|
|
2018-05-06 03:36:34 +10:00
|
|
|
use super::{DeviceId, WindowId};
|
2017-11-11 20:03:42 +11:00
|
|
|
use super::event_loop::EventsLoopSink;
|
|
|
|
use super::window::WindowStore;
|
|
|
|
|
2018-05-06 03:36:34 +10:00
|
|
|
use sctk::reexports::client::{NewProxy, Proxy};
|
|
|
|
use sctk::reexports::client::protocol::wl_touch::{Event as TouchEvent, WlTouch};
|
2017-11-11 20:03:42 +11:00
|
|
|
|
|
|
|
struct TouchPoint {
|
|
|
|
wid: WindowId,
|
|
|
|
location: (f64, f64),
|
2018-05-06 03:36:34 +10:00
|
|
|
id: i32,
|
2017-11-11 20:03:42 +11:00
|
|
|
}
|
|
|
|
|
2018-05-06 03:36:34 +10:00
|
|
|
pub(crate) fn implement_touch(
|
|
|
|
touch: NewProxy<WlTouch>,
|
|
|
|
sink: Arc<Mutex<EventsLoopSink>>,
|
|
|
|
store: Arc<Mutex<WindowStore>>,
|
|
|
|
) -> Proxy<WlTouch> {
|
|
|
|
let mut pending_ids = Vec::new();
|
|
|
|
touch.implement(move |evt, _| {
|
|
|
|
let mut sink = sink.lock().unwrap();
|
|
|
|
let store = store.lock().unwrap();
|
|
|
|
match evt {
|
|
|
|
TouchEvent::Down {
|
|
|
|
surface, id, x, y, ..
|
|
|
|
} => {
|
|
|
|
let wid = store.find_wid(&surface);
|
|
|
|
if let Some(wid) = wid {
|
|
|
|
sink.send_event(
|
|
|
|
WindowEvent::Touch(::Touch {
|
|
|
|
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
|
|
|
phase: TouchPhase::Started,
|
2018-06-15 09:42:18 +10:00
|
|
|
location: (x, y).into(),
|
2018-05-06 03:36:34 +10:00
|
|
|
id: id as u64,
|
|
|
|
}),
|
|
|
|
wid,
|
|
|
|
);
|
|
|
|
pending_ids.push(TouchPoint {
|
|
|
|
wid: wid,
|
2017-11-11 20:03:42 +11:00
|
|
|
location: (x, y),
|
2018-05-06 03:36:34 +10:00
|
|
|
id: id,
|
|
|
|
});
|
|
|
|
}
|
2017-11-11 20:03:42 +11:00
|
|
|
}
|
2018-05-06 03:36:34 +10:00
|
|
|
TouchEvent::Up { id, .. } => {
|
|
|
|
let idx = pending_ids.iter().position(|p| p.id == id);
|
|
|
|
if let Some(idx) = idx {
|
|
|
|
let pt = pending_ids.remove(idx);
|
|
|
|
sink.send_event(
|
|
|
|
WindowEvent::Touch(::Touch {
|
|
|
|
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
|
|
|
phase: TouchPhase::Ended,
|
2018-06-15 09:42:18 +10:00
|
|
|
location: pt.location.into(),
|
2018-05-06 03:36:34 +10:00
|
|
|
id: id as u64,
|
|
|
|
}),
|
|
|
|
pt.wid,
|
|
|
|
);
|
|
|
|
}
|
2017-11-11 20:03:42 +11:00
|
|
|
}
|
2018-05-06 03:36:34 +10:00
|
|
|
TouchEvent::Motion { id, x, y, .. } => {
|
|
|
|
let pt = pending_ids.iter_mut().find(|p| p.id == id);
|
|
|
|
if let Some(pt) = pt {
|
|
|
|
pt.location = (x, y);
|
|
|
|
sink.send_event(
|
|
|
|
WindowEvent::Touch(::Touch {
|
|
|
|
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
|
|
|
phase: TouchPhase::Moved,
|
2018-06-15 09:42:18 +10:00
|
|
|
location: (x, y).into(),
|
2018-05-06 03:36:34 +10:00
|
|
|
id: id as u64,
|
|
|
|
}),
|
|
|
|
pt.wid,
|
|
|
|
);
|
|
|
|
}
|
2017-11-11 20:03:42 +11:00
|
|
|
}
|
2018-05-06 03:36:34 +10:00
|
|
|
TouchEvent::Frame => (),
|
|
|
|
TouchEvent::Cancel => for pt in pending_ids.drain(..) {
|
|
|
|
sink.send_event(
|
|
|
|
WindowEvent::Touch(::Touch {
|
2017-11-11 20:03:42 +11:00
|
|
|
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
|
|
|
phase: TouchPhase::Cancelled,
|
2018-06-15 09:42:18 +10:00
|
|
|
location: pt.location.into(),
|
2018-05-06 03:36:34 +10:00
|
|
|
id: pt.id as u64,
|
2017-11-11 20:03:42 +11:00
|
|
|
}),
|
|
|
|
pt.wid,
|
|
|
|
);
|
2018-05-06 03:36:34 +10:00
|
|
|
},
|
2017-11-11 20:03:42 +11:00
|
|
|
}
|
2018-05-06 03:36:34 +10:00
|
|
|
})
|
|
|
|
}
|