From 1e37f53e99016aa2cd725d7050788bb5d4fcc76a Mon Sep 17 00:00:00 2001 From: Rayzeq Date: Sun, 14 Apr 2024 16:57:58 +0200 Subject: [PATCH] fix #42: use gtk's text truncation system when possible (#1066) * fix #42: use gtk's text truncation system when possible * enhance doc + add to changelog --- CHANGELOG.md | 1 + Cargo.lock | 1 + crates/eww/Cargo.toml | 1 + crates/eww/src/widgets/widget_definitions.rs | 62 +++++++++++++++----- 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60b557eb..5189fd3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to eww will be listed here, starting at changes since versio - The `shell-completions` subcommand is now run before anything is set up - Fix nix flake - Fix `jq` (By: w-lfchen) +- Labels now use gtk's truncation system (By: Rayzeq). ### Features - Add `systray` widget (By: ralismark) diff --git a/Cargo.lock b/Cargo.lock index 8e3af352..8baf72e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -951,6 +951,7 @@ dependencies = [ "notify", "once_cell", "ordered-stream", + "pango", "pretty_env_logger", "regex", "serde", diff --git a/crates/eww/Cargo.toml b/crates/eww/Cargo.toml index 2aa461a4..a5b62d9e 100644 --- a/crates/eww/Cargo.toml +++ b/crates/eww/Cargo.toml @@ -23,6 +23,7 @@ notifier_host.workspace = true gtk = "0.17.1" gdk = "0.17.1" +pango = "0.17.1" glib = "0.17.8" glib-macros = "0.17.8" diff --git a/crates/eww/src/widgets/widget_definitions.rs b/crates/eww/src/widgets/widget_definitions.rs index 16aae7d0..696a5bfa 100644 --- a/crates/eww/src/widgets/widget_definitions.rs +++ b/crates/eww/src/widgets/widget_definitions.rs @@ -896,27 +896,37 @@ fn build_gtk_label(bargs: &mut BuilderArgs) -> Result { // @prop text - the text to display // @prop limit-width - maximum count of characters to display // @prop truncate-left - whether to truncate on the left side - // @prop show-truncated - show whether the text was truncated + // @prop show-truncated - show whether the text was truncated. Disabling it will also disable dynamic truncation (the labels won't be truncated more than `limit-width`, even if there is not enough space for them), and will completly disable truncation on pango markup. // @prop unindent - whether to remove leading spaces prop(text: as_string, limit_width: as_i32 = i32::MAX, truncate_left: as_bool = false, show_truncated: as_bool = true, unindent: as_bool = true) { - let limit_width = limit_width as usize; - let char_count = text.chars().count(); - let text = if char_count > limit_width { - let mut truncated: String = if truncate_left { - text.chars().skip(char_count - limit_width).collect() + let text = if show_truncated { + // gtk does weird thing if we set max_width_chars to i32::MAX + if limit_width == i32::MAX { + gtk_widget.set_max_width_chars(-1); } else { - text.chars().take(limit_width).collect() - }; - if show_truncated { + gtk_widget.set_max_width_chars(limit_width); + } + if truncate_left { + gtk_widget.set_ellipsize(pango::EllipsizeMode::Start); + } else { + gtk_widget.set_ellipsize(pango::EllipsizeMode::End); + } + + text + } else { + gtk_widget.set_ellipsize(pango::EllipsizeMode::None); + + let limit_width = limit_width as usize; + let char_count = text.chars().count(); + if char_count > limit_width && !show_truncated { if truncate_left { - truncated.insert_str(0, "..."); + text.chars().skip(char_count - limit_width).collect() } else { - truncated.push_str("..."); + text.chars().take(limit_width).collect() } + } else { + text } - truncated - } else { - text }; let text = unescape::unescape(&text).context(format!("Failed to unescape label text {}", &text))?; @@ -924,7 +934,29 @@ fn build_gtk_label(bargs: &mut BuilderArgs) -> Result { gtk_widget.set_text(&text); }, // @prop markup - Pango markup to display - prop(markup: as_string) { gtk_widget.set_markup(&markup); }, + // @prop limit-width - maximum count of characters to display + // @prop truncate-left - whether to truncate on the left side + // @prop show-truncated - show whether the text was truncatedd. Disabling it will also disable dynamic truncation (the labels won't be truncated more than `limit-width`, even if there is not enough space for them), and will completly disable truncation on pango markup. + prop(markup: as_string, limit_width: as_i32 = i32::MAX, truncate_left: as_bool = false, show_truncated: as_bool = true) { + if show_truncated { + // gtk does weird thing if we set max_width_chars to i32::MAX + if limit_width == i32::MAX { + gtk_widget.set_max_width_chars(-1); + } else { + gtk_widget.set_max_width_chars(limit_width); + } + + if truncate_left { + gtk_widget.set_ellipsize(pango::EllipsizeMode::Start); + } else { + gtk_widget.set_ellipsize(pango::EllipsizeMode::End); + } + } else { + gtk_widget.set_ellipsize(pango::EllipsizeMode::None); + } + + gtk_widget.set_markup(&markup); + }, // @prop wrap - Wrap the text. This mainly makes sense if you set the width of this widget. prop(wrap: as_bool) { gtk_widget.set_line_wrap(wrap) }, // @prop angle - the angle of rotation for the label (between 0 - 360)