feat(ui): implement Heartbeat on Linux

This commit is contained in:
Federico Terzi 2021-08-06 19:56:36 +02:00
parent 02b486dc7a
commit 733d7e2ff4
3 changed files with 34 additions and 13 deletions

1
Cargo.lock generated
View File

@ -759,6 +759,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cc", "cc",
"crossbeam",
"lazy_static", "lazy_static",
"lazycell", "lazycell",
"log", "log",

View File

@ -28,6 +28,7 @@ lazycell = "1.3.0"
[target.'cfg(target_os="linux")'.dependencies] [target.'cfg(target_os="linux")'.dependencies]
notify-rust = "4.2.2" notify-rust = "4.2.2"
crossbeam = "0.8.0"
[build-dependencies] [build-dependencies]
cc = "1.0.66" cc = "1.0.66"

View File

@ -17,20 +17,24 @@
* along with espanso. If not, see <https://www.gnu.org/licenses/>. * along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/ */
use std::time::Duration;
use anyhow::Result; use anyhow::Result;
use crossbeam::{
channel::{unbounded, Receiver, Sender},
select,
};
use log::error; use log::error;
use notify_rust::Notification; use notify_rust::Notification;
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender};
use crate::{UIEventLoop, UIRemote}; use crate::{event::UIEvent, UIEventLoop, UIRemote};
pub struct LinuxUIOptions { pub struct LinuxUIOptions {
pub notification_icon_path: String, pub notification_icon_path: String,
} }
pub fn create(options: LinuxUIOptions) -> (LinuxRemote, LinuxEventLoop) { pub fn create(options: LinuxUIOptions) -> (LinuxRemote, LinuxEventLoop) {
let (tx, rx) = mpsc::channel(); let (tx, rx) = unbounded();
let remote = LinuxRemote::new(tx, options.notification_icon_path); let remote = LinuxRemote::new(tx, options.notification_icon_path);
let eventloop = LinuxEventLoop::new(rx); let eventloop = LinuxEventLoop::new(rx);
(remote, eventloop) (remote, eventloop)
@ -75,7 +79,9 @@ impl UIRemote for LinuxRemote {
} }
fn exit(&self) { fn exit(&self) {
self.stop().expect("unable to send termination signal to ui eventloop"); self
.stop()
.expect("unable to send termination signal to ui eventloop");
} }
} }
@ -95,14 +101,27 @@ impl UIEventLoop for LinuxEventLoop {
Ok(()) Ok(())
} }
fn run(&self, _: crate::UIEventCallback) -> Result<()> { fn run(&self, callback: crate::UIEventCallback) -> Result<()> {
// We don't run an event loop on Linux as there is no tray icon or application window needed. loop {
// Thad said, we still need a way to block this method, and thus we use a channel select! {
if let Err(error) = self.rx.recv() { recv(self.rx) -> result => {
error!("Unable to block the LinuxEventLoop: {}", error); // We don't run an event loop on Linux as there is no tray icon or application window needed.
return Err(error.into()); // Thad said, we still need a way to block this method, and thus we use a channel
match result {
Ok(_) => {
// remote.exit() called
return Ok(());
}
Err(error) => {
error!("Unable to block the LinuxEventLoop: {}", error);
return Err(error.into());
}
}
},
default(Duration::from_millis(1000)) => {
(*callback)(UIEvent::Heartbeat);
}
}
} }
Ok(())
} }
} }