Implement multiple value update, breakign syntax of eww update (#51)

This commit is contained in:
ElKowar 2020-10-30 22:12:21 +01:00 committed by GitHub
parent c8ff2ce4f4
commit 0f68a76507
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 40 deletions

View file

@ -18,7 +18,7 @@ use std::collections::HashMap;
#[derive(Debug)] #[derive(Debug)]
pub enum EwwCommand { pub enum EwwCommand {
UpdateVar(VarName, PrimitiveValue), UpdateVars(Vec<(VarName, PrimitiveValue)>),
ReloadConfig(config::EwwConfig), ReloadConfig(config::EwwConfig),
ReloadCss(String), ReloadCss(String),
OpenWindow { OpenWindow {
@ -55,31 +55,45 @@ pub struct App {
impl App { impl App {
pub fn handle_command(&mut self, event: EwwCommand) { pub fn handle_command(&mut self, event: EwwCommand) {
log::debug!("Handling event: {:?}", &event); log::debug!("Handling event: {:?}", &event);
let result: Result<_> = match event { let result: Result<_> = try {
EwwCommand::UpdateVar(key, value) => self.update_state(key, value), match event {
EwwCommand::ReloadConfig(config) => self.reload_all_windows(config), EwwCommand::UpdateVars(mappings) => {
EwwCommand::ReloadCss(css) => self.load_css(&css), for (var_name, new_value) in mappings {
EwwCommand::KillServer => { self.update_state(var_name, new_value)?;
log::info!("Received kill command, stopping server!"); }
self.script_var_handler.stop(); }
self.windows.values().for_each(|w| w.gtk_window.close()); EwwCommand::ReloadConfig(config) => {
script_var_process::on_application_death(); self.reload_all_windows(config)?;
std::process::exit(0); }
} EwwCommand::ReloadCss(css) => {
EwwCommand::OpenWindow { window_name, pos, size } => self.open_window(&window_name, pos, size), self.load_css(&css)?;
EwwCommand::CloseWindow { window_name } => self.close_window(&window_name), }
EwwCommand::PrintState(sender) => { EwwCommand::KillServer => {
let output = self log::info!("Received kill command, stopping server!");
.eww_state self.script_var_handler.stop();
.get_variables() self.windows.values().for_each(|w| w.gtk_window.close());
.iter() script_var_process::on_application_death();
.map(|(key, value)| format!("{}: {}", key, value)) std::process::exit(0);
.join("\n"); }
sender.send(output).context("sending response from main thread") EwwCommand::OpenWindow { window_name, pos, size } => {
} self.open_window(&window_name, pos, size)?;
EwwCommand::PrintDebug(sender) => { }
let output = format!("state: {:#?}\n\nconfig: {:#?}", &self.eww_state, &self.eww_config); EwwCommand::CloseWindow { window_name } => {
sender.send(output).context("sending response from main thread") self.close_window(&window_name)?;
}
EwwCommand::PrintState(sender) => {
let output = self
.eww_state
.get_variables()
.iter()
.map(|(key, value)| format!("{}: {}", key, value))
.join("\n");
sender.send(output).context("sending response from main thread")?
}
EwwCommand::PrintDebug(sender) => {
let output = format!("state: {:#?}\n\nconfig: {:#?}", &self.eww_state, &self.eww_config);
sender.send(output).context("sending response from main thread")?
}
} }
}; };

View file

@ -1,3 +1,4 @@
use anyhow::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use structopt::StructOpt; use structopt::StructOpt;
@ -12,6 +13,8 @@ pub struct Opt {
#[structopt(subcommand)] #[structopt(subcommand)]
pub action: Action, pub action: 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")] #[structopt(short = "-d", long = "--detach")]
pub should_detach: bool, pub should_detach: bool,
} }
@ -26,43 +29,69 @@ pub enum Action {
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)] #[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
pub enum ActionClientOnly { pub enum ActionClientOnly {
#[structopt(name = "logs", help = "Print and watch the eww logs")] /// Print and watch the eww logs
#[structopt(name = "logs")]
Logs, Logs,
} }
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)] #[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
pub enum ActionWithServer { pub enum ActionWithServer {
#[structopt(name = "update", help = "update the value of a variable, in a running eww instance")] /// Update the value of a variable, in a running eww instance
Update { fieldname: VarName, value: PrimitiveValue }, #[structopt(name = "update")]
Update {
/// variable_name="new_value"-pairs that will be updated
#[structopt(parse(try_from_str = parse_var_update_arg))]
mappings: Vec<(VarName, PrimitiveValue)>,
},
#[structopt(name = "open", help = "open a window")] /// open a window
#[structopt(name = "open")]
OpenWindow { OpenWindow {
/// Name of the window you want to open.
window_name: WindowName, window_name: WindowName,
#[structopt(short, long, help = "The position of the window, where it should open.")] /// The position of the window, where it should open.
#[structopt(short, long)]
pos: Option<Coords>, pos: Option<Coords>,
#[structopt(short, long, help = "The size of the window to open")] /// The size of the window to open
#[structopt(short, long)]
size: Option<Coords>, size: Option<Coords>,
}, },
#[structopt(name = "close", help = "close the window with the given name")] /// Close the window with the given name
#[structopt(name = "close")]
CloseWindow { window_name: WindowName }, CloseWindow { window_name: WindowName },
#[structopt(name = "kill", help("kill the eww daemon"))] /// kill the eww daemon
#[structopt(name = "kill")]
KillServer, KillServer,
#[structopt(name = "state", help = "Print the current eww-state")] /// Print the current eww-state
#[structopt(name = "state")]
ShowState, ShowState,
#[structopt(name = "debug", help = "Print out the widget structure as seen by eww")] /// Print out the widget structure as seen by eww.
///
/// This may be useful if you are facing issues with how eww is interpreting your configuration,
/// and to provide additional context to the eww developers if you are filing a bug.
#[structopt(name = "debug")]
ShowDebug, ShowDebug,
} }
fn parse_var_update_arg(s: &str) -> Result<(VarName, PrimitiveValue)> {
let (name, value) = s
.split_once('=')
.with_context(|| format!("arguments must be in the shape `variable_name=\"new_value\"`, but got: {}", s))?;
Ok((name.into(), PrimitiveValue::from_string(value.to_owned())))
}
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::Update { fieldname, value } => app::EwwCommand::UpdateVar(fieldname, value), ActionWithServer::Update { mappings } => {
app::EwwCommand::UpdateVars(mappings.into_iter().map(|x| x.into()).collect())
}
ActionWithServer::OpenWindow { window_name, pos, size } => app::EwwCommand::OpenWindow { window_name, pos, size }, ActionWithServer::OpenWindow { window_name, pos, size } => app::EwwCommand::OpenWindow { window_name, pos, size },
ActionWithServer::CloseWindow { window_name } => app::EwwCommand::CloseWindow { window_name }, ActionWithServer::CloseWindow { window_name } => app::EwwCommand::CloseWindow { window_name },
ActionWithServer::KillServer => app::EwwCommand::KillServer, ActionWithServer::KillServer => app::EwwCommand::KillServer,

View file

@ -70,7 +70,7 @@ impl ScriptVarHandler {
var.interval, var.interval,
glib::clone!(@strong var, @strong evt_send => move |_| { glib::clone!(@strong var, @strong evt_send => move |_| {
let result: Result<_> = try { let result: Result<_> = try {
evt_send.send(app::EwwCommand::UpdateVar(var.name.clone(), var.run_once()?))?; evt_send.send(app::EwwCommand::UpdateVars(vec![(var.name.clone(), var.run_once()?)]))?;
}; };
util::print_result_err("while running script-var command", &result); util::print_result_err("while running script-var command", &result);
}), }),
@ -112,10 +112,10 @@ impl ScriptVarHandler {
.with_context(|| format!("No command output handle found for variable '{}'", var_name))?; .with_context(|| format!("No command output handle found for variable '{}'", var_name))?;
let mut buffer = String::new(); let mut buffer = String::new();
handle.stdout_reader.read_line(&mut buffer)?; handle.stdout_reader.read_line(&mut buffer)?;
evt_send.send(EwwCommand::UpdateVar( evt_send.send(EwwCommand::UpdateVars(vec![(
var_name.to_owned(), var_name.to_owned(),
PrimitiveValue::from_string(buffer.trim_matches('\n').to_owned()), PrimitiveValue::from_string(buffer.trim_matches('\n').to_owned()),
))?; )]))?;
} else if event.hangup { } else if event.hangup {
script_var_processes.remove(var_name); script_var_processes.remove(var_name);
sources.unregister(var_name); sources.unregister(var_name);