diff --git a/docs/modules/Custom.md b/docs/modules/Custom.md index 6596b16..9a04381 100644 --- a/docs/modules/Custom.md +++ b/docs/modules/Custom.md @@ -61,10 +61,10 @@ An image or icon from disk or http. > Type `image` -| Name | Type | Default | Description | -|--------|-----------|---------|-------------------------------------------------------------| -| `src` | `image` | `null` | Image source. See [here](images) for information on images. | -| `size` | `integer` | `null` | Width/height of the image. Aspect ratio is preserved. | +| Name | Type | Default | Description | +|--------|-----------|---------|---------------------------------------------------------------------------------------------| +| `src` | `image` | `null` | Image source. See [here](images) for information on images. Embedded scripts are supported. | +| `size` | `integer` | `null` | Width/height of the image. Aspect ratio is preserved. | #### Slider @@ -130,7 +130,7 @@ $progress = { bar = [ { type = "progress" - value = "500:mpc | sed -n 2p | awk '{ print $4 }' | grep -Eo '[0-9]+'" + value = "500:mpc | sed -n 2p | awk '{ print $4 }' | grep -Eo '[0-9]+' || echo 0" label = "{{500:mpc | sed -n 2p | awk '{ print $3 }'}} elapsed" length = 200 } diff --git a/src/image/provider.rs b/src/image/provider.rs index 9c5eb88..9fa40f7 100644 --- a/src/image/provider.rs +++ b/src/image/provider.rs @@ -193,7 +193,16 @@ impl<'a> ImageProvider<'a> { /// Attempts to get `Bytes` from an HTTP resource asynchronously. #[cfg(feature = "http")] async fn get_bytes_from_http(url: reqwest::Url) -> Result { - let bytes = reqwest::get(url).await?.bytes().await?; - Ok(glib::Bytes::from_owned(bytes)) + let res = reqwest::get(url).await?; + + let status = res.status(); + if status.is_success() { + let bytes = res.bytes().await?; + Ok(glib::Bytes::from_owned(bytes)) + } else { + Err(Report::msg(format!( + "Received non-success HTTP code ({status})" + ))) + } } } diff --git a/src/modules/custom/box.rs b/src/modules/custom/box.rs index af541e6..13a6781 100644 --- a/src/modules/custom/box.rs +++ b/src/modules/custom/box.rs @@ -21,7 +21,7 @@ impl CustomWidget for BoxWidget { if let Some(orientation) = self.orientation { container.set_orientation( try_get_orientation(&orientation).unwrap_or(Orientation::Horizontal), - ) + ); } if let Some(widgets) = self.widgets { diff --git a/src/modules/custom/image.rs b/src/modules/custom/image.rs index 715bad0..6e98d15 100644 --- a/src/modules/custom/image.rs +++ b/src/modules/custom/image.rs @@ -1,5 +1,6 @@ use super::{CustomWidget, CustomWidgetContext}; use crate::build; +use crate::dynamic_string::DynamicString; use crate::image::ImageProvider; use gtk::prelude::*; use gtk::Image; @@ -10,8 +11,13 @@ use tracing::error; pub struct ImageWidget { name: Option, class: Option, - src: Option, - size: Option, + src: String, + #[serde(default = "default_size")] + size: i32, +} + +const fn default_size() -> i32 { + 32 } impl CustomWidget for ImageWidget { @@ -20,13 +26,20 @@ impl CustomWidget for ImageWidget { fn into_widget(self, context: CustomWidgetContext) -> Self::Widget { let gtk_image = build!(self, Self::Widget); - if let Some(src) = self.src { - let size = self.size.unwrap_or(32); - if let Err(err) = ImageProvider::parse(&src, context.icon_theme, size) - .and_then(|image| image.load_into_image(gtk_image.clone())) - { - error!("{err:?}"); - } + { + let gtk_image = gtk_image.clone(); + let icon_theme = context.icon_theme.clone(); + + DynamicString::new(&self.src, move |src| { + let res = ImageProvider::parse(&src, &icon_theme, self.size) + .and_then(|image| image.load_into_image(gtk_image.clone())); + + if let Err(err) = res { + error!("{err:?}"); + } + + Continue(true) + }); } gtk_image diff --git a/src/modules/custom/mod.rs b/src/modules/custom/mod.rs index 1ba97a6..5c9bfb5 100644 --- a/src/modules/custom/mod.rs +++ b/src/modules/custom/mod.rs @@ -109,12 +109,12 @@ impl Widget { /// Creates this widget and adds it to the parent container fn add_to(self, parent: >k::Box, context: CustomWidgetContext) { match self { - Widget::Box(widget) => parent.add(&widget.into_widget(context)), - Widget::Label(widget) => parent.add(&widget.into_widget(context)), - Widget::Button(widget) => parent.add(&widget.into_widget(context)), - Widget::Image(widget) => parent.add(&widget.into_widget(context)), - Widget::Slider(widget) => parent.add(&widget.into_widget(context)), - Widget::Progress(widget) => parent.add(&widget.into_widget(context)), + Self::Box(widget) => parent.add(&widget.into_widget(context)), + Self::Label(widget) => parent.add(&widget.into_widget(context)), + Self::Button(widget) => parent.add(&widget.into_widget(context)), + Self::Image(widget) => parent.add(&widget.into_widget(context)), + Self::Slider(widget) => parent.add(&widget.into_widget(context)), + Self::Progress(widget) => parent.add(&widget.into_widget(context)), } } } @@ -147,7 +147,7 @@ impl Module for CustomModule { debug!("executing command: '{}'", script.cmd); - let args = event.args.unwrap_or(vec![]); + let args = event.args.unwrap_or_default(); if let Err(err) = script.get_output(Some(&args)).await { error!("{err:?}"); diff --git a/src/modules/custom/slider.rs b/src/modules/custom/slider.rs index 030053d..0b2f946 100644 --- a/src/modules/custom/slider.rs +++ b/src/modules/custom/slider.rs @@ -60,7 +60,7 @@ impl CustomWidget for SliderWidget { scale.connect_change_value(move |scale, _, val| { // GTK will send values outside min/max range - let val = clamp(val, min, max); + let val = val.clamp(min, max); if val != prev_value.get() { try_send!( @@ -106,14 +106,3 @@ impl CustomWidget for SliderWidget { scale } } - -/// Ensures `num` is between `min` and `max` (inclusive). -fn clamp(num: f64, min: f64, max: f64) -> f64 { - if num < min { - min - } else if num > max { - max - } else { - num - } -}