experimental multitouch based smooth scrolling
high-resolution mouse wheels aren't supported in userland yet, so why
don't we fake a high resolution touchpad instead 😄
it's somewhat working, though it seems to crash on startup when
installed (among other weird bugs).
This commit is contained in:
79
Cargo.lock
generated
79
Cargo.lock
generated
@@ -71,6 +71,12 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.19"
|
||||
@@ -84,6 +90,15 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
@@ -97,7 +112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"cfg-if 0.1.10",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
@@ -169,7 +184,7 @@ version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
@@ -185,6 +200,15 @@ dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb1fc4429a33e1f80d41dc9fea4d108a88bec1de8053878898ae448a0b52f613"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@@ -206,13 +230,22 @@ dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -295,6 +328,32 @@ dependencies = [
|
||||
"objc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cloudabi",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.19"
|
||||
@@ -336,6 +395,12 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.1.16"
|
||||
@@ -356,6 +421,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.8.0"
|
||||
@@ -379,7 +450,9 @@ dependencies = [
|
||||
"directories",
|
||||
"evdev-rs",
|
||||
"hidapi",
|
||||
"lazy_static",
|
||||
"notify-rust",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
|
||||
@@ -9,5 +9,7 @@ directories = "3.0"
|
||||
# master includes a PR that implements `Send` for `Device` and `UInputDevice`
|
||||
evdev-rs = { git = "https://github.com/ndesh26/evdev-rs.git", rev = "8e995b8bf" }
|
||||
hidapi = { version = "1.2.3", default-features = false, features = ["linux-shared-hidraw"] }
|
||||
lazy_static = "1.4"
|
||||
notify-rust = "4"
|
||||
parking_lot = "0.11.0"
|
||||
signal-hook = "0.1.16"
|
||||
|
||||
4559
notes/touchpad_evtest.txt
Normal file
4559
notes/touchpad_evtest.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@ mod media;
|
||||
mod null;
|
||||
mod paddle;
|
||||
mod scroll;
|
||||
mod scroll_mt;
|
||||
mod volume;
|
||||
mod zoom;
|
||||
|
||||
@@ -9,5 +10,6 @@ pub use self::media::*;
|
||||
pub use self::null::*;
|
||||
pub use self::paddle::*;
|
||||
pub use self::scroll::*;
|
||||
pub use self::scroll_mt::*;
|
||||
pub use self::volume::*;
|
||||
pub use self::zoom::*;
|
||||
|
||||
61
src/controller/controls/scroll_mt.rs
Normal file
61
src/controller/controls/scroll_mt.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use crate::controller::{ControlMode, ControlModeMeta};
|
||||
use crate::dial_device::DialHaptics;
|
||||
use crate::fake_input::FakeInput;
|
||||
use crate::DynResult;
|
||||
|
||||
pub struct ScrollMT {
|
||||
acc_delta: i32,
|
||||
|
||||
fake_input: FakeInput,
|
||||
}
|
||||
|
||||
impl ScrollMT {
|
||||
pub fn new() -> ScrollMT {
|
||||
ScrollMT {
|
||||
acc_delta: 0,
|
||||
fake_input: FakeInput::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ControlMode for ScrollMT {
|
||||
fn meta(&self) -> ControlModeMeta {
|
||||
ControlModeMeta {
|
||||
name: "Scroll",
|
||||
icon: "input-mouse",
|
||||
}
|
||||
}
|
||||
|
||||
fn on_start(&mut self, haptics: &DialHaptics) -> DynResult<()> {
|
||||
haptics.set_mode(false, Some(3600))?;
|
||||
self.acc_delta = 0;
|
||||
|
||||
self.fake_input.scroll_mt_start()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_end(&mut self, _haptics: &DialHaptics) -> DynResult<()> {
|
||||
self.fake_input.scroll_mt_end()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// HACK: the button will reset the scroll event, which sometimes helps
|
||||
|
||||
fn on_btn_press(&mut self, _: &DialHaptics) -> DynResult<()> {
|
||||
self.fake_input.scroll_mt_end()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_btn_release(&mut self, _haptics: &DialHaptics) -> DynResult<()> {
|
||||
self.fake_input.scroll_mt_start()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_dial(&mut self, _: &DialHaptics, delta: i32) -> DynResult<()> {
|
||||
self.acc_delta += delta;
|
||||
self.fake_input.scroll_mt_step(self.acc_delta)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,13 @@ use std::io;
|
||||
|
||||
use evdev_rs::enums::*;
|
||||
use evdev_rs::{Device, InputEvent, TimeVal, UInputDevice};
|
||||
use parking_lot::ReentrantMutex;
|
||||
|
||||
static mut FAKE_INPUT: Option<UInputDevice> = None;
|
||||
fn get_fake_input() -> io::Result<&'static UInputDevice> {
|
||||
if unsafe { FAKE_INPUT.is_none() } {
|
||||
lazy_static::lazy_static! {
|
||||
static ref FAKE_KEYBOARD: ReentrantMutex<UInputDevice> = {
|
||||
(|| -> io::Result<_> {
|
||||
let device = Device::new().unwrap();
|
||||
device.set_name("Surface Dial Virtual Input");
|
||||
device.set_name("Surface Dial Virtual Keyboard/Mouse");
|
||||
|
||||
device.enable(&EventType::EV_SYN)?;
|
||||
device.enable(&EventCode::EV_SYN(EV_SYN::SYN_REPORT))?;
|
||||
@@ -41,15 +42,82 @@ fn get_fake_input() -> io::Result<&'static UInputDevice> {
|
||||
device.enable(&EventCode::EV_REL(EV_REL::REL_WHEEL_HI_RES))?;
|
||||
}
|
||||
|
||||
unsafe { FAKE_INPUT = Some(UInputDevice::create_from_device(&device)?) }
|
||||
Ok(ReentrantMutex::new(UInputDevice::create_from_device(&device)?))
|
||||
})().expect("failed to install virtual mouse/keyboard device")
|
||||
};
|
||||
|
||||
static ref FAKE_TOUCHPAD: ReentrantMutex<UInputDevice> = {
|
||||
(|| -> io::Result<_> {
|
||||
let device = Device::new().unwrap();
|
||||
device.set_name("Surface Dial Virtual Touchpad");
|
||||
|
||||
device.enable(&InputProp::INPUT_PROP_BUTTONPAD)?;
|
||||
device.enable(&InputProp::INPUT_PROP_POINTER)?;
|
||||
|
||||
device.enable(&EventType::EV_SYN)?;
|
||||
device.enable(&EventCode::EV_SYN(EV_SYN::SYN_REPORT))?;
|
||||
|
||||
device.enable(&EventType::EV_KEY)?;
|
||||
{
|
||||
device.enable(&EventCode::EV_KEY(EV_KEY::BTN_LEFT))?;
|
||||
device.enable(&EventCode::EV_KEY(EV_KEY::BTN_TOOL_FINGER))?;
|
||||
device.enable(&EventCode::EV_KEY(EV_KEY::BTN_TOUCH))?;
|
||||
device.enable(&EventCode::EV_KEY(EV_KEY::BTN_TOOL_DOUBLETAP))?;
|
||||
device.enable(&EventCode::EV_KEY(EV_KEY::BTN_TOOL_TRIPLETAP))?;
|
||||
device.enable(&EventCode::EV_KEY(EV_KEY::BTN_TOOL_QUADTAP))?;
|
||||
}
|
||||
unsafe { Ok(FAKE_INPUT.as_ref().unwrap()) }
|
||||
|
||||
// roughly copied from my laptop's trackpad (Aero 15x)
|
||||
device.enable(&EventType::EV_ABS)?;
|
||||
{
|
||||
let mut abs_info = evdev_rs::AbsInfo {
|
||||
value: 0,
|
||||
minimum: 0,
|
||||
maximum: 0,
|
||||
fuzz: 0,
|
||||
flat: 0,
|
||||
resolution: 0,
|
||||
};
|
||||
|
||||
abs_info.minimum = 0;
|
||||
abs_info.maximum = 4;
|
||||
device.enable_event_code(&EventCode::EV_ABS(EV_ABS::ABS_MT_SLOT), Some(&abs_info))?;
|
||||
|
||||
abs_info.minimum = 0;
|
||||
abs_info.maximum = 65535;
|
||||
device.enable_event_code(
|
||||
&EventCode::EV_ABS(EV_ABS::ABS_MT_TRACKING_ID),
|
||||
Some(&abs_info),
|
||||
)?;
|
||||
|
||||
// higher = more sensitive
|
||||
const SENSITIVITY: i32 = 64;
|
||||
|
||||
abs_info.minimum = 0;
|
||||
abs_info.maximum = std::i32::MAX;
|
||||
abs_info.resolution = SENSITIVITY;
|
||||
device.enable_event_code(
|
||||
&EventCode::EV_ABS(EV_ABS::ABS_MT_POSITION_X),
|
||||
Some(&abs_info),
|
||||
)?;
|
||||
|
||||
abs_info.minimum = 0;
|
||||
abs_info.maximum = std::i32::MAX;
|
||||
abs_info.resolution = SENSITIVITY;
|
||||
device.enable_event_code(
|
||||
&EventCode::EV_ABS(EV_ABS::ABS_MT_POSITION_Y),
|
||||
Some(&abs_info),
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(ReentrantMutex::new(UInputDevice::create_from_device(&device)?))
|
||||
})().expect("failed to install virtual touchpad device")
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct FakeInput {
|
||||
uinput: &'static UInputDevice,
|
||||
}
|
||||
pub struct FakeInput {}
|
||||
|
||||
macro_rules! input_event {
|
||||
($type:ident, $code:ident, $value:expr) => {
|
||||
@@ -70,14 +138,11 @@ impl Default for FakeInput {
|
||||
|
||||
impl FakeInput {
|
||||
pub fn new() -> FakeInput {
|
||||
FakeInput {
|
||||
uinput: get_fake_input().expect("could not install fake input device"),
|
||||
}
|
||||
FakeInput {}
|
||||
}
|
||||
|
||||
fn syn_report(&self) -> io::Result<()> {
|
||||
self.uinput
|
||||
.write_event(&input_event!(EV_SYN, SYN_REPORT, 0))
|
||||
fn kbd_syn_report(&self) -> io::Result<()> {
|
||||
(FAKE_KEYBOARD.lock()).write_event(&input_event!(EV_SYN, SYN_REPORT, 0))
|
||||
}
|
||||
|
||||
pub fn key_click(&self, keys: &[EV_KEY]) -> io::Result<()> {
|
||||
@@ -87,34 +152,40 @@ impl FakeInput {
|
||||
}
|
||||
|
||||
pub fn key_press(&self, keys: &[EV_KEY]) -> io::Result<()> {
|
||||
let keyboard = FAKE_KEYBOARD.lock();
|
||||
|
||||
for key in keys {
|
||||
self.uinput.write_event(&InputEvent {
|
||||
keyboard.write_event(&InputEvent {
|
||||
time: TimeVal::new(0, 0),
|
||||
event_code: EventCode::EV_KEY(*key),
|
||||
event_type: EventType::EV_KEY,
|
||||
value: 1,
|
||||
})?;
|
||||
}
|
||||
self.syn_report()?;
|
||||
self.kbd_syn_report()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn key_release(&self, keys: &[EV_KEY]) -> io::Result<()> {
|
||||
let keyboard = FAKE_KEYBOARD.lock();
|
||||
|
||||
for key in keys.iter().clone() {
|
||||
self.uinput.write_event(&InputEvent {
|
||||
keyboard.write_event(&InputEvent {
|
||||
time: TimeVal::new(0, 0),
|
||||
event_code: EventCode::EV_KEY(*key),
|
||||
event_type: EventType::EV_KEY,
|
||||
value: 0,
|
||||
})?;
|
||||
}
|
||||
self.syn_report()?;
|
||||
self.kbd_syn_report()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn scroll_step(&self, dir: ScrollStep) -> io::Result<()> {
|
||||
let keyboard = FAKE_KEYBOARD.lock();
|
||||
|
||||
// copied from my razer blackwidow chroma mouse
|
||||
self.uinput.write_event(&InputEvent {
|
||||
keyboard.write_event(&InputEvent {
|
||||
time: TimeVal::new(0, 0),
|
||||
event_code: EventCode::EV_REL(EV_REL::REL_WHEEL),
|
||||
event_type: EventType::EV_REL,
|
||||
@@ -123,7 +194,7 @@ impl FakeInput {
|
||||
ScrollStep::Up => 1,
|
||||
},
|
||||
})?;
|
||||
self.uinput.write_event(&InputEvent {
|
||||
keyboard.write_event(&InputEvent {
|
||||
time: TimeVal::new(0, 0),
|
||||
event_code: EventCode::EV_REL(EV_REL::REL_WHEEL_HI_RES),
|
||||
event_type: EventType::EV_REL,
|
||||
@@ -132,11 +203,89 @@ impl FakeInput {
|
||||
ScrollStep::Up => 120,
|
||||
},
|
||||
})?;
|
||||
self.syn_report()?;
|
||||
self.kbd_syn_report()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn touch_syn_report(&self) -> io::Result<()> {
|
||||
(FAKE_TOUCHPAD.lock()).write_event(&input_event!(EV_SYN, SYN_REPORT, 0))
|
||||
}
|
||||
|
||||
pub fn scroll_mt_start(&self) -> io::Result<()> {
|
||||
let touchpad = FAKE_TOUCHPAD.lock();
|
||||
|
||||
{
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_SLOT, 0))?;
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_TRACKING_ID, 1))?;
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_POSITION_X, MT_BASELINE))?;
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_POSITION_Y, MT_BASELINE))?;
|
||||
|
||||
touchpad.write_event(&input_event!(EV_KEY, BTN_TOUCH, 1))?;
|
||||
touchpad.write_event(&input_event!(EV_KEY, BTN_TOOL_FINGER, 1))?;
|
||||
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_X, MT_BASELINE))?;
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_Y, MT_BASELINE))?;
|
||||
}
|
||||
|
||||
self.touch_syn_report()?;
|
||||
|
||||
{
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_SLOT, 1))?;
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_TRACKING_ID, 2))?;
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_POSITION_X, std::i32::MAX / 3))?;
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_POSITION_Y, MT_BASELINE))?;
|
||||
|
||||
touchpad.write_event(&input_event!(EV_KEY, BTN_TOOL_FINGER, 0))?;
|
||||
touchpad.write_event(&input_event!(EV_KEY, BTN_TOOL_DOUBLETAP, 1))?;
|
||||
}
|
||||
|
||||
self.touch_syn_report()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn scroll_mt_step(&self, delta: i32) -> io::Result<()> {
|
||||
let touchpad = FAKE_TOUCHPAD.lock();
|
||||
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_SLOT, 0))?;
|
||||
touchpad.write_event(&input_event!(
|
||||
EV_ABS,
|
||||
ABS_MT_POSITION_Y,
|
||||
MT_BASELINE + delta
|
||||
))?;
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_SLOT, 1))?;
|
||||
touchpad.write_event(&input_event!(
|
||||
EV_ABS,
|
||||
ABS_MT_POSITION_Y,
|
||||
MT_BASELINE + delta
|
||||
))?;
|
||||
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_Y, MT_BASELINE + delta))?;
|
||||
|
||||
self.touch_syn_report()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn scroll_mt_end(&self) -> io::Result<()> {
|
||||
let touchpad = FAKE_TOUCHPAD.lock();
|
||||
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_SLOT, 0))?;
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_TRACKING_ID, -1))?;
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_SLOT, 1))?;
|
||||
touchpad.write_event(&input_event!(EV_ABS, ABS_MT_TRACKING_ID, -1))?;
|
||||
|
||||
touchpad.write_event(&input_event!(EV_KEY, BTN_TOUCH, 0))?;
|
||||
touchpad.write_event(&input_event!(EV_KEY, BTN_TOOL_DOUBLETAP, 0))?;
|
||||
|
||||
self.touch_syn_report()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
const MT_BASELINE: i32 = std::i32::MAX / 2;
|
||||
|
||||
pub enum ScrollStep {
|
||||
Up,
|
||||
Down,
|
||||
|
||||
12
src/main.rs
12
src/main.rs
@@ -62,8 +62,8 @@ fn main() {
|
||||
println!("{}", e);
|
||||
}
|
||||
|
||||
kill_notif_tx.send(None).unwrap(); // silently shut down
|
||||
handle.join().unwrap();
|
||||
let _ = kill_notif_tx.send(None); // silently shut down
|
||||
let _ = handle.join();
|
||||
}
|
||||
|
||||
fn true_main(kill_notif_tx: mpsc::Sender<Option<(String, &'static str)>>) -> DynResult<()> {
|
||||
@@ -78,9 +78,10 @@ fn true_main(kill_notif_tx: mpsc::Sender<Option<(String, &'static str)>>) -> Dyn
|
||||
let signals = Signals::new(&[SIGTERM, SIGINT]).unwrap();
|
||||
for sig in signals.forever() {
|
||||
eprintln!("received signal {:?}", sig);
|
||||
kill_notif_tx
|
||||
.send(Some(("Terminated!".into(), "dialog-warning")))
|
||||
.unwrap();
|
||||
match kill_notif_tx.send(Some(("Terminated!".into(), "dialog-warning"))) {
|
||||
Ok(_) => {}
|
||||
Err(_) => std::process::exit(1),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -88,6 +89,7 @@ fn true_main(kill_notif_tx: mpsc::Sender<Option<(String, &'static str)>>) -> Dyn
|
||||
dial,
|
||||
cfg.last_mode,
|
||||
vec![
|
||||
// Box::new(controller::controls::ScrollMT::new()),
|
||||
Box::new(controller::controls::Scroll::new()),
|
||||
Box::new(controller::controls::Zoom::new()),
|
||||
Box::new(controller::controls::Volume::new()),
|
||||
|
||||
Reference in New Issue
Block a user