clone
ssh://git@git.notashelf.dev:33/notashelf/beer.gitCommit fb590c164503
tarballunverified2 files changed+122-2
@@ -141,6 +141,12 @@ impl SeatHandler for App { Err(err) => tracing::warn!("get pointer: {err}"), } }+ if capability == Capability::Touch && self.seats[i].touch.is_none() {+ match self.seat_state.get_touch(qh, &seat) {+ Ok(touch) => self.seats[i].touch = Some(touch),+ Err(err) => tracing::warn!("get touch: {err}"),+ }+ } } fn remove_capability(@@ -165,6 +171,12 @@ impl SeatHandler for App { pointer.release(); } }+ Capability::Touch => {+ if let Some(touch) = s.touch.take() {+ touch.release();+ }+ self.touch_scroll = None;+ } _ => {} } }@@ -437,6 +449,96 @@ impl PointerHandler for App { } } +// Touch drives one-finger drag-to-scroll of the scrollback viewport. Taps and+// multi-finger gestures are ignored; only the first touch point is tracked.+impl TouchHandler for App {+ fn down(+ &mut self,+ _: &Connection,+ _: &QueueHandle<Self>,+ _: &wl_touch::WlTouch,+ _serial: u32,+ _time: u32,+ _surface: wl_surface::WlSurface,+ id: i32,+ position: (f64, f64),+ ) {+ if self.touch_scroll.is_none() {+ self.touch_scroll = Some(TouchScroll {+ id,+ last_y: position.1,+ acc: 0.0,+ });+ }+ }++ fn up(+ &mut self,+ _: &Connection,+ _: &QueueHandle<Self>,+ _: &wl_touch::WlTouch,+ _serial: u32,+ _time: u32,+ id: i32,+ ) {+ if self.touch_scroll.as_ref().is_some_and(|t| t.id == id) {+ self.touch_scroll = None;+ }+ }++ fn motion(+ &mut self,+ _: &Connection,+ _: &QueueHandle<Self>,+ _: &wl_touch::WlTouch,+ _time: u32,+ id: i32,+ position: (f64, f64),+ ) {+ let cell_h = self.renderer.metrics().height as f64;+ let Some(touch) = self.touch_scroll.as_mut().filter(|t| t.id == id) else {+ return;+ };+ touch.acc += position.1 - touch.last_y;+ touch.last_y = position.1;+ // Dragging down (positive delta) reveals older lines, matching the+ // viewport's "positive scrolls back" convention.+ let lines = (touch.acc / cell_h) as isize;+ if lines != 0 {+ touch.acc -= lines as f64 * cell_h;+ if let Some(session) = self.session.as_mut() {+ session.term.scroll_view(lines);+ self.needs_draw = true;+ }+ }+ }++ fn shape(+ &mut self,+ _: &Connection,+ _: &QueueHandle<Self>,+ _: &wl_touch::WlTouch,+ _: i32,+ _: f64,+ _: f64,+ ) {+ }++ fn orientation(+ &mut self,+ _: &Connection,+ _: &QueueHandle<Self>,+ _: &wl_touch::WlTouch,+ _: i32,+ _: f64,+ ) {+ }++ fn cancel(&mut self, _: &Connection, _: &QueueHandle<Self>, _: &wl_touch::WlTouch) {+ self.touch_scroll = None;+ }+}+ impl OutputHandler for App { fn output_state(&mut self) -> &mut OutputState { &mut self.output_state@@ -757,6 +859,7 @@ delegate_shm!(App); delegate_seat!(App); delegate_keyboard!(App); delegate_pointer!(App);+delegate_touch!(App); delegate_xdg_shell!(App); delegate_xdg_window!(App); delegate_data_device!(App);@@ -46,7 +46,7 @@ use smithay_client_toolkit::{ delegate_activation, delegate_compositor, delegate_data_device, delegate_keyboard, delegate_output, delegate_pointer, delegate_primary_selection, delegate_registry, delegate_seat, delegate_shm,- delegate_xdg_shell, delegate_xdg_window,+ delegate_touch, delegate_xdg_shell, delegate_xdg_window, output::{OutputHandler, OutputState}, primary_selection::{ PrimarySelectionManagerState,@@ -62,6 +62,7 @@ use smithay_client_toolkit::{ BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, PointerEvent, PointerEventKind, PointerHandler, cursor_shape::CursorShapeManager, },+ touch::TouchHandler, }, shell::{ WaylandSurface,@@ -81,7 +82,7 @@ use wayland_client::{ protocol::{ wl_data_device::WlDataDevice, wl_data_device_manager::DndAction, wl_data_source::WlDataSource, wl_keyboard, wl_output, wl_pointer, wl_seat, wl_shm,- wl_surface,+ wl_surface, wl_touch, }, }; use wayland_protocols::wp::content_type::v1::client::{@@ -289,6 +290,7 @@ pub fn run(config: Config, config_path: Option<std::path::PathBuf>) -> anyhow::R url_input: String::new(), unicode_input: None, keys_down: std::collections::HashSet::new(),+ touch_scroll: None, focused: true, exit: false, exit_code: ExitCode::SUCCESS,@@ -394,6 +396,18 @@ struct SeatData { primary_device: Option<PrimarySelectionDevice>, /// text-input-v3 handle for IME preedit/commit, if the compositor offers it. text_input: Option<ZwpTextInputV3>,+ touch: Option<wl_touch::WlTouch>,+}++/// A single-finger touch drag in progress, used to scroll the viewport.+#[derive(Debug)]+struct TouchScroll {+ /// Touch point id we are tracking (the first finger down).+ id: i32,+ /// Surface-local y of the last motion, to take per-event deltas.+ last_y: f64,+ /// Sub-cell pixel remainder carried between motions.+ acc: f64, } /// Window + Wayland client state shared across all protocol handlers.@@ -514,6 +528,8 @@ struct App { /// Raw key codes currently held, to tell press from repeat for the kitty /// keyboard protocol's event-type reporting. keys_down: std::collections::HashSet<u32>,+ /// A single-finger touch drag in progress (scrolls the viewport).+ touch_scroll: Option<TouchScroll>, /// Whether the toplevel currently has keyboard focus (drives the cursor). focused: bool, exit: bool,@@ -1205,6 +1221,7 @@ impl App { data_device: None, primary_device: None, text_input: None,+ touch: None, }); self.seats.len() - 1 }