clean up notification when terminated
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -145,7 +145,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "evdev-rs"
|
name = "evdev-rs"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "git+https://github.com/ndesh26/evdev-rs.git#8e995b8bfc1f8ed844ae47edaa4286c99e8c88b5"
|
source = "git+https://github.com/ndesh26/evdev-rs.git?rev=8e995b8bf#8e995b8bfc1f8ed844ae47edaa4286c99e8c88b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.2.1",
|
"bitflags 1.2.1",
|
||||||
"evdev-sys",
|
"evdev-sys",
|
||||||
@@ -156,7 +156,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "evdev-sys"
|
name = "evdev-sys"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/ndesh26/evdev-rs.git#8e995b8bfc1f8ed844ae47edaa4286c99e8c88b5"
|
source = "git+https://github.com/ndesh26/evdev-rs.git?rev=8e995b8bf#8e995b8bfc1f8ed844ae47edaa4286c99e8c88b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
directories = "3.0"
|
directories = "3.0"
|
||||||
# master includes a PR that implements `Send` for `Device` and `UInputDevice`
|
# master includes a PR that implements `Send` for `Device` and `UInputDevice`
|
||||||
evdev-rs = { git = "https://github.com/ndesh26/evdev-rs.git" }
|
evdev-rs = { git = "https://github.com/ndesh26/evdev-rs.git", rev = "8e995b8bf" }
|
||||||
hidapi = { version = "1.2.3", default-features = false, features = ["linux-shared-hidraw"] }
|
hidapi = { version = "1.2.3", default-features = false, features = ["linux-shared-hidraw"] }
|
||||||
notify-rust = "4"
|
notify-rust = "4"
|
||||||
signal-hook = "0.1.16"
|
signal-hook = "0.1.16"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::fs;
|
|||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use evdev_rs::{Device, InputEvent};
|
use evdev_rs::{Device, InputEvent, ReadStatus};
|
||||||
use hidapi::{HidApi, HidDevice};
|
use hidapi::{HidApi, HidDevice};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
@@ -10,7 +10,7 @@ use crate::error::Error;
|
|||||||
pub struct DialDevice {
|
pub struct DialDevice {
|
||||||
long_press_timeout: Duration,
|
long_press_timeout: Duration,
|
||||||
haptics: DialHaptics,
|
haptics: DialHaptics,
|
||||||
events: mpsc::Receiver<DialEvent>,
|
events: mpsc::Receiver<std::io::Result<(ReadStatus, InputEvent)>>,
|
||||||
|
|
||||||
possible_long_press: bool,
|
possible_long_press: bool,
|
||||||
}
|
}
|
||||||
@@ -75,17 +75,10 @@ impl DialDevice {
|
|||||||
|
|
||||||
std::thread::spawn({
|
std::thread::spawn({
|
||||||
let events = events_tx;
|
let events = events_tx;
|
||||||
move || {
|
move || loop {
|
||||||
loop {
|
events
|
||||||
let (_axis_status, axis_evt) = axis
|
.send(axis.next_event(evdev_rs::ReadFlag::NORMAL))
|
||||||
.next_event(evdev_rs::ReadFlag::NORMAL)
|
.expect("failed to send axis event");
|
||||||
.expect("Error::Evdev");
|
|
||||||
// assert!(matches!(axis_status, ReadStatus::Success));
|
|
||||||
let event = DialEvent::from_raw_evt(axis_evt.clone())
|
|
||||||
.expect("Error::UnexpectedEvt(axis_evt)");
|
|
||||||
|
|
||||||
events.send(event).expect("failed to send axis event");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -108,7 +101,10 @@ impl DialDevice {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let event = match evt {
|
let event = match evt {
|
||||||
Ok(event) => {
|
Ok(Ok((_event_status, event))) => {
|
||||||
|
// assert!(matches!(axis_status, ReadStatus::Success));
|
||||||
|
let event =
|
||||||
|
DialEvent::from_raw_evt(event.clone()).ok_or(Error::UnexpectedEvt(event))?;
|
||||||
match event.kind {
|
match event.kind {
|
||||||
DialEventKind::ButtonPress => self.possible_long_press = true,
|
DialEventKind::ButtonPress => self.possible_long_press = true,
|
||||||
DialEventKind::ButtonRelease => self.possible_long_press = false,
|
DialEventKind::ButtonRelease => self.possible_long_press = false,
|
||||||
@@ -116,6 +112,7 @@ impl DialDevice {
|
|||||||
}
|
}
|
||||||
event
|
event
|
||||||
}
|
}
|
||||||
|
Ok(Err(e)) => return Err(Error::Evdev(e)),
|
||||||
Err(mpsc::RecvTimeoutError::Timeout) => {
|
Err(mpsc::RecvTimeoutError::Timeout) => {
|
||||||
self.possible_long_press = false;
|
self.possible_long_press = false;
|
||||||
DialEvent {
|
DialEvent {
|
||||||
|
|||||||
67
src/main.rs
67
src/main.rs
@@ -9,6 +9,8 @@ mod fake_input;
|
|||||||
|
|
||||||
pub type DynResult<T> = Result<T, Box<dyn std::error::Error>>;
|
pub type DynResult<T> = Result<T, Box<dyn std::error::Error>>;
|
||||||
|
|
||||||
|
use std::sync::mpsc;
|
||||||
|
|
||||||
use crate::controller::DialController;
|
use crate::controller::DialController;
|
||||||
use crate::dial_device::DialDevice;
|
use crate::dial_device::DialDevice;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
@@ -17,22 +19,9 @@ use notify_rust::{Hint, Notification, Timeout};
|
|||||||
use signal_hook::{iterator::Signals, SIGINT, SIGTERM};
|
use signal_hook::{iterator::Signals, SIGINT, SIGTERM};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
if let Err(e) = true_main() {
|
let (kill_notif_tx, kill_notif_rx) = mpsc::channel::<Option<(String, &'static str)>>();
|
||||||
println!("{}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn true_main() -> DynResult<()> {
|
|
||||||
println!("Started");
|
|
||||||
|
|
||||||
let cfg = config::Config::from_disk()?;
|
|
||||||
|
|
||||||
let dial = DialDevice::new(std::time::Duration::from_millis(750))?;
|
|
||||||
println!("Found the dial");
|
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
|
||||||
// TODO: use this persistent notification for the meta mode.
|
|
||||||
|
|
||||||
|
let handle = std::thread::spawn(move || {
|
||||||
let active_notification = Notification::new()
|
let active_notification = Notification::new()
|
||||||
.hint(Hint::Resident(true))
|
.hint(Hint::Resident(true))
|
||||||
.hint(Hint::Category("device".into()))
|
.hint(Hint::Category("device".into()))
|
||||||
@@ -43,11 +32,55 @@ fn true_main() -> DynResult<()> {
|
|||||||
.show()
|
.show()
|
||||||
.expect("failed to send notification");
|
.expect("failed to send notification");
|
||||||
|
|
||||||
|
let kill_notif = kill_notif_rx.recv();
|
||||||
|
|
||||||
|
active_notification.close();
|
||||||
|
|
||||||
|
let (msg, icon) = match kill_notif {
|
||||||
|
Ok(None) => {
|
||||||
|
// shutdown immediately
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
Ok(Some((msg, icon))) => (msg, icon),
|
||||||
|
Err(_) => ("Unexpected Error".into(), "dialog-error"),
|
||||||
|
};
|
||||||
|
|
||||||
|
Notification::new()
|
||||||
|
.hint(Hint::Transient(true))
|
||||||
|
.hint(Hint::Category("device".into()))
|
||||||
|
.timeout(Timeout::Milliseconds(100))
|
||||||
|
.summary("Surface Dial")
|
||||||
|
.body(&msg)
|
||||||
|
.icon(icon)
|
||||||
|
.show()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
std::process::exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Err(e) = true_main(kill_notif_tx.clone()) {
|
||||||
|
println!("{}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
kill_notif_tx.send(None).unwrap(); // silently shut down
|
||||||
|
handle.join().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn true_main(kill_notif_tx: mpsc::Sender<Option<(String, &'static str)>>) -> DynResult<()> {
|
||||||
|
println!("Started");
|
||||||
|
|
||||||
|
let cfg = config::Config::from_disk()?;
|
||||||
|
|
||||||
|
let dial = DialDevice::new(std::time::Duration::from_millis(750))?;
|
||||||
|
println!("Found the dial");
|
||||||
|
|
||||||
|
std::thread::spawn(move || {
|
||||||
let signals = Signals::new(&[SIGTERM, SIGINT]).unwrap();
|
let signals = Signals::new(&[SIGTERM, SIGINT]).unwrap();
|
||||||
for sig in signals.forever() {
|
for sig in signals.forever() {
|
||||||
eprintln!("received signal {:?}", sig);
|
eprintln!("received signal {:?}", sig);
|
||||||
active_notification.close();
|
kill_notif_tx
|
||||||
std::process::exit(1);
|
.send(Some(("Terminated!".into(), "dialog-warning")))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user