diff --git a/src/panel/widgets/notifications/single-notification.cpp b/src/panel/widgets/notifications/single-notification.cpp index 4e3fd5d5..e4b5453d 100644 --- a/src/panel/widgets/notifications/single-notification.cpp +++ b/src/panel/widgets/notifications/single-notification.cpp @@ -116,11 +116,12 @@ WfSingleNotification::WfSingleNotification(const Notification & notification) text.set_wrap_mode(Pango::WrapMode::CHAR); if (notification.body.empty()) { - text.set_markup(notification.summary); + text.set_markup(markup_escape(notification.summary)); } else { // NOTE: that is not a really right way to implement FDN markup feature, but the easiest one. - text.set_markup("" + notification.summary + "" + "\n" + notification.body); + text.set_markup("" + markup_escape( + notification.summary) + "" + "\n" + markup_escape(notification.body)); } content.append(text); diff --git a/src/panel/widgets/tray/item.cpp b/src/panel/widgets/tray/item.cpp index fae84034..4b02ef99 100644 --- a/src/panel/widgets/tray/item.cpp +++ b/src/panel/widgets/tray/item.cpp @@ -167,10 +167,11 @@ void StatusNotifierItem::setup_tooltip() get_item_property>("ToolTip"); auto tooltip_label_text = !tooltip_text.empty() && !tooltip_title.empty() ? - "" + tooltip_title + ": " + tooltip_text : - !tooltip_title.empty() ? tooltip_title : - !tooltip_text.empty() ? tooltip_text : - get_item_property("Title"); + "" + markup_escape(tooltip_title) + ": " + + markup_escape(tooltip_text) : + !tooltip_title.empty() ? markup_escape(tooltip_title) : + !tooltip_text.empty() ? markup_escape(tooltip_text) : + markup_escape(get_item_property("Title")); const auto pixbuf = extract_pixbuf(std::move(tooltip_icon_data)); bool icon_shown = false; diff --git a/src/util/gtk-utils.cpp b/src/util/gtk-utils.cpp index 80cec7b5..4b1a0f0d 100644 --- a/src/util/gtk-utils.cpp +++ b/src/util/gtk-utils.cpp @@ -1,3 +1,4 @@ +#include "glibmm/markup.h" #include #include #include @@ -72,3 +73,35 @@ void image_set_icon(Gtk::Image *image, std::string path) image->set_from_icon_name(path); } } + +/* + * Check if this string appears to be markup + * + * Does not check it is *valid* markup + */ +bool is_markup(std::string input) +{ + int count_left = std::count(input.begin(), input.end(), '<'); + int count_right = std::count(input.begin(), input.end(), '>'); + int count_amp = std::count(input.begin(), input.end(), '&'); + int count_semi = std::count(input.begin(), input.end(), ';'); + + if ((count_left == count_right) && (count_amp == count_semi)) + { + /* And they pair up */ + return true; + } + + return false; +} + +/* Escape string if it doesn't appear to be markup */ +std::string markup_escape(std::string input) +{ + if (is_markup(input)) + { + return input; + } + + return Glib::Markup::escape_text(input); +} diff --git a/src/util/gtk-utils.hpp b/src/util/gtk-utils.hpp index 8cac6c29..ef78616e 100644 --- a/src/util/gtk-utils.hpp +++ b/src/util/gtk-utils.hpp @@ -20,3 +20,7 @@ struct WfIconLoadOptions void invert_pixbuf(Glib::RefPtr& pbuff); void image_set_icon(Gtk::Image *image, std::string path); + +bool is_markup(std::string); + +std::string markup_escape(std::string);