Add daemon subcommand (fixes #69)

This commit is contained in:
elkowar 2020-12-07 18:18:58 +01:00
parent 0e97847a3a
commit 0b900861cb
5 changed files with 43 additions and 9 deletions

View file

@ -15,6 +15,7 @@ use std::collections::{HashMap, HashSet};
#[derive(Debug)]
pub enum EwwCommand {
NoOp,
UpdateVars(Vec<(VarName, PrimitiveValue)>),
ReloadConfig(config::EwwConfig),
ReloadCss(String),
@ -61,6 +62,7 @@ impl App {
log::debug!("Handling event: {:?}", &event);
let result: Result<_> = try {
match event {
EwwCommand::NoOp => {}
EwwCommand::UpdateVars(mappings) => {
for (var_name, new_value) in mappings {
self.update_state(var_name, new_value)?;

View file

@ -26,6 +26,7 @@ pub struct EwwConfig {
impl EwwConfig {
pub fn merge_includes(mut eww_config: EwwConfig, includes: Vec<EwwConfig>) -> Result<EwwConfig> {
// TODO issue warnings on conflict
for config in includes {
eww_config.widgets.extend(config.widgets);
eww_config.windows.extend(config.windows);

View file

@ -11,7 +11,6 @@ extern crate gtk;
use anyhow::*;
use std::{os::unix::net, path::PathBuf};
use structopt::StructOpt;
pub mod app;
pub mod client;
@ -45,7 +44,7 @@ fn main() {
pretty_env_logger::init();
let result: Result<_> = try {
let opts: opts::Opt = StructOpt::from_args();
let opts: opts::Opt = opts::Opt::from_env();
match opts.action {
opts::Action::ClientOnly(action) => {

View file

@ -8,21 +8,30 @@ use crate::{
value::{Coords, PrimitiveValue, VarName},
};
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Opt {
#[structopt(subcommand)]
pub action: Action,
pub should_detach: bool,
}
/// Helper struct that will be normalized into instance of [Opt]
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
struct RawOpt {
#[structopt(subcommand)]
action: Option<Action>,
/// Run Eww in the background, daemonizing it.
/// When daemonized, to kill eww you can run `eww kill`. To see logs, use `eww logs`.
#[structopt(short = "-d", long = "--detach")]
pub should_detach: bool,
should_detach: bool,
}
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq, smart_default::SmartDefault)]
pub enum Action {
#[structopt(flatten)]
ClientOnly(ActionClientOnly),
#[default]
#[structopt(flatten)]
WithServer(ActionWithServer),
}
@ -34,8 +43,12 @@ pub enum ActionClientOnly {
Logs,
}
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq, smart_default::SmartDefault)]
pub enum ActionWithServer {
#[structopt(name = "daemon")]
#[default]
Daemon,
/// Update the value of a variable, in a running eww instance
#[structopt(name = "update")]
Update {
@ -83,6 +96,24 @@ pub enum ActionWithServer {
ShowDebug,
}
impl Opt {
pub fn from_env() -> Self {
let raw: RawOpt = StructOpt::from_args();
raw.into()
}
}
impl From<RawOpt> for Opt {
fn from(other: RawOpt) -> Self {
let RawOpt { action, should_detach } = other;
let action = action.unwrap_or_default();
Opt {
should_detach: should_detach || action == Action::WithServer(ActionWithServer::Daemon),
action,
}
}
}
fn parse_var_update_arg(s: &str) -> Result<(VarName, PrimitiveValue)> {
let (name, value) = s
.split_once('=')
@ -93,6 +124,7 @@ fn parse_var_update_arg(s: &str) -> Result<(VarName, PrimitiveValue)> {
impl ActionWithServer {
pub fn into_eww_command(self) -> (app::EwwCommand, Option<crossbeam_channel::Receiver<String>>) {
let command = match self {
ActionWithServer::Daemon => app::EwwCommand::NoOp,
ActionWithServer::Update { mappings } => app::EwwCommand::UpdateVars(mappings.into_iter().collect()),
ActionWithServer::OpenWindow {
window_name,
@ -122,7 +154,7 @@ impl ActionWithServer {
/// returns true if this command requires a server to already be running
pub fn needs_server_running(&self) -> bool {
match self {
ActionWithServer::OpenWindow { .. } => false,
ActionWithServer::OpenWindow { .. } | ActionWithServer::Daemon => false,
_ => true,
}
}

View file

@ -375,7 +375,7 @@ fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result<gtk::Frame> {
}
/// @widget calendar
/// @widget A widget that displays a calendar
/// @desc A widget that displays a calendar
fn build_gtk_calendar(bargs: &mut BuilderArgs) -> Result<gtk::Calendar> {
let gtk_widget = gtk::Calendar::new();
let on_click_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));