diff --git a/include/modules/sway/window.hpp b/include/modules/sway/window.hpp index c99ba7f..c13d5ce 100644 --- a/include/modules/sway/window.hpp +++ b/include/modules/sway/window.hpp @@ -24,7 +24,6 @@ class Window : public AIconLabel, public sigc::trackable { std::tuple getFocusedNode( const Json::Value& nodes, std::string& output); void getTree(); - std::string rewriteTitle(const std::string& title); void updateAppIconName(); void updateAppIcon(); diff --git a/include/util/rewrite_title.hpp b/include/util/rewrite_title.hpp new file mode 100644 index 0000000..c477339 --- /dev/null +++ b/include/util/rewrite_title.hpp @@ -0,0 +1,8 @@ +#pragma once +#include + +#include + +namespace waybar::util { +std::string rewriteTitle(const std::string&, const Json::Value&); +} diff --git a/man/waybar-hyprland-window.5.scd b/man/waybar-hyprland-window.5.scd index 4be137d..0135d7c 100644 --- a/man/waybar-hyprland-window.5.scd +++ b/man/waybar-hyprland-window.5.scd @@ -17,12 +17,31 @@ Addressed by *hyprland/window* default: {} ++ The format, how information should be displayed. On {} the current window title is displayed. +*rewrite*: ++ + typeof: object ++ + Rules to rewrite window title. See *rewrite rules*. + +# REWRITE RULES + +*rewrite* is an object where keys are regular expressions and values are +rewrite rules if the expression matches. Rules may contain references to +captures of the expression. + +Regular expression and replacement follow ECMA-script rules. + +If no expression matches, the title is left unchanged. + +Invalid expressions (e.g., mismatched parentheses) are skipped. # EXAMPLES ``` "hyprland/window": { - "format": "{}" + "format": "{}", + "rewrite": { + "(.*) - Mozilla Firefox": "🌎 $1", + "(.*) - zsh": "> [$1]" + } } ``` diff --git a/meson.build b/meson.build index e537bcc..e72d99f 100644 --- a/meson.build +++ b/meson.build @@ -157,7 +157,8 @@ src_files = files( 'src/config.cpp', 'src/group.cpp', 'src/util/ustring_clen.cpp', - 'src/util/sanitize_str.cpp' + 'src/util/sanitize_str.cpp', + 'src/util/rewrite_title.cpp' ) if is_linux diff --git a/src/modules/hyprland/window.cpp b/src/modules/hyprland/window.cpp index 8d02cf3..d942cf6 100644 --- a/src/modules/hyprland/window.cpp +++ b/src/modules/hyprland/window.cpp @@ -2,11 +2,13 @@ #include +#include #include #include "modules/hyprland/backend.hpp" #include "util/command.hpp" #include "util/json.hpp" +#include "util/rewrite_title.hpp" namespace waybar::modules::hyprland { @@ -32,7 +34,8 @@ auto Window::update() -> void { if (!format_.empty()) { label_.show(); - label_.set_markup(fmt::format(format_, lastView)); + label_.set_markup( + fmt::format(format_, waybar::util::rewriteTitle(lastView, config_["rewrite"]))); } else { label_.hide(); } @@ -60,7 +63,7 @@ std::string Window::getLastWindowTitle(uint workspaceID) { return workspace["id"].as() == workspaceID; }); - if (workspace != std::end(json)) { + if (workspace == std::end(json)) { return ""; } return (*workspace)["lastwindowtitle"].as(); @@ -86,5 +89,4 @@ void Window::onEvent(const std::string& ev) { dp.emit(); } - } // namespace waybar::modules::hyprland \ No newline at end of file diff --git a/src/modules/sway/window.cpp b/src/modules/sway/window.cpp index 3d63743..5da7d3d 100644 --- a/src/modules/sway/window.cpp +++ b/src/modules/sway/window.cpp @@ -12,6 +12,8 @@ #include #include +#include "util/rewrite_title.hpp" + namespace waybar::modules::sway { Window::Window(const std::string& id, const Bar& bar, const Json::Value& config) @@ -175,8 +177,9 @@ auto Window::update() -> void { bar_.window.get_style_context()->remove_class("solo"); bar_.window.get_style_context()->remove_class("empty"); } - label_.set_markup(fmt::format(format_, fmt::arg("title", rewriteTitle(window_)), - fmt::arg("app_id", app_id_), fmt::arg("shell", shell_))); + label_.set_markup(fmt::format( + format_, fmt::arg("title", waybar::util::rewriteTitle(window_, config_["rewrite"])), + fmt::arg("app_id", app_id_), fmt::arg("shell", shell_))); if (tooltipEnabled()) { label_.set_tooltip_text(window_); } @@ -262,30 +265,4 @@ void Window::getTree() { } } -std::string Window::rewriteTitle(const std::string& title) { - const auto& rules = config_["rewrite"]; - if (!rules.isObject()) { - return title; - } - - std::string res = title; - - for (auto it = rules.begin(); it != rules.end(); ++it) { - if (it.key().isString() && it->isString()) { - try { - // malformated regexes will cause an exception. - // in this case, log error and try the next rule. - const std::regex rule{it.key().asString()}; - if (std::regex_match(title, rule)) { - res = std::regex_replace(res, rule, it->asString()); - } - } catch (const std::regex_error& e) { - spdlog::error("Invalid rule {}: {}", it.key().asString(), e.what()); - } - } - } - - return res; -} - } // namespace waybar::modules::sway diff --git a/src/util/rewrite_title.cpp b/src/util/rewrite_title.cpp new file mode 100644 index 0000000..fae59bb --- /dev/null +++ b/src/util/rewrite_title.cpp @@ -0,0 +1,32 @@ +#include "util/rewrite_title.hpp" + +#include + +#include + +namespace waybar::util { +std::string rewriteTitle(const std::string& title, const Json::Value& rules) { + if (!rules.isObject()) { + return title; + } + + std::string res = title; + + for (auto it = rules.begin(); it != rules.end(); ++it) { + if (it.key().isString() && it->isString()) { + try { + // malformated regexes will cause an exception. + // in this case, log error and try the next rule. + const std::regex rule{it.key().asString()}; + if (std::regex_match(title, rule)) { + res = std::regex_replace(res, rule, it->asString()); + } + } catch (const std::regex_error& e) { + spdlog::error("Invalid rule {}: {}", it.key().asString(), e.what()); + } + } + } + + return res; +} +} // namespace waybar::util