forked from NotAShelf/beer
wayland: one-finger touch drag scrolls the viewport
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I58396f87fbe47cb3a552bf53d45e7e836a6a6964
This commit is contained in:
parent
e172d4fbb3
commit
fb590c1645
2 changed files with 122 additions and 2 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue