Changed the driver to have a lower sensitivity and to automatically stop a mt_scroll_event upon receiving no inputs for 100 ms. It restarts upon receiving new input afterwards.
Changes are implemented in fake_input.rs for the sensitivity change; and scroll_mt.rs for the debouncing behaviour.
This commit is contained in:
@@ -2,14 +2,55 @@ use crate::controller::{ControlMode, ControlModeMeta};
|
|||||||
use crate::dial_device::DialHaptics;
|
use crate::dial_device::DialHaptics;
|
||||||
use crate::error::{Error, Result};
|
use crate::error::{Error, Result};
|
||||||
use crate::fake_input;
|
use crate::fake_input;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::thread::{self, JoinHandle};
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
pub struct ScrollMT {
|
pub struct ScrollMT {
|
||||||
acc_delta: i32,
|
acc_delta: i32,
|
||||||
|
last_dial_time: Arc<Mutex<Option<Instant>>>,
|
||||||
|
stop_thread: Arc<Mutex<bool>>,
|
||||||
|
is_scrolling: Arc<Mutex<bool>>,
|
||||||
|
timer_thread: Option<JoinHandle<()>>, // Add this to store the thread handle
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScrollMT {
|
impl ScrollMT {
|
||||||
pub fn new() -> ScrollMT {
|
pub fn new() -> ScrollMT {
|
||||||
ScrollMT { acc_delta: 0 }
|
ScrollMT {
|
||||||
|
acc_delta: 0,
|
||||||
|
last_dial_time: Arc::new(Mutex::new(None)),
|
||||||
|
stop_thread: Arc::new(Mutex::new(false)),
|
||||||
|
is_scrolling: Arc::new(Mutex::new(false)),
|
||||||
|
timer_thread: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_timer_thread(&mut self) {
|
||||||
|
// Reset the stop signal
|
||||||
|
*self.stop_thread.lock().unwrap() = false;
|
||||||
|
|
||||||
|
let last_dial_time = Arc::clone(&self.last_dial_time);
|
||||||
|
let stop_thread = Arc::clone(&self.stop_thread);
|
||||||
|
let is_scrolling = Arc::clone(&self.is_scrolling);
|
||||||
|
|
||||||
|
self.timer_thread = Some(thread::spawn(move || {
|
||||||
|
while !(*stop_thread.lock().unwrap()) {
|
||||||
|
thread::sleep(Duration::from_millis(100));
|
||||||
|
|
||||||
|
let mut last_time = last_dial_time.lock().unwrap();
|
||||||
|
let mut scrolling = is_scrolling.lock().unwrap();
|
||||||
|
|
||||||
|
if let Some(last) = *last_time {
|
||||||
|
if last.elapsed() > Duration::from_millis(100) && *scrolling {
|
||||||
|
if let Err(e) = fake_input::scroll_mt_end() {
|
||||||
|
eprintln!("Error ending scroll: {:?}", e);
|
||||||
|
}
|
||||||
|
*last_time = None;
|
||||||
|
*scrolling = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,37 +66,60 @@ impl ControlMode for ScrollMT {
|
|||||||
|
|
||||||
fn on_start(&mut self, _haptics: &DialHaptics) -> Result<()> {
|
fn on_start(&mut self, _haptics: &DialHaptics) -> Result<()> {
|
||||||
self.acc_delta = 0;
|
self.acc_delta = 0;
|
||||||
|
*self.last_dial_time.lock().unwrap() = None;
|
||||||
|
*self.is_scrolling.lock().unwrap() = true;
|
||||||
|
|
||||||
// HACK: for some reason, if scroll mode is the startup mode, then just calling
|
fake_input::scroll_mt_start().map_err(Error::Evdev)?;
|
||||||
// `scroll_mt_start` doesn't work as expected.
|
|
||||||
std::thread::spawn(move || {
|
// Start a new timer thread
|
||||||
fake_input::scroll_mt_end().unwrap();
|
self.start_timer_thread();
|
||||||
std::thread::sleep(std::time::Duration::from_millis(200));
|
|
||||||
fake_input::scroll_mt_start().unwrap();
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_end(&mut self, _haptics: &DialHaptics) -> Result<()> {
|
fn on_end(&mut self, _haptics: &DialHaptics) -> Result<()> {
|
||||||
|
// Signal the timer thread to stop
|
||||||
|
*self.stop_thread.lock().unwrap() = true;
|
||||||
|
|
||||||
|
// Wait for the timer thread to finish
|
||||||
|
if let Some(thread) = self.timer_thread.take() {
|
||||||
|
let _ = thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
// End multitouch scrolling
|
||||||
fake_input::scroll_mt_end().map_err(Error::Evdev)?;
|
fake_input::scroll_mt_end().map_err(Error::Evdev)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: the button will reset the scroll event, which sometimes helps
|
|
||||||
|
|
||||||
fn on_btn_press(&mut self, _: &DialHaptics) -> Result<()> {
|
fn on_btn_press(&mut self, _: &DialHaptics) -> Result<()> {
|
||||||
|
// End multitouch scrolling on button press
|
||||||
fake_input::scroll_mt_end().map_err(Error::Evdev)?;
|
fake_input::scroll_mt_end().map_err(Error::Evdev)?;
|
||||||
|
*self.is_scrolling.lock().unwrap() = false;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_btn_release(&mut self, _haptics: &DialHaptics) -> Result<()> {
|
fn on_btn_release(&mut self, _haptics: &DialHaptics) -> Result<()> {
|
||||||
|
// Restart multitouch scrolling on button release
|
||||||
fake_input::scroll_mt_start().map_err(Error::Evdev)?;
|
fake_input::scroll_mt_start().map_err(Error::Evdev)?;
|
||||||
|
*self.is_scrolling.lock().unwrap() = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_dial(&mut self, _: &DialHaptics, delta: i32) -> Result<()> {
|
fn on_dial(&mut self, _: &DialHaptics, delta: i32) -> Result<()> {
|
||||||
self.acc_delta += delta;
|
self.acc_delta += delta;
|
||||||
|
|
||||||
|
// Update the last dial time
|
||||||
|
let mut last_dial_time = self.last_dial_time.lock().unwrap();
|
||||||
|
*last_dial_time = Some(Instant::now());
|
||||||
|
|
||||||
|
// Restart multitouch scrolling if it was inactive
|
||||||
|
let mut scrolling = self.is_scrolling.lock().unwrap();
|
||||||
|
if !*scrolling {
|
||||||
|
fake_input::scroll_mt_start().map_err(Error::Evdev)?;
|
||||||
|
*scrolling = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform a multitouch scroll step
|
||||||
fake_input::scroll_mt_step(self.acc_delta).map_err(Error::Evdev)?;
|
fake_input::scroll_mt_step(self.acc_delta).map_err(Error::Evdev)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use parking_lot::ReentrantMutex;
|
|||||||
// this should be a fairly high number, as the axis is from 0..(MT_BASELINE*2)
|
// this should be a fairly high number, as the axis is from 0..(MT_BASELINE*2)
|
||||||
const MT_BASELINE: i32 = std::i32::MAX / 8;
|
const MT_BASELINE: i32 = std::i32::MAX / 8;
|
||||||
// higher = slower scrolling
|
// higher = slower scrolling
|
||||||
const MT_SENSITIVITY: i32 = 48;
|
const MT_SENSITIVITY: i32 = 32;
|
||||||
|
|
||||||
pub struct FakeInputs {
|
pub struct FakeInputs {
|
||||||
keyboard: ReentrantMutex<UInputDevice>,
|
keyboard: ReentrantMutex<UInputDevice>,
|
||||||
|
|||||||
Reference in New Issue
Block a user