diff --git a/src/nodes/items/panel.rs b/src/nodes/items/panel.rs index b20f3eb..4c0908c 100644 --- a/src/nodes/items/panel.rs +++ b/src/nodes/items/panel.rs @@ -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); + + fn touch_down(&self, surface: &SurfaceID, id: u32, position: Vector2); + fn touch_move(&self, id: u32, position: Vector2); + fn touch_up(&self, id: u32); + fn reset_touches(&self); } pub fn panel_item_from_node(node: &Node) -> Option> { @@ -252,7 +261,10 @@ impl PanelItem { 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 PanelItem { 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 PanelItem { 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 PanelItem { let Ok(message) = serialize(sid) else {return}; let _ = node.send_remote_signal("grab_keyboard", message); } + + fn touch_down_flex(node: &Node, _calling_client: Arc, message: Message) -> Result<()> { + let Some(panel_item) = panel_item_from_node(node) else { return Ok(()) }; + + let (surface_id, id, position): (SurfaceID, u32, Vector2) = + 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, message: Message) -> Result<()> { + let Some(panel_item) = panel_item_from_node(node) else { return Ok(()) }; + + let (id, position): (u32, Vector2) = 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 PanelItemTrait for PanelItem { fn uid(&self) -> &str { @@ -490,6 +531,19 @@ impl Backend for PanelItem { fn keyboard_keys(&self, surface: &SurfaceID, keymap_id: &str, keys: Vec) { self.backend.keyboard_keys(surface, keymap_id, keys) } + + fn touch_down(&self, surface: &SurfaceID, id: u32, position: Vector2) { + self.backend.touch_down(surface, id, position) + } + fn touch_move(&self, id: u32, position: Vector2) { + 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 Drop for PanelItem { fn drop(&mut self) { diff --git a/src/wayland/seat.rs b/src/wayland/seat.rs index edc21dd..4bbf101 100644 --- a/src/wayland/seat.rs +++ b/src/wayland/seat.rs @@ -279,6 +279,7 @@ pub struct SeatData { pointer: OnceCell<(WlPointer, Mutex)>, keyboard: OnceCell<(WlKeyboard, Mutex)>, touch: OnceCell, + touches: Mutex>, } impl SeatData { pub fn new(dh: &DisplayHandle) -> Arc { @@ -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) { + 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) { + 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, 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) -> bool { diff --git a/src/wayland/xdg_shell.rs b/src/wayland/xdg_shell.rs index d97fe8a..ba0f5e2 100644 --- a/src/wayland/xdg_shell.rs +++ b/src/wayland/xdg_shell.rs @@ -1031,4 +1031,18 @@ impl Backend for XDGBackend { ); } } + + fn touch_down(&self, surface: &SurfaceID, id: u32, position: Vector2) { + 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) { + 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() + } }