Add eww logs command. fixes #7
This commit is contained in:
parent
a906c18bd7
commit
e427101c19
2 changed files with 75 additions and 37 deletions
110
src/main.rs
110
src/main.rs
|
@ -20,6 +20,7 @@ use std::{
|
||||||
io::{Read, Write},
|
io::{Read, Write},
|
||||||
os::unix::{io::AsRawFd, net},
|
os::unix::{io::AsRawFd, net},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
process::Stdio,
|
||||||
};
|
};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use value::Coords;
|
use value::Coords;
|
||||||
|
@ -82,8 +83,23 @@ pub struct Opt {
|
||||||
#[structopt(short = "-d", long = "--detach")]
|
#[structopt(short = "-d", long = "--detach")]
|
||||||
should_detach: bool,
|
should_detach: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub enum OptAction {
|
pub enum OptAction {
|
||||||
|
#[structopt(flatten)]
|
||||||
|
ClientOnly(OptActionClientOnly),
|
||||||
|
#[structopt(flatten)]
|
||||||
|
WithServer(OptActionWithServer),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum OptActionClientOnly {
|
||||||
|
#[structopt(name = "logs", help = "Print and watch the eww logs")]
|
||||||
|
Logs,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum OptActionWithServer {
|
||||||
#[structopt(name = "update", help = "update the value of a variable, in a running eww instance")]
|
#[structopt(name = "update", help = "update the value of a variable, in a running eww instance")]
|
||||||
Update { fieldname: VarName, value: PrimitiveValue },
|
Update { fieldname: VarName, value: PrimitiveValue },
|
||||||
|
|
||||||
|
@ -101,7 +117,7 @@ pub enum OptAction {
|
||||||
#[structopt(name = "close", help = "close the window with the given name")]
|
#[structopt(name = "close", help = "close the window with the given name")]
|
||||||
CloseWindow { window_name: WindowName },
|
CloseWindow { window_name: WindowName },
|
||||||
|
|
||||||
#[structopt(name = "kill", help = "kill the eww daemon")]
|
#[structopt(name = "kill", help("kill the eww daemon"))]
|
||||||
KillServer,
|
KillServer,
|
||||||
|
|
||||||
#[structopt(name = "state", help = "Print the current eww-state")]
|
#[structopt(name = "state", help = "Print the current eww-state")]
|
||||||
|
@ -111,18 +127,18 @@ pub enum OptAction {
|
||||||
ShowDebug,
|
ShowDebug,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OptAction {
|
impl OptActionWithServer {
|
||||||
fn into_eww_command(self) -> (app::EwwCommand, Option<crossbeam_channel::Receiver<String>>) {
|
fn into_eww_command(self) -> (app::EwwCommand, Option<crossbeam_channel::Receiver<String>>) {
|
||||||
let command = match self {
|
let command = match self {
|
||||||
OptAction::Update { fieldname, value } => app::EwwCommand::UpdateVar(fieldname, value),
|
OptActionWithServer::Update { fieldname, value } => app::EwwCommand::UpdateVar(fieldname, value),
|
||||||
OptAction::OpenWindow { window_name, pos, size } => app::EwwCommand::OpenWindow { window_name, pos, size },
|
OptActionWithServer::OpenWindow { window_name, pos, size } => app::EwwCommand::OpenWindow { window_name, pos, size },
|
||||||
OptAction::CloseWindow { window_name } => app::EwwCommand::CloseWindow { window_name },
|
OptActionWithServer::CloseWindow { window_name } => app::EwwCommand::CloseWindow { window_name },
|
||||||
OptAction::KillServer => app::EwwCommand::KillServer,
|
OptActionWithServer::KillServer => app::EwwCommand::KillServer,
|
||||||
OptAction::ShowState => {
|
OptActionWithServer::ShowState => {
|
||||||
let (send, recv) = crossbeam_channel::unbounded();
|
let (send, recv) = crossbeam_channel::unbounded();
|
||||||
return (app::EwwCommand::PrintState(send), Some(recv));
|
return (app::EwwCommand::PrintState(send), Some(recv));
|
||||||
}
|
}
|
||||||
OptAction::ShowDebug => {
|
OptActionWithServer::ShowDebug => {
|
||||||
let (send, recv) = crossbeam_channel::unbounded();
|
let (send, recv) = crossbeam_channel::unbounded();
|
||||||
return (app::EwwCommand::PrintDebug(send), Some(recv));
|
return (app::EwwCommand::PrintDebug(send), Some(recv));
|
||||||
}
|
}
|
||||||
|
@ -130,41 +146,63 @@ impl OptAction {
|
||||||
(command, None)
|
(command, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_server_command(&self) -> bool {
|
/// returns true if this command requires a server to already be running
|
||||||
|
fn needs_server_running(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
OptAction::OpenWindow { .. } => true,
|
OptActionWithServer::OpenWindow { .. } => false,
|
||||||
_ => false,
|
_ => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_main() -> Result<()> {
|
fn try_main() -> Result<()> {
|
||||||
let opts: Opt = StructOpt::from_args();
|
let opts: Opt = StructOpt::from_args();
|
||||||
log::info!("Trying to find server process");
|
|
||||||
if let Ok(mut stream) = net::UnixStream::connect(&*IPC_SOCKET_PATH) {
|
|
||||||
log::info!("Forwarding options to server");
|
|
||||||
stream.write_all(&bincode::serialize(&opts)?)?;
|
|
||||||
|
|
||||||
let mut buf = String::new();
|
match opts.action {
|
||||||
stream.set_read_timeout(Some(std::time::Duration::from_millis(100)))?;
|
OptAction::ClientOnly(action) => {
|
||||||
stream.read_to_string(&mut buf)?;
|
handle_client_only_action(action)?;
|
||||||
println!("{}", buf);
|
|
||||||
} else {
|
|
||||||
log::info!("No instance found... Initializing server.");
|
|
||||||
|
|
||||||
let _ = std::fs::remove_file(&*IPC_SOCKET_PATH);
|
|
||||||
|
|
||||||
if opts.should_detach {
|
|
||||||
do_detach()?;
|
|
||||||
}
|
}
|
||||||
|
OptAction::WithServer(action) => {
|
||||||
|
log::info!("Trying to find server process");
|
||||||
|
if let Ok(mut stream) = net::UnixStream::connect(&*IPC_SOCKET_PATH) {
|
||||||
|
log::info!("Forwarding options to server");
|
||||||
|
stream.write_all(&bincode::serialize(&action)?)?;
|
||||||
|
|
||||||
initialize_server(opts)?;
|
let mut buf = String::new();
|
||||||
|
stream.set_read_timeout(Some(std::time::Duration::from_millis(100)))?;
|
||||||
|
stream.read_to_string(&mut buf)?;
|
||||||
|
println!("{}", buf);
|
||||||
|
} else {
|
||||||
|
log::info!("No instance found... Initializing server.");
|
||||||
|
|
||||||
|
let _ = std::fs::remove_file(&*IPC_SOCKET_PATH);
|
||||||
|
|
||||||
|
if opts.should_detach {
|
||||||
|
do_detach()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize_server(action)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_server(opts: Opt) -> Result<()> {
|
fn handle_client_only_action(action: OptActionClientOnly) -> Result<()> {
|
||||||
if !opts.action.is_server_command() {
|
match action {
|
||||||
|
OptActionClientOnly::Logs => {
|
||||||
|
std::process::Command::new("tail")
|
||||||
|
.args(["-f", LOG_FILE.to_string_lossy().as_ref()].iter())
|
||||||
|
.stdin(Stdio::null())
|
||||||
|
.spawn()?
|
||||||
|
.wait()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initialize_server(action: OptActionWithServer) -> Result<()> {
|
||||||
|
if action.needs_server_running() {
|
||||||
println!("No eww server running");
|
println!("No eww server running");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -205,8 +243,8 @@ fn initialize_server(opts: Opt) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// run the command that eww was started with
|
// run the command that eww was started with
|
||||||
log::info!("running command: {:?}", &opts.action);
|
log::info!("running command: {:?}", &action);
|
||||||
let (command, maybe_response_recv) = opts.action.into_eww_command();
|
let (command, maybe_response_recv) = action.into_eww_command();
|
||||||
app.handle_command(command);
|
app.handle_command(command);
|
||||||
if let Some(response_recv) = maybe_response_recv {
|
if let Some(response_recv) = maybe_response_recv {
|
||||||
if let Ok(response) = response_recv.recv_timeout(std::time::Duration::from_millis(100)) {
|
if let Ok(response) = response_recv.recv_timeout(std::time::Duration::from_millis(100)) {
|
||||||
|
@ -235,9 +273,9 @@ fn run_server_thread(evt_send: glib::Sender<app::EwwCommand>) -> Result<()> {
|
||||||
for stream in listener.incoming() {
|
for stream in listener.incoming() {
|
||||||
try_logging_errors!("handling message from IPC client" => {
|
try_logging_errors!("handling message from IPC client" => {
|
||||||
let mut stream = stream?;
|
let mut stream = stream?;
|
||||||
let opts: Opt = bincode::deserialize_from(&stream)?;
|
let action: OptActionWithServer = bincode::deserialize_from(&stream)?;
|
||||||
log::info!("received command from IPC: {:?}", &opts);
|
log::info!("received command from IPC: {:?}", &action);
|
||||||
let (command, maybe_response_recv) = opts.action.into_eww_command();
|
let (command, maybe_response_recv) = action.into_eww_command();
|
||||||
evt_send.send(command)?;
|
evt_send.send(command)?;
|
||||||
if let Some(response_recv) = maybe_response_recv {
|
if let Some(response_recv) = maybe_response_recv {
|
||||||
if let Ok(response) = response_recv.recv_timeout(std::time::Duration::from_millis(100)) {
|
if let Ok(response) = response_recv.recv_timeout(std::time::Duration::from_millis(100)) {
|
||||||
|
@ -295,8 +333,6 @@ fn do_detach() -> Result<()> {
|
||||||
nix::unistd::ForkResult::Child => {}
|
nix::unistd::ForkResult::Child => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
nix::unistd::setsid().context("Failed to run setsid")?;
|
|
||||||
|
|
||||||
let file = std::fs::OpenOptions::new()
|
let file = std::fs::OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
.append(true)
|
.append(true)
|
||||||
|
@ -313,6 +349,8 @@ fn do_detach() -> Result<()> {
|
||||||
if nix::unistd::isatty(2)? {
|
if nix::unistd::isatty(2)? {
|
||||||
nix::unistd::dup2(std::io::stderr().as_raw_fd(), fd)?;
|
nix::unistd::dup2(std::io::stderr().as_raw_fd(), fd)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nix::unistd::setsid().context("Failed to run setsid")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -219,7 +219,7 @@ fn build_gtk_scale(bargs: &mut BuilderArgs) -> Result<gtk::Scale> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @widget input
|
/// @widget input
|
||||||
/// @desc an input field that doesn't yet really work
|
/// @desc an input field. For this to be useful, set `focusable="true"` on the window.
|
||||||
fn build_gtk_input(bargs: &mut BuilderArgs) -> Result<gtk::Entry> {
|
fn build_gtk_input(bargs: &mut BuilderArgs) -> Result<gtk::Entry> {
|
||||||
let gtk_widget = gtk::Entry::new();
|
let gtk_widget = gtk::Entry::new();
|
||||||
let on_change_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
let on_change_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
||||||
|
|
Loading…
Add table
Reference in a new issue