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

View file

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

View file

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

View file

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

View file

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