Fix script-vars being ran without window using them, and add debug flag. fixes #94.
This commit is contained in:
parent
23db60508e
commit
6c2e0dbbc1
5 changed files with 62 additions and 46 deletions
|
@ -30,8 +30,8 @@ If none of these fixed your problem [open an issue on the GitHub repo.](https://
|
||||||
|
|
||||||
You should try the following things, before opening a issue or doing more specialized troubleshooting:
|
You should try the following things, before opening a issue or doing more specialized troubleshooting:
|
||||||
|
|
||||||
- Try killing the eww daemon with `eww kill` and run again
|
- Kill the eww daemon by running `eww kill` and restart it with `eww --debug daemon` to get additional log output.
|
||||||
- If you're running with `-d`, run without `-d` to see output, or run `eww logs` to see the logs written by eww. These logs are stored in `~/.cache/eww.log`.
|
- Now you can take a look at the logs by running `eww logs`.
|
||||||
- use `eww state`, to see the state of all variables
|
- use `eww state`, to see the state of all variables
|
||||||
- use `eww debug`, to see the xml of your widget and other information
|
- use `eww debug`, to see the xml of your widget and other information
|
||||||
- update to the latest eww version
|
- update to the latest eww version
|
||||||
|
@ -42,4 +42,4 @@ If you're experiencing issues printing variables, try to print them in quotes, s
|
||||||
onchange="notify-send '{}'"
|
onchange="notify-send '{}'"
|
||||||
```
|
```
|
||||||
|
|
||||||
Remember if your issue isn't listed here, [open an issue on the GitHub repo](https://github.com/elkowar/eww/issues).
|
Remember, if your issue isn't listed here, [open an issue on the GitHub repo](https://github.com/elkowar/eww/issues).
|
||||||
|
|
74
src/app.rs
74
src/app.rs
|
@ -11,7 +11,7 @@ use debug_stub_derive::*;
|
||||||
use gdk::WindowExt;
|
use gdk::WindowExt;
|
||||||
use gtk::{ContainerExt, CssProviderExt, GtkWindowExt, StyleContextExt, WidgetExt};
|
use gtk::{ContainerExt, CssProviderExt, GtkWindowExt, StyleContextExt, WidgetExt};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::HashMap;
|
||||||
use tokio::sync::mpsc::UnboundedSender;
|
use tokio::sync::mpsc::UnboundedSender;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -135,25 +135,16 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_window(&mut self, window_name: &WindowName) -> Result<()> {
|
fn close_window(&mut self, window_name: &WindowName) -> Result<()> {
|
||||||
|
for unused_var in self.variables_only_used_in(&window_name) {
|
||||||
|
log::info!("stopping for {}", &unused_var);
|
||||||
|
self.script_var_handler.stop_for_variable(unused_var.clone());
|
||||||
|
}
|
||||||
|
|
||||||
let window = self
|
let window = self
|
||||||
.windows
|
.windows
|
||||||
.remove(window_name)
|
.remove(window_name)
|
||||||
.context(format!("No window with name '{}' is running.", window_name))?;
|
.context(format!("No window with name '{}' is running.", window_name))?;
|
||||||
|
|
||||||
// Stop script-var handlers for variables that where only referenced by this window
|
|
||||||
// TODO somehow make this whole process less shit.
|
|
||||||
let currently_used_vars = self.get_currently_used_variables().cloned().collect::<HashSet<VarName>>();
|
|
||||||
|
|
||||||
for unused_var in self
|
|
||||||
.eww_state
|
|
||||||
.vars_referenced_in(window_name)
|
|
||||||
.into_iter()
|
|
||||||
.filter(|var| !currently_used_vars.contains(*var))
|
|
||||||
{
|
|
||||||
println!("stopping for {}", &unused_var);
|
|
||||||
self.script_var_handler.stop_for_variable(unused_var.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
window.close();
|
window.close();
|
||||||
self.eww_state.clear_window_state(window_name);
|
self.eww_state.clear_window_state(window_name);
|
||||||
|
|
||||||
|
@ -172,10 +163,6 @@ impl App {
|
||||||
|
|
||||||
log::info!("Opening window {}", window_name);
|
log::info!("Opening window {}", window_name);
|
||||||
|
|
||||||
// remember which variables are used before opening the window, to then
|
|
||||||
// set up the necessary handlers for the newly used variables.
|
|
||||||
let currently_used_vars = self.get_currently_used_variables().cloned().collect::<HashSet<_>>();
|
|
||||||
|
|
||||||
let mut window_def = self.eww_config.get_window(window_name)?.clone();
|
let mut window_def = self.eww_config.get_window(window_name)?.clone();
|
||||||
window_def.geometry = window_def.geometry.override_if_given(anchor, pos, size);
|
window_def.geometry = window_def.geometry.override_if_given(anchor, pos, size);
|
||||||
|
|
||||||
|
@ -191,25 +178,16 @@ impl App {
|
||||||
let monitor_geometry = get_monitor_geometry(window_def.screen_number.unwrap_or_else(get_default_monitor_index));
|
let monitor_geometry = get_monitor_geometry(window_def.screen_number.unwrap_or_else(get_default_monitor_index));
|
||||||
let eww_window = initialize_window(monitor_geometry, root_widget, window_def)?;
|
let eww_window = initialize_window(monitor_geometry, root_widget, window_def)?;
|
||||||
|
|
||||||
|
self.windows.insert(window_name.clone(), eww_window);
|
||||||
|
|
||||||
// initialize script var handlers for variables that where not used before opening this window.
|
// initialize script var handlers for variables that where not used before opening this window.
|
||||||
// TODO somehow make this less shit
|
// TODO somehow make this less shit
|
||||||
let newly_used_vars = self
|
for newly_used_var in self
|
||||||
.eww_state
|
.variables_only_used_in(&window_name)
|
||||||
.vars_referenced_in(window_name)
|
.filter_map(|var| self.eww_config.get_script_var(&var))
|
||||||
.into_iter()
|
{
|
||||||
.filter(|x| !currently_used_vars.contains(*x))
|
self.script_var_handler.add(newly_used_var.clone());
|
||||||
.collect_vec()
|
|
||||||
.clone();
|
|
||||||
|
|
||||||
// TODO all of the cloning above is highly ugly.... REEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
|
|
||||||
for newly_used_var in newly_used_vars {
|
|
||||||
let value = self.eww_config.get_script_var(&newly_used_var);
|
|
||||||
if let Some(value) = value {
|
|
||||||
self.script_var_handler.add(value.clone());
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
self.windows.insert(window_name.clone(), eww_window);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -235,8 +213,32 @@ impl App {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get all variable names that are currently referenced in any of the open windows.
|
||||||
pub fn get_currently_used_variables(&self) -> impl Iterator<Item = &VarName> {
|
pub fn get_currently_used_variables(&self) -> impl Iterator<Item = &VarName> {
|
||||||
self.eww_state.referenced_vars()
|
self.windows
|
||||||
|
.keys()
|
||||||
|
.flat_map(move |window_name| self.eww_state.vars_referenced_in(window_name))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get all variables mapped to a list of windows they are being used in.
|
||||||
|
pub fn currently_used_variables<'a>(&'a self) -> HashMap<&'a VarName, Vec<&'a WindowName>> {
|
||||||
|
let mut vars: HashMap<&'a VarName, Vec<_>> = HashMap::new();
|
||||||
|
for window_name in self.windows.keys() {
|
||||||
|
for var in self.eww_state.vars_referenced_in(window_name) {
|
||||||
|
vars.entry(var)
|
||||||
|
.and_modify(|l| l.push(window_name))
|
||||||
|
.or_insert_with(|| vec![window_name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vars
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get all variables that are only used in the given window.
|
||||||
|
pub fn variables_only_used_in<'a>(&'a self, window: &'a WindowName) -> impl Iterator<Item = &'a VarName> {
|
||||||
|
self.currently_used_variables()
|
||||||
|
.into_iter()
|
||||||
|
.filter(move |(_, wins)| wins.len() == 1 && wins.contains(&window))
|
||||||
|
.map(|(var, _)| var)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -43,11 +43,19 @@ lazy_static::lazy_static! {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
pretty_env_logger::init();
|
|
||||||
|
|
||||||
let result: Result<_> = try {
|
|
||||||
let opts: opts::Opt = opts::Opt::from_env();
|
let opts: opts::Opt = opts::Opt::from_env();
|
||||||
|
|
||||||
|
let log_level_filter = if opts.log_debug {
|
||||||
|
log::LevelFilter::Debug
|
||||||
|
} else {
|
||||||
|
log::LevelFilter::Off
|
||||||
|
};
|
||||||
|
|
||||||
|
pretty_env_logger::formatted_builder()
|
||||||
|
.filter(Some("eww"), log_level_filter)
|
||||||
|
.init();
|
||||||
|
|
||||||
|
let result: Result<_> = try {
|
||||||
match opts.action {
|
match opts.action {
|
||||||
opts::Action::ClientOnly(action) => {
|
opts::Action::ClientOnly(action) => {
|
||||||
client::handle_client_only_action(action)?;
|
client::handle_client_only_action(action)?;
|
||||||
|
|
11
src/opts.rs
11
src/opts.rs
|
@ -8,14 +8,19 @@ use crate::{
|
||||||
value::{Coords, PrimitiveValue, VarName},
|
value::{Coords, PrimitiveValue, VarName},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Struct that gets generated from `RawOpt`.
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct Opt {
|
pub struct Opt {
|
||||||
|
pub log_debug: bool,
|
||||||
pub action: Action,
|
pub action: Action,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper struct that will be normalized into instance of [Opt]
|
|
||||||
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
struct RawOpt {
|
struct RawOpt {
|
||||||
|
/// Write out debug logs. (To read the logs, run `eww logs`).
|
||||||
|
#[structopt(long = "debug")]
|
||||||
|
log_debug: bool,
|
||||||
|
|
||||||
#[structopt(subcommand)]
|
#[structopt(subcommand)]
|
||||||
action: Action,
|
action: Action,
|
||||||
}
|
}
|
||||||
|
@ -111,8 +116,8 @@ impl Opt {
|
||||||
|
|
||||||
impl From<RawOpt> for Opt {
|
impl From<RawOpt> for Opt {
|
||||||
fn from(other: RawOpt) -> Self {
|
fn from(other: RawOpt) -> Self {
|
||||||
let RawOpt { action } = other;
|
let RawOpt { action, log_debug } = other;
|
||||||
Opt { action }
|
Opt { action, log_debug }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,7 @@ fn init_async_part(config_file_path: PathBuf, scss_file_path: PathBuf, ui_send:
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
// Wait for application exit event
|
// Wait for application exit event
|
||||||
let _ = crate::application_lifecycle::recv_exit().await;
|
let _ = crate::application_lifecycle::recv_exit().await;
|
||||||
|
log::info!("Forward task received exit event");
|
||||||
// Then forward that to the application
|
// Then forward that to the application
|
||||||
let _ = ui_send.send(app::EwwCommand::KillServer);
|
let _ = ui_send.send(app::EwwCommand::KillServer);
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue