diff --git a/src/app/main.cpp b/src/app/main.cpp index 1cc5680..1088e71 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -7,6 +7,8 @@ #include "screencast/network/discovery.h" #include "screencast/network/signaling.h" +#include + #include #include @@ -205,10 +207,19 @@ void spawn_detached_sender(const std::string& peer, int bitrate_kbps) { void print_waybar_status() { const auto state = sc::read_sender_state(); + + // Built with nlohmann::json so all escaping (newlines in tooltips, + // non-ASCII characters) is handled correctly. Hand-rolled format + // strings produced literal control characters that broke waybar's + // JSON parser. + nlohmann::json json = nlohmann::json::object(); + if (!state.has_value()) { - std::cout << std::format("{{\"text\":\"\u23f8\",\"alt\":\"idle\",\"class\":\"idle\"," - "\"tooltip\":\"screencast idle \u2014 click to stream to the last receiver\n" - "right-click: open the panel\"}}\n"); + json["text"] = "\u23f8"; // pause symbol + json["alt"] = "idle"; + json["class"] = "idle"; + json["tooltip"] = "screencast idle \u2014 click to stream to the last receiver\nright-click: open the panel"; + std::cout << json.dump() << '\n'; return; } @@ -218,13 +229,17 @@ void print_waybar_status() { state->started_epoch_ms; const std::int64_t minutes = elapsed_ms / 60000; const std::int64_t seconds = (elapsed_ms / 1000) % 60; - std::cout << std::format("{{\"text\":\"\u25b6\",\"alt\":\"streaming\",\"class\":\"streaming\"," - "\"tooltip\":\"screencast \u2192 {}\\n{} kbps \u00b7 {}m {:02}s\\nsession {}\"}}\n", - state->receiver, - state->bitrate_kbps, - minutes, - seconds, - state->session_id); + + json["text"] = "\u25b6"; // play symbol + json["alt"] = "streaming"; + json["class"] = "streaming"; + json["tooltip"] = std::format("screencast \u2192 {}\n{} kbps \u00b7 {}m {:02}s\nsession {}", + state->receiver, + state->bitrate_kbps, + minutes, + seconds, + state->session_id); + std::cout << json.dump() << '\n'; } int run_waybar(const sc::WaybarCommand& command) {