feat(wayland): touch support

This commit is contained in:
Nova
2023-09-24 11:44:26 -04:00
parent bf248e192f
commit 4da7ed1ccf
3 changed files with 103 additions and 3 deletions

View File

@@ -39,6 +39,10 @@ lazy_static! {
"pointer_scroll",
"keyboard_keymap",
"keyboard_key",
"touch_down",
"touch_move",
"touch_up",
"reset_touches",
],
aliased_local_methods: vec![],
aliased_remote_signals: vec![
@@ -191,6 +195,11 @@ pub trait Backend: Send + Sync + 'static {
);
fn keyboard_keys(&self, surface: &SurfaceID, keymap_id: &str, keys: Vec<i32>);
fn touch_down(&self, surface: &SurfaceID, id: u32, position: Vector2<f32>);
fn touch_move(&self, id: u32, position: Vector2<f32>);
fn touch_up(&self, id: u32);
fn reset_touches(&self);
}
pub fn panel_item_from_node(node: &Node) -> Option<Arc<dyn PanelItemTrait>> {
@@ -252,7 +261,10 @@ impl<B: Backend + ?Sized> PanelItem<B> {
node.add_local_signal("apply_surface_material", Self::apply_surface_material_flex);
node.add_local_signal("close_toplevel", Self::close_toplevel_flex);
node.add_local_signal("auto_size_toplevel", Self::auto_size_toplevel_flex);
node.add_local_signal("set_toplevel_size_changed", Self::set_toplevel_size_changed);
node.add_local_signal(
"set_toplevel_size_changed",
Self::set_toplevel_size_changed_flex,
);
node.add_local_signal("pointer_motion", Self::pointer_motion_flex);
node.add_local_signal("pointer_button", Self::pointer_button_flex);
@@ -260,6 +272,11 @@ impl<B: Backend + ?Sized> PanelItem<B> {
node.add_local_signal("keyboard_key", Self::keyboard_keys_flex);
node.add_local_signal("touch_down", Self::touch_down_flex);
node.add_local_signal("touch_move", Self::touch_move_flex);
node.add_local_signal("touch_up", Self::touch_up_flex);
node.add_local_signal("reset_touches", Self::reset_touches_flex);
panel_item
}
pub fn drop_toplevel(&self) {
@@ -369,7 +386,7 @@ impl<B: Backend + ?Sized> PanelItem<B> {
flex_no_args!(close_toplevel_flex, close_toplevel);
flex_no_args!(auto_size_toplevel_flex, auto_size_toplevel);
flex_deserialize!(set_toplevel_size_changed, set_toplevel_size);
flex_deserialize!(set_toplevel_size_changed_flex, set_toplevel_size);
fn pointer_motion_flex(
node: &Node,
@@ -439,6 +456,30 @@ impl<B: Backend + ?Sized> PanelItem<B> {
let Ok(message) = serialize(sid) else {return};
let _ = node.send_remote_signal("grab_keyboard", message);
}
fn touch_down_flex(node: &Node, _calling_client: Arc<Client>, message: Message) -> Result<()> {
let Some(panel_item) = panel_item_from_node(node) else { return Ok(()) };
let (surface_id, id, position): (SurfaceID, u32, Vector2<f32>) =
deserialize(message.as_ref())?;
debug!(?surface_id, id, ?position, "Touch down");
panel_item.touch_down(&surface_id, id, position);
Ok(())
}
fn touch_move_flex(node: &Node, _calling_client: Arc<Client>, message: Message) -> Result<()> {
let Some(panel_item) = panel_item_from_node(node) else { return Ok(()) };
let (id, position): (u32, Vector2<f32>) = deserialize(message.as_ref())?;
debug!(?position, "Touch move");
panel_item.touch_move(id, position);
Ok(())
}
flex_deserialize!(touch_up_flex, touch_up);
flex_no_args!(reset_touches_flex, reset_touches);
}
impl<B: Backend + ?Sized> PanelItemTrait for PanelItem<B> {
fn uid(&self) -> &str {
@@ -490,6 +531,19 @@ impl<B: Backend + ?Sized> Backend for PanelItem<B> {
fn keyboard_keys(&self, surface: &SurfaceID, keymap_id: &str, keys: Vec<i32>) {
self.backend.keyboard_keys(surface, keymap_id, keys)
}
fn touch_down(&self, surface: &SurfaceID, id: u32, position: Vector2<f32>) {
self.backend.touch_down(surface, id, position)
}
fn touch_move(&self, id: u32, position: Vector2<f32>) {
self.backend.touch_move(id, position)
}
fn touch_up(&self, id: u32) {
self.backend.touch_up(id)
}
fn reset_touches(&self) {
self.backend.reset_touches()
}
}
impl<B: Backend + ?Sized> Drop for PanelItem<B> {
fn drop(&mut self) {

View File

@@ -279,6 +279,7 @@ pub struct SeatData {
pointer: OnceCell<(WlPointer, Mutex<ObjectId>)>,
keyboard: OnceCell<(WlKeyboard, Mutex<ObjectId>)>,
touch: OnceCell<WlTouch>,
touches: Mutex<FxHashMap<ObjectId, u32>>,
}
impl SeatData {
pub fn new(dh: &DisplayHandle) -> Arc<Self> {
@@ -289,6 +290,7 @@ impl SeatData {
pointer: OnceCell::new(),
keyboard: OnceCell::new(),
touch: OnceCell::new(),
touches: Mutex::new(FxHashMap::default()),
});
let _ = seat_data
@@ -418,6 +420,36 @@ impl SeatData {
*keyboard_focus = ObjectId::null();
}
}
self.touches.lock().remove(&surface.id());
}
pub fn touch_down(&self, surface: &WlSurface, id: u32, position: Vector2<f32>) {
let Some(touch) = self.touch.get() else {return};
touch.down(
SERIAL_COUNTER.inc(),
0,
surface,
id as i32,
position.x as f64,
position.y as f64,
);
self.touches.lock().insert(surface.id(), id);
}
pub fn touch_move(&self, id: u32, position: Vector2<f32>) {
let Some(touch) = self.touch.get() else {return};
touch.motion(0, id as i32, position.x as f64, position.y as f64);
}
pub fn touch_up(&self, id: u32) {
let Some(touch) = self.touch.get() else {return};
touch.up(SERIAL_COUNTER.inc(), 0, id as i32);
let mut touches = self.touches.lock();
touches.retain(|_, tid| *tid != id);
}
pub fn reset_touches(&self) {
let Some(touch) = self.touch.get() else {return};
for (_, touch_id) in self.touches.lock().drain() {
touch.up(SERIAL_COUNTER.inc(), 0, touch_id as i32);
}
}
}
@@ -451,7 +483,7 @@ impl GlobalDispatch<WlSeat, Arc<SeatData>, WaylandState> for WaylandState {
resource.name(nanoid!());
}
resource.capabilities(Capability::Pointer | Capability::Keyboard);
resource.capabilities(Capability::Pointer | Capability::Keyboard | Capability::Touch);
}
fn can_view(client: Client, data: &Arc<SeatData>) -> bool {

View File

@@ -1031,4 +1031,18 @@ impl Backend for XDGBackend {
);
}
}
fn touch_down(&self, surface: &SurfaceID, id: u32, position: Vector2<f32>) {
let Some(surface) = self.wl_surface_from_id(surface) else {return};
self.seat.touch_down(&surface, id, position)
}
fn touch_move(&self, id: u32, position: Vector2<f32>) {
self.seat.touch_move(id, position)
}
fn touch_up(&self, id: u32) {
self.seat.touch_up(id)
}
fn reset_touches(&self) {
self.seat.reset_touches()
}
}