Skip to content

Commit 6240b4b

Browse files
authored
Merge pull request #746 from JakeStanger/fix/markup-escape
fix: markup escape issues
2 parents 56153f1 + b2db7b0 commit 6240b4b

File tree

10 files changed

+51
-30
lines changed

10 files changed

+51
-30
lines changed

src/dynamic_value/dynamic_string.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ enum DynamicStringSegment {
2222
///
2323
/// ```rs
2424
/// dynamic_string(&text, move |string| {
25-
/// label.set_markup(&string);
25+
/// label.set_label_escaped(&string);
2626
/// });
2727
/// ```
2828
pub fn dynamic_string<F>(input: &str, mut f: F)

src/gtk_helpers.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use glib::IsA;
1+
use glib::{markup_escape_text, IsA};
22
use gtk::prelude::*;
33
use gtk::{Orientation, Widget};
44

@@ -75,3 +75,22 @@ impl<W: IsA<Widget>> IronbarGtkExt for W {
7575
unsafe { self.set_data(key, value) }
7676
}
7777
}
78+
79+
pub trait IronbarLabelExt {
80+
/// Sets the label value to the provided string.
81+
///
82+
/// If the label does not contain markup `span` tags,
83+
/// the text is escaped to avoid issues with special characters (ie `&`).
84+
/// Otherwise, the text is used verbatim, and it is up to the user to escape.
85+
fn set_label_escaped(&self, label: &str);
86+
}
87+
88+
impl IronbarLabelExt for gtk::Label {
89+
fn set_label_escaped(&self, label: &str) {
90+
if !label.contains("<span") {
91+
self.set_label(&markup_escape_text(label));
92+
} else {
93+
self.set_label(label);
94+
}
95+
}
96+
}

src/modules/custom/button.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ use gtk::prelude::*;
22
use gtk::{Button, Label, Orientation};
33
use serde::Deserialize;
44

5+
use super::{CustomWidget, CustomWidgetContext, ExecEvent, WidgetConfig};
56
use crate::config::ModuleOrientation;
67
use crate::dynamic_value::dynamic_string;
8+
use crate::gtk_helpers::IronbarLabelExt;
79
use crate::modules::PopupButton;
810
use crate::{build, try_send};
911

