From df4bfc83d04146213ef44b125492e588c2a2d02b Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Fri, 28 Jun 2024 23:24:30 +0100 Subject: [PATCH 1/4] feat(truncate): explicit `off` mode --- docs/modules/Clipboard.md | 18 ++++++++--------- docs/modules/Focused.md | 18 ++++++++--------- docs/modules/Music.md | 42 +++++++++++++++++++-------------------- src/config/truncate.rs | 17 ++++++++++++++-- 4 files changed, 54 insertions(+), 41 deletions(-) diff --git a/docs/modules/Clipboard.md b/docs/modules/Clipboard.md index 212a60d5..f168f8f5 100644 --- a/docs/modules/Clipboard.md +++ b/docs/modules/Clipboard.md @@ -12,15 +12,15 @@ Supports plain text and images. > Type: `clipboard` -| Name | Type | Default | Description | -|-----------------------|---------------------------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------| -| `icon` | `string` or [image](images) | `󰨸` | Icon to show on the widget button. | -| `icon_size` | `integer` | `32` | Size to render icon at (image icons only). | -| `max_items` | `integer` | `10` | Maximum number of items to show in the popup. | -| `truncate` | `'start'` or `'middle'` or `'end'` or `Map` | `null` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. Use the long-hand `Map` version if specifying a length. | -| `truncate.mode` | `'start'` or `'middle'` or `'end'` | `null` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. | -| `truncate.length` | `integer` | `null` | The fixed width (in chars) of the widget. Leave blank to let GTK automatically handle. | -| `truncate.max_length` | `integer` | `null` | The maximum number of characters before truncating. Leave blank to let GTK automatically handle. | +| Name | Type | Default | Description | +|-----------------------|------------------------------------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| `icon` | `string` or [image](images) | `󰨸` | Icon to show on the widget button. | +| `icon_size` | `integer` | `32` | Size to render icon at (image icons only). | +| `max_items` | `integer` | `10` | Maximum number of items to show in the popup. | +| `truncate` | `'start'` or `'middle'` or `'end'` or `off` or `Map` | `off` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. Use the long-hand `Map` version if specifying a length. | +| `truncate.mode` | `'start'` or `'middle'` or `'end'` or `off` | `off` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. | +| `truncate.length` | `integer` | `null` | The fixed width (in chars) of the widget. Leave blank to let GTK automatically handle. | +| `truncate.max_length` | `integer` | `null` | The maximum number of characters before truncating. Leave blank to let GTK automatically handle. |
JSON diff --git a/docs/modules/Focused.md b/docs/modules/Focused.md index 009b1251..066004a8 100644 --- a/docs/modules/Focused.md +++ b/docs/modules/Focused.md @@ -10,15 +10,15 @@ Displays the title and/or icon of the currently focused window. > Type: `focused` -| Name | Type | Default | Description | -|-----------------------|---------------------------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------| -| `show_icon` | `boolean` | `true` | Whether to show the app's icon. | -| `show_title` | `boolean` | `true` | Whether to show the app's title. | -| `icon_size` | `integer` | `32` | Size of icon in pixels. | -| `truncate` | `'start'` or `'middle'` or `'end'` or `Map` | `null` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. Use the long-hand `Map` version if specifying a length. | -| `truncate.mode` | `'start'` or `'middle'` or `'end'` | `null` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. | -| `truncate.length` | `integer` | `null` | The fixed width (in chars) of the widget. Leave blank to let GTK automatically handle. | -| `truncate.max_length` | `integer` | `null` | The maximum number of characters before truncating. Leave blank to let GTK automatically handle. | +| Name | Type | Default | Description | +|-----------------------|------------------------------------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| `show_icon` | `boolean` | `true` | Whether to show the app's icon. | +| `show_title` | `boolean` | `true` | Whether to show the app's title. | +| `icon_size` | `integer` | `32` | Size of icon in pixels. | +| `truncate` | `'start'` or `'middle'` or `'end'` or `off` or `Map` | `off` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. Use the long-hand `Map` version if specifying a length. | +| `truncate.mode` | `'start'` or `'middle'` or `'end'` or `off` | `off` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. | +| `truncate.length` | `integer` | `null` | The fixed width (in chars) of the widget. Leave blank to let GTK automatically handle. | +| `truncate.max_length` | `integer` | `null` | The maximum number of characters before truncating. Leave blank to let GTK automatically handle. |
JSON diff --git a/docs/modules/Music.md b/docs/modules/Music.md index 5c5bc7d1..bdde6817 100644 --- a/docs/modules/Music.md +++ b/docs/modules/Music.md @@ -11,27 +11,27 @@ in MPRIS mode, the widget will listen to all players and automatically detect/di > Type: `music` -| | Type | Default | Description | -|-----------------------|---------------------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| -| `player_type` | `'mpris'` or `'mpd'` | `mpris` | Whether to connect to MPRIS players or an MPD server. | -| `format` | `string` | `{title} / {artist}` | Format string for the widget. More info below. | -| `truncate` | `'start'` or `'middle'` or `'end'` or `Map` | `null` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. Use the long-hand `Map` version if specifying a length. | -| `truncate.mode` | `'start'` or `'middle'` or `'end'` | `null` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. | -| `truncate.length` | `integer` | `null` | The fixed width (in chars) of the widget. Leave blank to let GTK automatically handle. | -| `truncate.max_length` | `integer` | `null` | The maximum number of characters before truncating. Leave blank to let GTK automatically handle. | -| `icons.play` | `string` or [image](images) | `` | Icon to show when playing. | -| `icons.pause` | `string` or [image](images) | `` | Icon to show when paused. | -| `icons.prev` | `string` or [image](images) | `󰒮` | Icon to show on previous button. | -| `icons.next` | `string` or [image](images) | `󰒭` | Icon to show on next button. | -| `icons.volume` | `string` or [image](images) | `󰕾` | Icon to show under popup volume slider. | -| `icons.track` | `string` or [image](images) | `󰎈` | Icon to show next to track title. | -| `icons.album` | `string` or [image](images) | `󰀥` | Icon to show next to album name. | -| `icons.artist` | `string` or [image](images) | `󰠃` | Icon to show next to artist name. | -| `show_status_icon` | `boolean` | `true` | Whether to show the play/pause icon on the widget. | -| `icon_size` | `integer` | `32` | Size to render icon at (image icons only). | -| `cover_image_size` | `integer` | `128` | Size to render album art image at inside popup. | -| `host` | `string` | `localhost:6600` | [MPD Only] TCP or Unix socket for the MPD server. | -| `music_dir` | `string` | `$HOME/Music` | [MPD Only] Path to MPD server's music directory on disc. Required for album art. | +| | Type | Default | Description | +|-----------------------|------------------------------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| `player_type` | `'mpris'` or `'mpd'` | `mpris` | Whether to connect to MPRIS players or an MPD server. | +| `format` | `string` | `{title} / {artist}` | Format string for the widget. More info below. | +| `truncate` | `'start'` or `'middle'` or `'end'` or `off` or `Map` | `off` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. Use the long-hand `Map` version if specifying a length. | +| `truncate.mode` | `'start'` or `'middle'` or `'end'` or `off` | `off` | The location of the ellipses and where to truncate text from. Leave null to avoid truncating. | +| `truncate.length` | `integer` | `null` | The fixed width (in chars) of the widget. Leave blank to let GTK automatically handle. | +| `truncate.max_length` | `integer` | `null` | The maximum number of characters before truncating. Leave blank to let GTK automatically handle. | +| `icons.play` | `string` or [image](images) | `` | Icon to show when playing. | +| `icons.pause` | `string` or [image](images) | `` | Icon to show when paused. | +| `icons.prev` | `string` or [image](images) | `󰒮` | Icon to show on previous button. | +| `icons.next` | `string` or [image](images) | `󰒭` | Icon to show on next button. | +| `icons.volume` | `string` or [image](images) | `󰕾` | Icon to show under popup volume slider. | +| `icons.track` | `string` or [image](images) | `󰎈` | Icon to show next to track title. | +| `icons.album` | `string` or [image](images) | `󰀥` | Icon to show next to album name. | +| `icons.artist` | `string` or [image](images) | `󰠃` | Icon to show next to artist name. | +| `show_status_icon` | `boolean` | `true` | Whether to show the play/pause icon on the widget. | +| `icon_size` | `integer` | `32` | Size to render icon at (image icons only). | +| `cover_image_size` | `integer` | `128` | Size to render album art image at inside popup. | +| `host` | `string` | `localhost:6600` | [MPD Only] TCP or Unix socket for the MPD server. | +| `music_dir` | `string` | `$HOME/Music` | [MPD Only] Path to MPD server's music directory on disc. Required for album art. | See [here](images) for information on images. diff --git a/src/config/truncate.rs b/src/config/truncate.rs index 09966cd8..14222ad4 100644 --- a/src/config/truncate.rs +++ b/src/config/truncate.rs @@ -6,6 +6,7 @@ use serde::Deserialize; #[serde(rename_all = "snake_case")] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum EllipsizeMode { + None, Start, Middle, End, @@ -14,6 +15,7 @@ pub enum EllipsizeMode { impl From for GtkEllipsizeMode { fn from(value: EllipsizeMode) -> Self { match value { + EllipsizeMode::None => Self::None, EllipsizeMode::Start => Self::Start, EllipsizeMode::Middle => Self::Middle, EllipsizeMode::End => Self::End, @@ -31,6 +33,17 @@ impl From for GtkEllipsizeMode { #[serde(untagged)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum TruncateMode { + /// Do not truncate content. + /// + /// Setting this option may cause excessively long content to overflow other widgets, + /// shifting them off-screen. + /// + /// # Example + /// + /// ```corn + /// { truncate = "off" } + Off, + /// Auto mode lets GTK decide when to ellipsize. /// /// To use this mode, set the truncate option to a string @@ -97,14 +110,14 @@ impl TruncateMode { const fn length(&self) -> Option { match self { - Self::Auto(_) => None, + Self::Auto(_) | Self::Off => None, Self::Length { length, .. } => *length, } } const fn max_length(&self) -> Option { match self { - Self::Auto(_) => None, + Self::Auto(_) | Self::Off => None, Self::Length { max_length, .. } => *max_length, } } From cc6f21ed682b5123c6a19309fbb03b50f995535a Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Fri, 28 Jun 2024 23:26:36 +0100 Subject: [PATCH 2/4] refactor: take reference into image provider --- src/image/gtk.rs | 4 ++-- src/image/provider.rs | 7 ++++--- src/modules/custom/image.rs | 2 +- src/modules/focused.rs | 2 +- src/modules/launcher/item.rs | 2 +- src/modules/music/mod.rs | 2 +- src/modules/upower.rs | 2 +- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/image/gtk.rs b/src/image/gtk.rs index bf80bcd4..8c17791c 100644 --- a/src/image/gtk.rs +++ b/src/image/gtk.rs @@ -13,7 +13,7 @@ pub fn new_icon_button(input: &str, icon_theme: &IconTheme, size: i32) -> Button image.add_class("icon"); match ImageProvider::parse(input, icon_theme, false, size) - .map(|provider| provider.load_into_image(image.clone())) + .map(|provider| provider.load_into_image(&image)) { Some(_) => { button.set_image(Some(&image)); @@ -42,7 +42,7 @@ pub fn new_icon_label(input: &str, icon_theme: &IconTheme, size: i32) -> gtk::Bo container.add(&image); ImageProvider::parse(input, icon_theme, false, size) - .map(|provider| provider.load_into_image(image)); + .map(|provider| provider.load_into_image(&image)); } else { let label = Label::builder().use_markup(true).label(input).build(); label.add_class("icon"); diff --git a/src/image/provider.rs b/src/image/provider.rs index eaf22223..5004c37f 100644 --- a/src/image/provider.rs +++ b/src/image/provider.rs @@ -141,7 +141,7 @@ impl<'a> ImageProvider<'a> { /// Attempts to fetch the image from the location /// and load it into the provided `GTK::Image` widget. - pub fn load_into_image(&self, image: gtk::Image) -> Result<()> { + pub fn load_into_image(&self, image: >k::Image) -> Result<()> { // handle remote locations async to avoid blocking UI thread while downloading #[cfg(feature = "http")] if let ImageLocation::Remote(url) = &self.location { @@ -157,6 +157,7 @@ impl<'a> ImageProvider<'a> { { let size = self.size; + let image = image.clone(); glib_recv_mpsc!(rx, bytes => { let stream = MemoryInputStream::from_bytes(&bytes); @@ -181,11 +182,11 @@ impl<'a> ImageProvider<'a> { }); } } else { - self.load_into_image_sync(&image)?; + self.load_into_image_sync(image)?; }; #[cfg(not(feature = "http"))] - self.load_into_image_sync(&image)?; + self.load_into_image_sync(image)?; Ok(()) } diff --git a/src/modules/custom/image.rs b/src/modules/custom/image.rs index cb4a33fc..fe46b5d1 100644 --- a/src/modules/custom/image.rs +++ b/src/modules/custom/image.rs @@ -52,7 +52,7 @@ impl CustomWidget for ImageWidget { dynamic_string(&self.src, move |src| { ImageProvider::parse(&src, &icon_theme, false, self.size) - .map(|image| image.load_into_image(gtk_image.clone())); + .map(|image| image.load_into_image(>k_image)); }); } diff --git a/src/modules/focused.rs b/src/modules/focused.rs index 989293f5..2fde9bff 100644 --- a/src/modules/focused.rs +++ b/src/modules/focused.rs @@ -156,7 +156,7 @@ impl Module for FocusedModule { if let Some((name, id)) = data { if self.show_icon { match ImageProvider::parse(&id, &icon_theme, true, self.icon_size) - .map(|image| image.load_into_image(icon.clone())) + .map(|image| image.load_into_image(&icon)) { Some(Ok(())) => icon.show(), _ => icon.hide(), diff --git a/src/modules/launcher/item.rs b/src/modules/launcher/item.rs index 07d7fb38..409ed7af 100644 --- a/src/modules/launcher/item.rs +++ b/src/modules/launcher/item.rs @@ -176,7 +176,7 @@ impl ItemButton { button.set_image(Some(>k_image)); button.set_always_show_image(true); - if let Err(err) = image.load_into_image(gtk_image) { + if let Err(err) = image.load_into_image(>k_image) { error!("{err:?}"); } }; diff --git a/src/modules/music/mod.rs b/src/modules/music/mod.rs index 96cb91af..1e02de45 100644 --- a/src/modules/music/mod.rs +++ b/src/modules/music/mod.rs @@ -415,7 +415,7 @@ impl Module