fix(AModule): don't crash on click/scroll commands with literal braces
handleUserEvent ran the configured command through fmt::format(fmt::runtime(...))
to substitute {x}/{y}. Commands containing literal braces that aren't {x}/{y}
(e.g. `echo ${HOME}`, `awk '{print $1}'`, brace expansions) made libfmt throw
fmt::format_error. Uncaught inside a GTK signal handler this aborts the whole bar.
Only format when {x}/{y} is present and fall back to the raw command on failure.
Fixes bar abort/std::terminate on on-click/on-scroll commands containing braces.
This commit is contained in:
+17
-3
@@ -238,9 +238,23 @@ bool AModule::handleUserEvent(GdkEventButton* const& e) {
|
|||||||
if (!format.empty()) {
|
if (!format.empty()) {
|
||||||
const int width = gdk_window_get_width(e->window);
|
const int width = gdk_window_get_width(e->window);
|
||||||
const int height = gdk_window_get_height(e->window);
|
const int height = gdk_window_get_height(e->window);
|
||||||
const std::string cmd =
|
// Substitute {x}/{y} with the click position. The configured command is
|
||||||
fmt::format(fmt::runtime(format), fmt::arg("x", (int)round(100. * e->x / width)),
|
// arbitrary user input that may contain literal braces which are not {x}/{y}
|
||||||
fmt::arg("y", (int)round(100. * e->y / height)));
|
// (e.g. `echo ${HOME}`, `awk '{print $1}'`, brace expansions). Those make
|
||||||
|
// libfmt throw fmt::format_error; since we run inside a GTK signal handler an
|
||||||
|
// uncaught exception aborts the whole bar. Only format when a placeholder is
|
||||||
|
// actually present, and fall back to the raw command if formatting throws.
|
||||||
|
std::string cmd = format;
|
||||||
|
if (format.find("{x}") != std::string::npos || format.find("{y}") != std::string::npos) {
|
||||||
|
try {
|
||||||
|
cmd = fmt::format(fmt::runtime(format), fmt::arg("x", (int)round(100. * e->x / width)),
|
||||||
|
fmt::arg("y", (int)round(100. * e->y / height)));
|
||||||
|
} catch (const fmt::format_error& err) {
|
||||||
|
spdlog::warn("Failed to format command '{}': {}. Running it unformatted.", format,
|
||||||
|
err.what());
|
||||||
|
cmd = format;
|
||||||
|
}
|
||||||
|
}
|
||||||
pid_children_.push_back(util::command::forkExec(cmd));
|
pid_children_.push_back(util::command::forkExec(cmd));
|
||||||
}
|
}
|
||||||
dp.emit();
|
dp.emit();
|
||||||
|
|||||||
Reference in New Issue
Block a user