feat(ui): implement Heartbeat on Linux
This commit is contained in:
parent
02b486dc7a
commit
733d7e2ff4
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -759,6 +759,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cc",
|
"cc",
|
||||||
|
"crossbeam",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"lazycell",
|
"lazycell",
|
||||||
"log",
|
"log",
|
||||||
|
|
|
@ -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"
|
|
@ -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<()> {
|
||||||
|
loop {
|
||||||
|
select! {
|
||||||
|
recv(self.rx) -> result => {
|
||||||
// We don't run an event loop on Linux as there is no tray icon or application window needed.
|
// We don't run an event loop on Linux as there is no tray icon or application window needed.
|
||||||
// Thad said, we still need a way to block this method, and thus we use a channel
|
// Thad said, we still need a way to block this method, and thus we use a channel
|
||||||
if let Err(error) = self.rx.recv() {
|
match result {
|
||||||
|
Ok(_) => {
|
||||||
|
// remote.exit() called
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
Err(error) => {
|
||||||
error!("Unable to block the LinuxEventLoop: {}", error);
|
error!("Unable to block the LinuxEventLoop: {}", error);
|
||||||
return Err(error.into());
|
return Err(error.into());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ok(())
|
},
|
||||||
|
default(Duration::from_millis(1000)) => {
|
||||||
|
(*callback)(UIEvent::Heartbeat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user