fix(hyprland): detect Lua protocol without side-effecting dispatch
isLuaProtocol() probed the protocol by sending a real "dispatch workspace __waybar_probe__". On Hyprland < 0.54 "workspace" is a valid dispatcher, so the probe actually switched the user to a junk workspace named __waybar_probe__ on the first workspace click/scroll. Detect the protocol with the read-only "version" IPC query instead: parse the numeric "version" field (falling back to the always-present "tag" field) and treat Hyprland >= 0.54 as Lua. This has no side effects. On any parse/query failure we log and fall back to the legacy protocol, preserving prior behavior for older versions.
This commit is contained in:
@@ -297,11 +297,40 @@ bool IPC::isLuaProtocol() {
|
|||||||
return *s_luaProtocolDetected_;
|
return *s_luaProtocolDetected_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Probe: send a harmless old-style dispatch and check the error.
|
// Detect the Lua-based dispatch protocol (Hyprland >= 0.54) via the read-only
|
||||||
// In Lua-based Hyprland (>= 0.54) the error contains "hl.dispatch".
|
// "version" query. This MUST have no side effects: an earlier probe issued a real
|
||||||
// In older versions it returns "ok" or a different error.
|
// "dispatch workspace __waybar_probe__", which on Hyprland < 0.54 actually switched
|
||||||
auto reply = getSocket1Reply("dispatch workspace __waybar_probe__");
|
// the user to a junk workspace named __waybar_probe__ on the first click/scroll.
|
||||||
bool luaProto = reply.find("hl.dispatch") != std::string::npos;
|
bool luaProto = false;
|
||||||
|
try {
|
||||||
|
util::JsonParser parser;
|
||||||
|
const Json::Value ver = parser.parse(getSocket1Reply("j/version"));
|
||||||
|
|
||||||
|
// Prefer the numeric "version" field ("0.54.0"); fall back to the "tag" field
|
||||||
|
// ("v0.54.0" or "v0.54.0-16-gdeadbee"), which is present on all releases.
|
||||||
|
std::string versionStr = ver["version"].asString();
|
||||||
|
if (versionStr.empty()) {
|
||||||
|
versionStr = ver["tag"].asString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t firstDigit = versionStr.find_first_of("0123456789");
|
||||||
|
if (firstDigit != std::string::npos) {
|
||||||
|
// std::stoi parses the leading integer and stops at the first non-digit, so it
|
||||||
|
// tolerates the trailing ".patch-commits-ghash" suffix on the tag.
|
||||||
|
const int major = std::stoi(versionStr.substr(firstDigit));
|
||||||
|
int minor = 0;
|
||||||
|
const size_t dot = versionStr.find('.', firstDigit);
|
||||||
|
if (dot != std::string::npos && dot + 1 < versionStr.size()) {
|
||||||
|
minor = std::stoi(versionStr.substr(dot + 1));
|
||||||
|
}
|
||||||
|
luaProto = major > 0 || (major == 0 && minor >= 54);
|
||||||
|
} else {
|
||||||
|
spdlog::warn("Hyprland IPC: could not parse version '{}', assuming legacy protocol",
|
||||||
|
versionStr);
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::warn("Hyprland IPC: version detection failed ({}), assuming legacy protocol", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
if (luaProto) {
|
if (luaProto) {
|
||||||
spdlog::info("Hyprland IPC: detected Lua-based dispatch protocol (Hyprland >= 0.54)");
|
spdlog::info("Hyprland IPC: detected Lua-based dispatch protocol (Hyprland >= 0.54)");
|
||||||
|
|||||||
Reference in New Issue
Block a user