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_;
|
||||
}
|
||||
|
||||
// Probe: send a harmless old-style dispatch and check the error.
|
||||
// In Lua-based Hyprland (>= 0.54) the error contains "hl.dispatch".
|
||||
// In older versions it returns "ok" or a different error.
|
||||
auto reply = getSocket1Reply("dispatch workspace __waybar_probe__");
|
||||
bool luaProto = reply.find("hl.dispatch") != std::string::npos;
|
||||
// Detect the Lua-based dispatch protocol (Hyprland >= 0.54) via the read-only
|
||||
// "version" query. This MUST have no side effects: an earlier probe issued a real
|
||||
// "dispatch workspace __waybar_probe__", which on Hyprland < 0.54 actually switched
|
||||
// the user to a junk workspace named __waybar_probe__ on the first click/scroll.
|
||||
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) {
|
||||
spdlog::info("Hyprland IPC: detected Lua-based dispatch protocol (Hyprland >= 0.54)");
|
||||
|
||||
Reference in New Issue
Block a user