The language and submap modules assumed their Hyprland payload delimiters were always present. When that assumption is violated, the old code could perform invalid iterator math or throw while slicing the event string. Validate the expected separators up front and bail out with a warning when the event is malformed so the modules degrade safely instead of crashing the update path. Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
96 lines
2.2 KiB
C++
96 lines
2.2 KiB
C++
#include "modules/hyprland/submap.hpp"
|
|
|
|
#include <spdlog/spdlog.h>
|
|
|
|
namespace waybar::modules::hyprland {
|
|
|
|
Submap::Submap(const std::string& id, const Bar& bar, const Json::Value& config)
|
|
: ALabel(config, "submap", id, "{}", 0, true), bar_(bar), m_ipc(IPC::inst()) {
|
|
parseConfig(config);
|
|
|
|
label_.hide();
|
|
ALabel::update();
|
|
|
|
// Displays widget immediately if always_on_ assuming default submap
|
|
// Needs an actual way to retrieve current submap on startup
|
|
if (always_on_) {
|
|
submap_ = default_submap_;
|
|
label_.get_style_context()->add_class(submap_);
|
|
}
|
|
|
|
// register for hyprland ipc
|
|
m_ipc.registerForIPC("submap", this);
|
|
dp.emit();
|
|
}
|
|
|
|
Submap::~Submap() {
|
|
m_ipc.unregisterForIPC(this);
|
|
// wait for possible event handler to finish
|
|
std::lock_guard<std::mutex> lg(mutex_);
|
|
}
|
|
|
|
auto Submap::parseConfig(const Json::Value& config) -> void {
|
|
auto const& alwaysOn = config["always-on"];
|
|
if (alwaysOn.isBool()) {
|
|
always_on_ = alwaysOn.asBool();
|
|
}
|
|
|
|
auto const& defaultSubmap = config["default-submap"];
|
|
if (defaultSubmap.isString()) {
|
|
default_submap_ = defaultSubmap.asString();
|
|
}
|
|
}
|
|
|
|
auto Submap::update() -> void {
|
|
std::lock_guard<std::mutex> lg(mutex_);
|
|
|
|
// Handle style class changes
|
|
if (!prev_submap_.empty()) {
|
|
label_.get_style_context()->remove_class(prev_submap_);
|
|
}
|
|
|
|
if (!submap_.empty()) {
|
|
label_.get_style_context()->add_class(submap_);
|
|
}
|
|
|
|
prev_submap_ = submap_;
|
|
|
|
if (submap_.empty()) {
|
|
event_box_.hide();
|
|
} else {
|
|
label_.set_markup(fmt::format(fmt::runtime(format_), submap_));
|
|
if (tooltipEnabled()) {
|
|
label_.set_tooltip_markup(submap_);
|
|
}
|
|
event_box_.show();
|
|
}
|
|
// Call parent update
|
|
ALabel::update();
|
|
}
|
|
|
|
void Submap::onEvent(const std::string& ev) {
|
|
std::lock_guard<std::mutex> lg(mutex_);
|
|
|
|
if (ev.find("submap") == std::string::npos) {
|
|
return;
|
|
}
|
|
|
|
const auto separator = ev.find(">>");
|
|
if (separator == std::string::npos) {
|
|
spdlog::warn("hyprland submap received malformed event: {}", ev);
|
|
return;
|
|
}
|
|
auto submapName = ev.substr(separator + 2);
|
|
|
|
submap_ = submapName;
|
|
|
|
if (submap_.empty() && always_on_) {
|
|
submap_ = default_submap_;
|
|
}
|
|
|
|
spdlog::debug("hyprland submap onevent with {}", submap_);
|
|
|
|
dp.emit();
|
|
}
|
|
} // namespace waybar::modules::hyprland
|