mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-08-16 22:31:03 +02:00
Merge pull request #746 from JakeStanger/fix/markup-escape
fix: markup escape issues
This commit is contained in:
commit
6240b4b4fd
10 changed files with 51 additions and 30 deletions
|
@ -22,7 +22,7 @@ enum DynamicStringSegment {
|
||||||
///
|
///
|
||||||
/// ```rs
|
/// ```rs
|
||||||
/// dynamic_string(&text, move |string| {
|
/// dynamic_string(&text, move |string| {
|
||||||
/// label.set_markup(&string);
|
/// label.set_label_escaped(&string);
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
pub fn dynamic_string<F>(input: &str, mut f: F)
|
pub fn dynamic_string<F>(input: &str, mut f: F)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use glib::IsA;
|
use glib::{markup_escape_text, IsA};
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{Orientation, Widget};
|
use gtk::{Orientation, Widget};
|
||||||
|
|
||||||
|
@ -75,3 +75,22 @@ impl<W: IsA<Widget>> IronbarGtkExt for W {
|
||||||
unsafe { self.set_data(key, value) }
|
unsafe { self.set_data(key, value) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait IronbarLabelExt {
|
||||||
|
/// Sets the label value to the provided string.
|
||||||
|
///
|
||||||
|
/// If the label does not contain markup `span` tags,
|
||||||
|
/// the text is escaped to avoid issues with special characters (ie `&`).
|
||||||
|
/// Otherwise, the text is used verbatim, and it is up to the user to escape.
|
||||||
|
fn set_label_escaped(&self, label: &str);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IronbarLabelExt for gtk::Label {
|
||||||
|
fn set_label_escaped(&self, label: &str) {
|
||||||
|
if !label.contains("<span") {
|
||||||
|
self.set_label(&markup_escape_text(label));
|
||||||
|
} else {
|
||||||
|
self.set_label(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@ use gtk::prelude::*;
|
||||||
use gtk::{Button, Label, Orientation};
|
use gtk::{Button, Label, Orientation};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use super::{CustomWidget, CustomWidgetContext, ExecEvent, WidgetConfig};
|
||||||
use crate::config::ModuleOrientation;
|
use crate::config::ModuleOrientation;
|
||||||
use crate::dynamic_value::dynamic_string;
|
use crate::dynamic_value::dynamic_string;
|
||||||
|
use crate::gtk_helpers::IronbarLabelExt;
|
||||||
use crate::modules::PopupButton;
|
use crate::modules::PopupButton;
|
||||||
use crate::{build, try_send};
|
use crate::{build, try_send};
|
||||||
|
|
||||||
use super::{CustomWidget, CustomWidgetContext, ExecEvent, WidgetConfig};
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||||
pub struct ButtonWidget {
|
pub struct ButtonWidget {
|
||||||
|
@ -75,7 +75,7 @@ impl CustomWidget for ButtonWidget {
|
||||||
button.add(&label);
|
button.add(&label);
|
||||||
|
|
||||||
dynamic_string(&text, move |string| {
|
dynamic_string(&text, move |string| {
|
||||||
label.set_markup(&string);
|
label.set_label_escaped(&string);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@ use gtk::prelude::*;
|
||||||
use gtk::Label;
|
use gtk::Label;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use super::{CustomWidget, CustomWidgetContext};
|
||||||
use crate::build;
|
use crate::build;
|
||||||
use crate::config::ModuleOrientation;
|
use crate::config::ModuleOrientation;
|
||||||
use crate::dynamic_value::dynamic_string;
|
use crate::dynamic_value::dynamic_string;
|
||||||
|
use crate::gtk_helpers::IronbarLabelExt;
|
||||||
use super::{CustomWidget, CustomWidgetContext};
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||||
|
@ -50,7 +50,7 @@ impl CustomWidget for LabelWidget {
|
||||||
{
|
{
|
||||||
let label = label.clone();
|
let label = label.clone();
|
||||||
dynamic_string(&self.label, move |string| {
|
dynamic_string(&self.label, move |string| {
|
||||||
label.set_markup(&string);
|
label.set_label_escaped(&string);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::config::CommonConfig;
|
use crate::config::CommonConfig;
|
||||||
use crate::dynamic_value::dynamic_string;
|
use crate::dynamic_value::dynamic_string;
|
||||||
|
use crate::gtk_helpers::IronbarLabelExt;
|
||||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||||
use crate::{glib_recv, module_impl, try_send};
|
use crate::{glib_recv, module_impl, try_send};
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::Label;
|
use gtk::Label;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
@ -56,12 +56,11 @@ impl Module<Label> for LabelModule {
|
||||||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||||
_info: &ModuleInfo,
|
_info: &ModuleInfo,
|
||||||
) -> Result<ModuleParts<Label>> {
|
) -> Result<ModuleParts<Label>> {
|
||||||
let label = Label::new(None);
|
let label = Label::builder().use_markup(true).build();
|
||||||
label.set_use_markup(true);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let label = label.clone();
|
let label = label.clone();
|
||||||
glib_recv!(context.subscribe(), string => label.set_markup(&string));
|
glib_recv!(context.subscribe(), string => label.set_label_escaped(&string));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ModuleParts {
|
Ok(ModuleParts {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use glib::{markup_escape_text, Propagation, PropertySet};
|
use glib::{Propagation, PropertySet};
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{Button, IconTheme, Label, Orientation, Scale};
|
use gtk::{Button, IconTheme, Label, Orientation, Scale};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
@ -16,7 +16,7 @@ use crate::clients::music::{
|
||||||
self, MusicClient, PlayerState, PlayerUpdate, ProgressTick, Status, Track,
|
self, MusicClient, PlayerState, PlayerUpdate, ProgressTick, Status, Track,
|
||||||
};
|
};
|
||||||
use crate::clients::Clients;
|
use crate::clients::Clients;
|
||||||
use crate::gtk_helpers::IronbarGtkExt;
|
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||||
use crate::image::{new_icon_button, new_icon_label, ImageProvider};
|
use crate::image::{new_icon_button, new_icon_label, ImageProvider};
|
||||||
use crate::modules::PopupButton;
|
use crate::modules::PopupButton;
|
||||||
use crate::modules::{
|
use crate::modules::{
|
||||||
|
@ -189,10 +189,11 @@ impl Module<Button> for MusicModule {
|
||||||
|
|
||||||
let icon_play = new_icon_label(&self.icons.play, info.icon_theme, self.icon_size);
|
let icon_play = new_icon_label(&self.icons.play, info.icon_theme, self.icon_size);
|
||||||
let icon_pause = new_icon_label(&self.icons.pause, info.icon_theme, self.icon_size);
|
let icon_pause = new_icon_label(&self.icons.pause, info.icon_theme, self.icon_size);
|
||||||
let label = Label::new(None);
|
|
||||||
|
|
||||||
label.set_use_markup(true);
|
let label = Label::builder()
|
||||||
label.set_angle(info.bar_position.get_angle());
|
.use_markup(true)
|
||||||
|
.angle(info.bar_position.get_angle())
|
||||||
|
.build();
|
||||||
|
|
||||||
if let Some(truncate) = self.truncate {
|
if let Some(truncate) = self.truncate {
|
||||||
truncate.truncate_label(&label);
|
truncate.truncate_label(&label);
|
||||||
|
@ -222,7 +223,7 @@ impl Module<Button> for MusicModule {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(event) = event.take() {
|
if let Some(event) = event.take() {
|
||||||
label.set_label(&event.display_string);
|
label.set_label_escaped(&event.display_string);
|
||||||
|
|
||||||
button.show();
|
button.show();
|
||||||
|
|
||||||
|
@ -473,7 +474,7 @@ impl Module<Button> for MusicModule {
|
||||||
if let (Some(elapsed), Some(duration)) =
|
if let (Some(elapsed), Some(duration)) =
|
||||||
(progress_tick.elapsed, progress_tick.duration)
|
(progress_tick.elapsed, progress_tick.duration)
|
||||||
{
|
{
|
||||||
progress_label.set_label(&format!(
|
progress_label.set_label_escaped(&format!(
|
||||||
"{}/{}",
|
"{}/{}",
|
||||||
format_time(elapsed),
|
format_time(elapsed),
|
||||||
format_time(duration)
|
format_time(duration)
|
||||||
|
@ -498,7 +499,7 @@ impl Module<Button> for MusicModule {
|
||||||
fn update_popup_metadata_label(text: Option<String>, label: &IconLabel) {
|
fn update_popup_metadata_label(text: Option<String>, label: &IconLabel) {
|
||||||
match text {
|
match text {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
label.label.set_text(&value);
|
label.label.set_label_escaped(&value);
|
||||||
label.container.show_all();
|
label.container.show_all();
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -531,7 +532,6 @@ fn get_token_value(song: &Track, token: &str) -> String {
|
||||||
"track" => song.track.map(|x| x.to_string()),
|
"track" => song.track.map(|x| x.to_string()),
|
||||||
_ => Some(token.to_string()),
|
_ => Some(token.to_string()),
|
||||||
}
|
}
|
||||||
.map(|str| markup_escape_text(str.as_str()).to_string())
|
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::config::CommonConfig;
|
use crate::config::CommonConfig;
|
||||||
|
use crate::gtk_helpers::IronbarLabelExt;
|
||||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||||
use crate::script::{OutputStream, Script, ScriptMode};
|
use crate::script::{OutputStream, Script, ScriptMode};
|
||||||
use crate::{glib_recv, module_impl, spawn, try_send};
|
use crate::{glib_recv, module_impl, spawn, try_send};
|
||||||
|
@ -103,7 +104,7 @@ impl Module<Label> for ScriptModule {
|
||||||
|
|
||||||
{
|
{
|
||||||
let label = label.clone();
|
let label = label.clone();
|
||||||
glib_recv!(context.subscribe(), s => label.set_markup(s.as_str()));
|
glib_recv!(context.subscribe(), s => label.set_label_escaped(&s));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ModuleParts {
|
Ok(ModuleParts {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::config::{CommonConfig, TruncateMode};
|
use crate::config::{CommonConfig, TruncateMode};
|
||||||
|
use crate::gtk_helpers::IronbarLabelExt;
|
||||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||||
use crate::{await_sync, glib_recv, module_impl, try_send};
|
use crate::{await_sync, glib_recv, module_impl, try_send};
|
||||||
use color_eyre::{Report, Result};
|
use color_eyre::{Report, Result};
|
||||||
|
@ -59,6 +60,7 @@ impl Module<Label> for SwayModeModule {
|
||||||
_info: &ModuleInfo,
|
_info: &ModuleInfo,
|
||||||
) -> Result<ModuleParts<Label>> {
|
) -> Result<ModuleParts<Label>> {
|
||||||
let label = Label::new(None);
|
let label = Label::new(None);
|
||||||
|
label.set_use_markup(true);
|
||||||
|
|
||||||
{
|
{
|
||||||
let label = label.clone();
|
let label = label.clone();
|
||||||
|
@ -71,9 +73,9 @@ impl Module<Label> for SwayModeModule {
|
||||||
trace!("mode: {:?}", mode);
|
trace!("mode: {:?}", mode);
|
||||||
label.set_use_markup(mode.pango_markup);
|
label.set_use_markup(mode.pango_markup);
|
||||||
if mode.change == "default" {
|
if mode.change == "default" {
|
||||||
label.set_markup("");
|
label.set_label_escaped("");
|
||||||
} else {
|
} else {
|
||||||
label.set_markup(&mode.change);
|
label.set_label_escaped(&mode.change);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::config::{CommonConfig, ModuleOrientation};
|
use crate::config::{CommonConfig, ModuleOrientation};
|
||||||
use crate::gtk_helpers::IronbarGtkExt;
|
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||||
use crate::{glib_recv, module_impl, send_async, spawn};
|
use crate::{glib_recv, module_impl, send_async, spawn};
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
|
@ -266,7 +266,7 @@ impl Module<gtk::Box> for SysInfoModule {
|
||||||
.to_string()
|
.to_string()
|
||||||
});
|
});
|
||||||
|
|
||||||
label.set_markup(format_compiled.as_ref());
|
label.set_label_escaped(format_compiled.as_ref());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use zbus;
|
||||||
use zbus::fdo::PropertiesProxy;
|
use zbus::fdo::PropertiesProxy;
|
||||||
|
|
||||||
use crate::config::CommonConfig;
|
use crate::config::CommonConfig;
|
||||||
use crate::gtk_helpers::IronbarGtkExt;
|
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||||
use crate::image::ImageProvider;
|
use crate::image::ImageProvider;
|
||||||
use crate::modules::PopupButton;
|
use crate::modules::PopupButton;
|
||||||
use crate::modules::{
|
use crate::modules::{
|
||||||
|
@ -212,7 +212,7 @@ impl Module<gtk::Button> for UpowerModule {
|
||||||
ImageProvider::parse(&icon_name, &icon_theme, false, self.icon_size)
|
ImageProvider::parse(&icon_name, &icon_theme, false, self.icon_size)
|
||||||
.map(|provider| provider.load_into_image(icon.clone()));
|
.map(|provider| provider.load_into_image(icon.clone()));
|
||||||
|
|
||||||
label.set_markup(format.as_ref());
|
label.set_label_escaped(&format);
|
||||||
});
|
});
|
||||||
|
|
||||||
let rx = context.subscribe();
|
let rx = context.subscribe();
|
||||||
|
@ -237,7 +237,7 @@ impl Module<gtk::Button> for UpowerModule {
|
||||||
.orientation(Orientation::Horizontal)
|
.orientation(Orientation::Horizontal)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let label = Label::new(None);
|
let label = Label::builder().use_markup(true).build();
|
||||||
label.add_class("upower-details");
|
label.add_class("upower-details");
|
||||||
container.add(&label);
|
container.add(&label);
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ impl Module<gtk::Button> for UpowerModule {
|
||||||
_ => String::new(),
|
_ => String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
label.set_markup(&format);
|
label.set_label_escaped(&format);
|
||||||
});
|
});
|
||||||
|
|
||||||
container.show_all();
|
container.show_all();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue