feat: forward touch input to clients

This commit is contained in:
Samuel Onoja committed 2026-09-25 02:21:41 +01:00
1 parent 84ffa1f41c
commit dbabe95a5e
2 files changed
+74 -10

No files matched your search

+72 -9
View File
@@ -2,10 +2,12 @@ use smithay::{
backend::input::{ backend::input::{
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent, AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent,
KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionEvent, KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionEvent,
TouchEvent,
}, },
input::{ input::{
keyboard::{FilterResult, keysyms}, keyboard::{FilterResult, keysyms},
pointer::{AxisFrame, ButtonEvent, MotionEvent, PointerHandle, RelativeMotionEvent}, pointer::{AxisFrame, ButtonEvent, MotionEvent, PointerHandle, RelativeMotionEvent},
touch::{DownEvent, MotionEvent as TouchMotionEvent, UpEvent},
}, },
reexports::wayland_server::protocol::wl_surface::WlSurface, reexports::wayland_server::protocol::wl_surface::WlSurface,
utils::{Logical, Point, SERIAL_COUNTER, Serial}, utils::{Logical, Point, SERIAL_COUNTER, Serial},
@@ -209,13 +211,9 @@ impl Ferese {
); );
} }
InputEvent::PointerMotionAbsolute { event, .. } => { InputEvent::PointerMotionAbsolute { event, .. } => {
let Some(output) = self.space.outputs().next() else { let Some(position) = self.absolute_event_position(&event) else {
return; return;
}; };
let Some(geometry) = self.space.output_geometry(output) else {
return;
};
let position = event.position_transformed(geometry.size) + geometry.loc.to_f64();
let pointer = self.seat.get_pointer().expect("seat has a pointer"); let pointer = self.seat.get_pointer().expect("seat has a pointer");
let position = self.constrain_pointer_position(&pointer, position); let position = self.constrain_pointer_position(&pointer, position);
@@ -274,7 +272,7 @@ impl Ferese {
let serial = SERIAL_COUNTER.next_serial(); let serial = SERIAL_COUNTER.next_serial();
if event.state() == ButtonState::Pressed && !pointer.is_grabbed() { if event.state() == ButtonState::Pressed && !pointer.is_grabbed() {
self.focus_window_under_pointer(serial); self.focus_window_at(pointer.current_location(), serial);
} }
pointer.button( pointer.button(
@@ -325,14 +323,79 @@ impl Ferese {
pointer.axis(self, frame); pointer.axis(self, frame);
pointer.frame(self); pointer.frame(self);
} }
InputEvent::TouchDown { event, .. } => {
let Some(location) = self.absolute_event_position(&event) else {
return;
};
self.focus_window_at(location, SERIAL_COUNTER.next_serial());
let touch = self.seat.get_touch().expect("seat has touch capability");
let serial = SERIAL_COUNTER.next_serial();
touch.down(
self,
self.surface_under(location),
&DownEvent {
slot: event.slot(),
location,
serial,
time: event.time() as u32,
},
);
}
InputEvent::TouchMotion { event, .. } => {
let Some(location) = self.absolute_event_position(&event) else {
return;
};
let touch = self.seat.get_touch().expect("seat has touch capability");
touch.motion(
self,
self.surface_under(location),
&TouchMotionEvent {
slot: event.slot(),
location,
time: event.time() as u32,
},
);
}
InputEvent::TouchUp { event, .. } => {
let touch = self.seat.get_touch().expect("seat has touch capability");
touch.up(
self,
&UpEvent {
slot: event.slot(),
serial: SERIAL_COUNTER.next_serial(),
time: event.time() as u32,
},
);
}
InputEvent::TouchCancel { .. } => {
let touch = self.seat.get_touch().expect("seat has touch capability");
touch.cancel(self);
}
InputEvent::TouchFrame { .. } => {
let touch = self.seat.get_touch().expect("seat has touch capability");
touch.frame(self);
}
_ => {} _ => {}
} }
} }
fn focus_window_under_pointer(&mut self, serial: Serial) { fn absolute_event_position<I, E>(&self, event: &E) -> Option<Point<f64, Logical>>
let pointer = self.seat.get_pointer().expect("seat has a pointer"); where
I: InputBackend,
E: AbsolutePositionEvent<I>,
{
let output = self
.focused_output()
.or_else(|| self.space.outputs().next())?;
let geometry = self.space.output_geometry(output)?;
Some(event.position_transformed(geometry.size) + geometry.loc.to_f64())
}
fn focus_window_at(&mut self, position: Point<f64, Logical>, serial: Serial) {
let keyboard = self.seat.get_keyboard().expect("seat has a keyboard"); let keyboard = self.seat.get_keyboard().expect("seat has a keyboard");
let position = pointer.current_location();
self.focus_output_at(position); self.focus_output_at(position);
if let Some((layer, _, _)) = self.layer_under(position) { if let Some((layer, _, _)) = self.layer_under(position) {
+2 -1
View File
@@ -229,7 +229,7 @@ impl Ferese {
} }
} }
fn focused_output(&self) -> Option<&Output> { pub(crate) fn focused_output(&self) -> Option<&Output> {
let focused = self.output_workspaces.focused_output()?; let focused = self.output_workspaces.focused_output()?;
self.output_ids self.output_ids
.iter() .iter()
@@ -325,6 +325,7 @@ impl Ferese {
let mut seat = seat_state.new_wl_seat(&display_handle, "ferese-winit"); let mut seat = seat_state.new_wl_seat(&display_handle, "ferese-winit");
seat.add_keyboard(Default::default(), 200, 25)?; seat.add_keyboard(Default::default(), 200, 25)?;
seat.add_pointer(); seat.add_pointer();
seat.add_touch();
let socket_name = Self::init_wayland_listener(display, event_loop)?; let socket_name = Self::init_wayland_listener(display, event_loop)?;
let start_time = Instant::now(); let start_time = Instant::now();