parent
2b4835171a
commit
7a679c6395
|
@ -8,7 +8,7 @@ use std::io::Read;
|
|||
use serde::{Serialize, Deserialize};
|
||||
use crate::event::KeyModifier;
|
||||
use std::collections::HashSet;
|
||||
use log::{error, LevelFilter};
|
||||
use log::{error};
|
||||
use std::fmt;
|
||||
use std::error::Error;
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::sync::mpsc;
|
||||
use std::os::raw::{c_void};
|
||||
use std::ffi::CString;
|
||||
use crate::bridge::linux::*;
|
||||
|
||||
|
|
97
src/main.rs
97
src/main.rs
|
@ -8,7 +8,7 @@ use std::time::Duration;
|
|||
|
||||
use clap::{App, Arg, SubCommand, ArgMatches};
|
||||
use fs2::FileExt;
|
||||
use log::{error, info, LevelFilter};
|
||||
use log::{error, info, warn, LevelFilter};
|
||||
use simplelog::{CombinedLogger, SharedLogger, TerminalMode, TermLogger};
|
||||
|
||||
use crate::config::ConfigSet;
|
||||
|
@ -69,6 +69,10 @@ fn main() {
|
|||
.about("Start the daemon without spawning a new process."))
|
||||
.subcommand(SubCommand::with_name("start")
|
||||
.about("Start the daemon spawning a new process in the background."))
|
||||
.subcommand(SubCommand::with_name("stop")
|
||||
.about("Stop the espanso daemon."))
|
||||
.subcommand(SubCommand::with_name("restart")
|
||||
.about("Restart the espanso daemon."))
|
||||
.subcommand(SubCommand::with_name("status")
|
||||
.about("Check if the espanso daemon is running or not."))
|
||||
.get_matches();
|
||||
|
@ -98,33 +102,43 @@ fn main() {
|
|||
|
||||
// Match the correct subcommand
|
||||
|
||||
if let Some(matches) = matches.subcommand_matches("dump") {
|
||||
if let Some(matches) = matches.subcommand_matches("cmd") {
|
||||
cmd_main(config_set, matches);
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(_) = matches.subcommand_matches("dump") {
|
||||
println!("{:#?}", config_set);
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(matches) = matches.subcommand_matches("detect") {
|
||||
if let Some(_) = matches.subcommand_matches("detect") {
|
||||
detect_main();
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(matches) = matches.subcommand_matches("daemon") {
|
||||
if let Some(_) = matches.subcommand_matches("daemon") {
|
||||
daemon_main(config_set);
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(matches) = matches.subcommand_matches("start") {
|
||||
if let Some(_) = matches.subcommand_matches("start") {
|
||||
start_main(config_set);
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(matches) = matches.subcommand_matches("status") {
|
||||
if let Some(_) = matches.subcommand_matches("status") {
|
||||
status_main();
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(matches) = matches.subcommand_matches("cmd") {
|
||||
cmd_main(matches);
|
||||
if let Some(_) = matches.subcommand_matches("stop") {
|
||||
stop_main(config_set);
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(_) = matches.subcommand_matches("restart") {
|
||||
restart_main(config_set);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -255,6 +269,49 @@ fn status_main() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Stop subcommand, used to stop the daemon.
|
||||
fn stop_main(config_set: ConfigSet) {
|
||||
// Try to acquire lock file
|
||||
let lock_file = acquire_lock();
|
||||
if lock_file.is_some() {
|
||||
println!("espanso daemon is not running.");
|
||||
release_lock(lock_file.unwrap());
|
||||
exit(3);
|
||||
}
|
||||
|
||||
let res = send_command(config_set, IPCCommand{
|
||||
id: "exit".to_owned(),
|
||||
payload: "".to_owned(),
|
||||
});
|
||||
|
||||
if let Err(e) = res {
|
||||
println!("{}", e);
|
||||
exit(1);
|
||||
}else{
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
fn restart_main(config_set: ConfigSet) {
|
||||
// Kill the daemon if running
|
||||
let lock_file = acquire_lock();
|
||||
if lock_file.is_none() {
|
||||
// Terminate the current espanso daemon
|
||||
send_command(config_set.clone(), IPCCommand{
|
||||
id: "exit".to_owned(),
|
||||
payload: "".to_owned(),
|
||||
}).unwrap_or_else(|e| warn!("Unable to send IPC command to daemon: {}", e));
|
||||
}else{
|
||||
release_lock(lock_file.unwrap());
|
||||
}
|
||||
|
||||
std::thread::sleep(Duration::from_millis(300));
|
||||
|
||||
// Restart the daemon
|
||||
start_main(config_set);
|
||||
}
|
||||
|
||||
/// Cli tool used to analyze active windows to extract useful information
|
||||
/// to create configuration filters.
|
||||
fn detect_main() {
|
||||
|
@ -289,23 +346,23 @@ fn detect_main() {
|
|||
}
|
||||
}
|
||||
|
||||
fn cmd_main(matches: &ArgMatches) {
|
||||
let command = if let Some(matches) = matches.subcommand_matches("exit") {
|
||||
fn cmd_main(config_set: ConfigSet, matches: &ArgMatches) {
|
||||
let command = if let Some(_) = matches.subcommand_matches("exit") {
|
||||
Some(IPCCommand {
|
||||
id: String::from("exit"),
|
||||
payload: String::from(""),
|
||||
})
|
||||
}else if let Some(matches) = matches.subcommand_matches("toggle") {
|
||||
}else if let Some(_) = matches.subcommand_matches("toggle") {
|
||||
Some(IPCCommand {
|
||||
id: String::from("toggle"),
|
||||
payload: String::from(""),
|
||||
})
|
||||
}else if let Some(matches) = matches.subcommand_matches("enable") {
|
||||
}else if let Some(_) = matches.subcommand_matches("enable") {
|
||||
Some(IPCCommand {
|
||||
id: String::from("enable"),
|
||||
payload: String::from(""),
|
||||
})
|
||||
}else if let Some(matches) = matches.subcommand_matches("disable") {
|
||||
}else if let Some(_) = matches.subcommand_matches("disable") {
|
||||
Some(IPCCommand {
|
||||
id: String::from("disable"),
|
||||
payload: String::from(""),
|
||||
|
@ -315,15 +372,23 @@ fn cmd_main(matches: &ArgMatches) {
|
|||
};
|
||||
|
||||
if let Some(command) = command {
|
||||
let ipc_client = protocol::get_ipc_client();
|
||||
ipc_client.send_command(command);
|
||||
let res = send_command(config_set, command);
|
||||
|
||||
exit(0);
|
||||
if res.is_ok() {
|
||||
exit(0);
|
||||
}else{
|
||||
println!("{}", res.unwrap_err());
|
||||
}
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fn send_command(config_set: ConfigSet, command: IPCCommand) -> Result<(), String> {
|
||||
let ipc_client = protocol::get_ipc_client();
|
||||
ipc_client.send_command(command)
|
||||
}
|
||||
|
||||
fn acquire_lock() -> Option<File> {
|
||||
let espanso_dir = context::get_data_dir();
|
||||
let lock_file_path = espanso_dir.join("espanso.lock");
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Result;
|
||||
use std::sync::mpsc::Sender;
|
||||
use crate::event::Event;
|
||||
use crate::event::Event::*;
|
||||
use crate::event::ActionType;
|
||||
use crate::event::ActionType::*;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
mod windows;
|
||||
|
@ -17,7 +14,7 @@ pub trait IPCServer {
|
|||
}
|
||||
|
||||
pub trait IPCClient {
|
||||
fn send_command(&self, command: IPCCommand);
|
||||
fn send_command(&self, command: IPCCommand) -> Result<(), String>;
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
use std::io::{BufRead, BufReader, Read};
|
||||
use std::io::{BufReader, Read};
|
||||
use std::io::Write;
|
||||
use std::os::unix::net::{UnixStream,UnixListener};
|
||||
use std::thread;
|
||||
use log::{info, error};
|
||||
use log::{info, error, warn};
|
||||
use std::sync::mpsc::Sender;
|
||||
use super::IPCCommand;
|
||||
|
||||
use crate::context;
|
||||
use crate::context::get_data_dir;
|
||||
use crate::event::*;
|
||||
|
||||
const UNIX_SOCKET_NAME : &str = "espanso.sock";
|
||||
|
@ -29,7 +27,9 @@ impl super::IPCServer for UnixIPCServer {
|
|||
let espanso_dir = context::get_data_dir();
|
||||
let unix_socket = espanso_dir.join(UNIX_SOCKET_NAME);
|
||||
|
||||
std::fs::remove_file(unix_socket.clone());
|
||||
std::fs::remove_file(unix_socket.clone()).unwrap_or_else(|e| {
|
||||
warn!("Unable to delete Unix socket: {}", e);
|
||||
});
|
||||
let listener = UnixListener::bind(unix_socket.clone()).expect("Can't bind to Unix Socket");
|
||||
|
||||
info!("Binded to IPC unix socket: {}", unix_socket.as_path().display());
|
||||
|
@ -39,19 +39,21 @@ impl super::IPCServer for UnixIPCServer {
|
|||
Ok(stream) => {
|
||||
let mut json_str= String::new();
|
||||
let mut buf_reader = BufReader::new(stream);
|
||||
buf_reader.read_to_string(&mut json_str);
|
||||
let res = buf_reader.read_to_string(&mut json_str);
|
||||
|
||||
let command : Result<IPCCommand, serde_json::Error> = serde_json::from_str(&json_str);
|
||||
match command {
|
||||
Ok(command) => {
|
||||
let event = command.to_event();
|
||||
if let Some(event) = event {
|
||||
event_channel.send(event).expect("Broken event channel");
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Error deserializing JSON command: {}", e);
|
||||
},
|
||||
if res.is_ok() {
|
||||
let command : Result<IPCCommand, serde_json::Error> = serde_json::from_str(&json_str);
|
||||
match command {
|
||||
Ok(command) => {
|
||||
let event = command.to_event();
|
||||
if let Some(event) = event {
|
||||
event_channel.send(event).expect("Broken event channel");
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Error deserializing JSON command: {}", e);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
|
@ -75,24 +77,27 @@ impl UnixIPCClient {
|
|||
}
|
||||
|
||||
impl super::IPCClient for UnixIPCClient {
|
||||
fn send_command(&self, command: IPCCommand) {
|
||||
fn send_command(&self, command: IPCCommand) -> Result<(), String> {
|
||||
let espanso_dir = context::get_data_dir();
|
||||
let unix_socket = espanso_dir.join(UNIX_SOCKET_NAME);
|
||||
|
||||
// Open the stream
|
||||
let mut stream = UnixStream::connect(unix_socket);
|
||||
let stream = UnixStream::connect(unix_socket);
|
||||
match stream {
|
||||
Ok(mut stream) => {
|
||||
let json_str = serde_json::to_string(&command);
|
||||
if let Ok(json_str) = json_str {
|
||||
stream.write_all(json_str.as_bytes()).unwrap_or_else(|e| {
|
||||
println!("Can't write to IPC socket");
|
||||
println!("Can't write to IPC socket: {}", e);
|
||||
});
|
||||
return Ok(())
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Can't connect to daemon: {}", e);
|
||||
return Err(format!("Can't connect to daemon: {}", e))
|
||||
}
|
||||
}
|
||||
|
||||
Err("Can't send command".to_owned())
|
||||
}
|
||||
}
|
|
@ -14,8 +14,8 @@ impl super::UIManager for LinuxUIManager {
|
|||
}
|
||||
}
|
||||
|
||||
fn show_menu(&self, menu: Vec<MenuItem>) {
|
||||
unimplemented!()
|
||||
fn show_menu(&self, _menu: Vec<MenuItem>) {
|
||||
// Not implemented on linux
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user