From 0b900861cb772c6083db8bfdc3589489e6b10476 Mon Sep 17 00:00:00 2001 From: elkowar <5300871+elkowar@users.noreply.github.com> Date: Mon, 7 Dec 2020 18:18:58 +0100 Subject: [PATCH] Add daemon subcommand (fixes #69) --- src/app.rs | 2 ++ src/config/eww_config.rs | 1 + src/main.rs | 3 +-- src/opts.rs | 44 ++++++++++++++++++++++++++----- src/widgets/widget_definitions.rs | 2 +- 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/app.rs b/src/app.rs index b680f38..864fe39 100644 --- a/src/app.rs +++ b/src/app.rs @@ -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)?; diff --git a/src/config/eww_config.rs b/src/config/eww_config.rs index 9ee96b2..52f8abb 100644 --- a/src/config/eww_config.rs +++ b/src/config/eww_config.rs @@ -26,6 +26,7 @@ pub struct EwwConfig { impl EwwConfig { pub fn merge_includes(mut eww_config: EwwConfig, includes: Vec) -> Result { + // TODO issue warnings on conflict for config in includes { eww_config.widgets.extend(config.widgets); eww_config.windows.extend(config.windows); diff --git a/src/main.rs b/src/main.rs index 8f7668c..b0d5f7b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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) => { diff --git a/src/opts.rs b/src/opts.rs index 841c418..0863150 100644 --- a/src/opts.rs +++ b/src/opts.rs @@ -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, /// 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 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>) { 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, } } diff --git a/src/widgets/widget_definitions.rs b/src/widgets/widget_definitions.rs index 04fd3ed..5623584 100644 --- a/src/widgets/widget_definitions.rs +++ b/src/widgets/widget_definitions.rs @@ -375,7 +375,7 @@ fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result { } /// @widget calendar -/// @widget A widget that displays a calendar +/// @desc A widget that displays a calendar fn build_gtk_calendar(bargs: &mut BuilderArgs) -> Result { let gtk_widget = gtk::Calendar::new(); let on_click_handler_id: Rc>> = Rc::new(RefCell::new(None));