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::error::{Error, Result};
|
||||
use crate::fake_input;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread::{self, JoinHandle};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub struct ScrollMT {
|
||||
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 {
|
||||
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<()> {
|
||||
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
|
||||
// `scroll_mt_start` doesn't work as expected.
|
||||
std::thread::spawn(move || {
|
||||
fake_input::scroll_mt_end().unwrap();
|
||||
std::thread::sleep(std::time::Duration::from_millis(200));
|
||||
fake_input::scroll_mt_start().unwrap();
|
||||
});
|
||||
fake_input::scroll_mt_start().map_err(Error::Evdev)?;
|
||||
|
||||
// Start a new timer thread
|
||||
self.start_timer_thread();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// HACK: the button will reset the scroll event, which sometimes helps
|
||||
|
||||
fn on_btn_press(&mut self, _: &DialHaptics) -> Result<()> {
|
||||
// End multitouch scrolling on button press
|
||||
fake_input::scroll_mt_end().map_err(Error::Evdev)?;
|
||||
*self.is_scrolling.lock().unwrap() = false;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_btn_release(&mut self, _haptics: &DialHaptics) -> Result<()> {
|
||||
// Restart multitouch scrolling on button release
|
||||
fake_input::scroll_mt_start().map_err(Error::Evdev)?;
|
||||
*self.is_scrolling.lock().unwrap() = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_dial(&mut self, _: &DialHaptics, delta: i32) -> Result<()> {
|
||||
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)?;
|
||||
|
||||
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)
|
||||
const MT_BASELINE: i32 = std::i32::MAX / 8;
|
||||
// higher = slower scrolling
|
||||
const MT_SENSITIVITY: i32 = 48;
|
||||
const MT_SENSITIVITY: i32 = 32;
|
||||
|
||||
pub struct FakeInputs {
|
||||
keyboard: ReentrantMutex<UInputDevice>,
|
||||
|
||||
Reference in New Issue
Block a user