10-
use super::{CustomWidget, CustomWidgetContext, ExecEvent, WidgetConfig};
11-
1212
#[derive(Debug, Deserialize, Clone)]
1313
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
1414
pub struct ButtonWidget {
@@ -75,7 +75,7 @@ impl CustomWidget for ButtonWidget {
7575
button.add(&label);
7676

7777
dynamic_string(&text, move |string| {
78-
label.set_markup(&string);
78+
label.set_label_escaped(&string);
7979
});
8080
}
8181

src/modules/custom/label.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ use gtk::prelude::*;
22
use gtk::Label;
33
use serde::Deserialize;
44

5+
use super::{CustomWidget, CustomWidgetContext};
56
use crate::build;
67
use crate::config::ModuleOrientation;
78
use crate::dynamic_value::dynamic_string;
8-
9-
use super::{CustomWidget, CustomWidgetContext};
9+
use crate::gtk_helpers::IronbarLabelExt;
1010

1111
#[derive(Debug, Deserialize, Clone)]
1212
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
@@ -50,7 +50,7 @@ impl CustomWidget for LabelWidget {
5050
{
5151
let label = label.clone();
5252
dynamic_string(&self.label, move |string| {
53-
label.set_markup(&string);
53+
label.set_label_escaped(&string);
5454
});
5555
}
5656

src/modules/label.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::config::CommonConfig;
22
use crate::dynamic_value::dynamic_string;
3+
use crate::gtk_helpers::IronbarLabelExt;
34
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
45
use crate::{glib_recv, module_impl, try_send};
56
use color_eyre::Result;
6-
use gtk::prelude::*;
77
use gtk::Label;
88
use serde::Deserialize;
99
use tokio::sync::mpsc;
@@ -56,12 +56,11 @@ impl Module<Label> for LabelModule {
5656
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
5757
_info: &ModuleInfo,
5858
) -> Result<ModuleParts<Label>> {
59-
let label = Label::new(None);
60-
label.set_use_markup(true);
59+
let label = Label::builder().use_markup(true).build();
6160

6261
{
6362
let label = label.clone();
64-
glib_recv!(context.subscribe(), string => label.set_markup(&string));
63+
glib_recv!(context.subscribe(), string => label.set_label_escaped(&string));
6564
}
6665

6766
Ok(ModuleParts {

src/modules/music/mod.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::sync::Arc;
55
use std::time::Duration;
66

77
use color_eyre::Result;
8-
use glib::{markup_escape_text, Propagation, PropertySet};
8+
use glib::{Propagation, PropertySet};
99
use gtk::prelude::*;
1010
use gtk::{Button, IconTheme, Label, Orientation, Scale};
1111
use regex::Regex;
@@ -16,7 +16,7 @@ use crate::clients::music::{
1616
self, MusicClient, PlayerState, PlayerUpdate, ProgressTick, Status, Track,
1717
};
1818
use crate::clients::Clients;
19-
use crate::gtk_helpers::IronbarGtkExt;
19+
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
2020
use crate::image::{new_icon_button, new_icon_label, ImageProvider};
2121
use crate::modules::PopupButton;
2222
use crate::modules::{
@@ -189,10 +189,11 @@ impl Module<Button> for MusicModule {
189189

190190
let icon_play = new_icon_label(&self.icons.play, info.icon_theme, self.icon_size);
191191
let icon_pause = new_icon_label(&self.icons.pause, info.icon_theme, self.icon_size);
192-
let label = Label::new(None);
193192

194-
label.set_use_markup(true);
195-
label.set_angle(info.bar_position.get_angle());
193+
let label = Label::builder()
194+
.use_markup(true)
195+
.angle(info.bar_position.get_angle())
196+
.build();
196197

197198
if let Some(truncate) = self.truncate {
198199
truncate.truncate_label(&label);
@@ -222,7 +223,7 @@ impl Module<Button> for MusicModule {
222223
};
223224

224225
if let Some(event) = event.take() {
225-
label.set_label(&event.display_string);
226+
label.set_label_escaped(&event.display_string);
226227

227228
button.show();
228229

@@ -473,7 +474,7 @@ impl Module<Button> for MusicModule {
473474
if let (Some(elapsed), Some(duration)) =
474475
(progress_tick.elapsed, progress_tick.duration)
475476
{
476-
progress_label.set_label(&format!(
477+
progress_label.set_label_escaped(&format!(
477478
"{}/{}",
478479
format_time(elapsed),
479480
format_time(duration)
@@ -498,7 +499,7 @@ impl Module<Button> for MusicModule {
498499
fn update_popup_metadata_label(text: Option<String>, label: &IconLabel) {
499500
match text {
500501
Some(value) => {
501-
label.label.set_text(&value);
502+
label.label.set_label_escaped(&value);
502503
label.container.show_all();
503504
}
504505
None => {
@@ -531,7 +532,6 @@ fn get_token_value(song: &Track, token: &str) -> String {
531532
"track" => song.track.map(|x| x.to_string()),
532533
_ => Some(token.to_string()),
533534
}
534-
.map(|str| markup_escape_text(str.as_str()).to_string())
535535
.unwrap_or_default()
536536
}
537537

src/modules/script.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::config::CommonConfig;
2+
use crate::gtk_helpers::IronbarLabelExt;
23
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
34
use crate::script::{OutputStream, Script, ScriptMode};
45
use crate::{glib_recv, module_impl, spawn, try_send};
@@ -103,7 +104,7 @@ impl Module<Label> for ScriptModule {
103104

104105
{
105106
let label = label.clone();
106-
glib_recv!(context.subscribe(), s => label.set_markup(s.as_str()));
107+
glib_recv!(context.subscribe(), s => label.set_label_escaped(&s));
107108
}
108109

109110
Ok(ModuleParts {

src/modules/sway/mode.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::config::{CommonConfig, TruncateMode};
2+
use crate::gtk_helpers::IronbarLabelExt;
23
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
34
use crate::{await_sync, glib_recv, module_impl, try_send};
45
use color_eyre::{Report, Result};
@@ -59,6 +60,7 @@ impl Module<Label> for SwayModeModule {
5960
_info: &ModuleInfo,
6061
) -> Result<ModuleParts<Label>> {
6162
let label = Label::new(None);
63+
label.set_use_markup(true);
6264

6365
{
6466
let label = label.clone();
@@ -71,9 +73,9 @@ impl Module<Label> for SwayModeModule {
7173
trace!("mode: {:?}", mode);
7274
label.set_use_markup(mode.pango_markup);
7375
if mode.change == "default" {
74-
label.set_markup("");
76+
label.set_label_escaped("");
7577
} else {
76-
label.set_markup(&mode.change);
78+
label.set_label_escaped(&mode.change);
7779
}
7880
};
7981

src/modules/sysinfo.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::config::{CommonConfig, ModuleOrientation};
2-
use crate::gtk_helpers::IronbarGtkExt;
2+
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
33
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
44
use crate::{glib_recv, module_impl, send_async, spawn};
55
use color_eyre::Result;
@@ -266,7 +266,7 @@ impl Module<gtk::Box> for SysInfoModule {
266266
.to_string()
267267
});
268268

269-
label.set_markup(format_compiled.as_ref());
269+
label.set_label_escaped(format_compiled.as_ref());
270270
}
271271
});
272272
}

src/modules/upower.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use zbus;
99
use zbus::fdo::PropertiesProxy;
1010

1111
use crate::config::CommonConfig;
12-
use crate::gtk_helpers::IronbarGtkExt;
12+
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
1313
use crate::image::ImageProvider;
1414
use crate::modules::PopupButton;
1515
use crate::modules::{
@@ -212,7 +212,7 @@ impl Module<gtk::Button> for UpowerModule {
212212
ImageProvider::parse(&icon_name, &icon_theme, false, self.icon_size)
213213
.map(|provider| provider.load_into_image(icon.clone()));
214214

215-
label.set_markup(format.as_ref());
215+
label.set_label_escaped(&format);
216216
});
217217

218218
let rx = context.subscribe();
@@ -237,7 +237,7 @@ impl Module<gtk::Button> for UpowerModule {
237237
.orientation(Orientation::Horizontal)
238238
.build();
239239

240-
let label = Label::new(None);
240+
let label = Label::builder().use_markup(true).build();
241241
label.add_class("upower-details");
242242
container.add(&label);
243243

@@ -263,7 +263,7 @@ impl Module<gtk::Button> for UpowerModule {
263263
_ => String::new(),
264264
};
265265

266-
label.set_markup(&format);
266+
label.set_label_escaped(&format);
267267
});
268268

269269
container.show_all();

0 commit comments

Comments
 (0)