hyprland/window: fix crash when no return from socket

Gracefully handle lack of response from the IPC. If socket isn't
available, we already log the IPC isn't running. We dont need to crash
program just because we couldn't get responses. We can just return an
empty object.
This commit is contained in:
Austin Horstman 2024-07-15 08:44:26 -05:00
parent 0a78da0315
commit b41fcdedff
No known key found for this signature in database
1 changed files with 71 additions and 61 deletions

View File

@ -92,30 +92,39 @@ auto Window::update() -> void {
auto Window::getActiveWorkspace() -> Workspace { auto Window::getActiveWorkspace() -> Workspace {
const auto workspace = gIPC->getSocket1JsonReply("activeworkspace"); const auto workspace = gIPC->getSocket1JsonReply("activeworkspace");
assert(workspace.isObject());
return Workspace::parse(workspace); if (workspace.isObject()) {
return Workspace::parse(workspace);
}
return {};
} }
auto Window::getActiveWorkspace(const std::string& monitorName) -> Workspace { auto Window::getActiveWorkspace(const std::string& monitorName) -> Workspace {
const auto monitors = gIPC->getSocket1JsonReply("monitors"); const auto monitors = gIPC->getSocket1JsonReply("monitors");
assert(monitors.isArray()); if (monitors.isArray()) {
auto monitor = std::find_if(monitors.begin(), monitors.end(), auto monitor = std::find_if(monitors.begin(), monitors.end(), [&](Json::Value monitor) {
[&](Json::Value monitor) { return monitor["name"] == monitorName; }); return monitor["name"] == monitorName;
if (monitor == std::end(monitors)) { });
spdlog::warn("Monitor not found: {}", monitorName); if (monitor == std::end(monitors)) {
return Workspace{-1, 0, "", ""}; spdlog::warn("Monitor not found: {}", monitorName);
} return Workspace{-1, 0, "", ""};
const int id = (*monitor)["activeWorkspace"]["id"].asInt(); }
const int id = (*monitor)["activeWorkspace"]["id"].asInt();
const auto workspaces = gIPC->getSocket1JsonReply("workspaces"); const auto workspaces = gIPC->getSocket1JsonReply("workspaces");
assert(workspaces.isArray()); if (workspaces.isArray()) {
auto workspace = std::find_if(workspaces.begin(), workspaces.end(), auto workspace = std::find_if(workspaces.begin(), workspaces.end(),
[&](Json::Value workspace) { return workspace["id"] == id; }); [&](Json::Value workspace) { return workspace["id"] == id; });
if (workspace == std::end(workspaces)) { if (workspace == std::end(workspaces)) {
spdlog::warn("No workspace with id {}", id); spdlog::warn("No workspace with id {}", id);
return Workspace{-1, 0, "", ""}; return Workspace{-1, 0, "", ""};
} }
return Workspace::parse(*workspace); return Workspace::parse(*workspace);
};
};
return {};
} }
auto Window::Workspace::parse(const Json::Value& value) -> Window::Workspace { auto Window::Workspace::parse(const Json::Value& value) -> Window::Workspace {
@ -146,53 +155,54 @@ void Window::queryActiveWorkspace() {
focused_ = true; focused_ = true;
if (workspace_.windows > 0) { if (workspace_.windows > 0) {
const auto clients = gIPC->getSocket1JsonReply("clients"); const auto clients = gIPC->getSocket1JsonReply("clients");
assert(clients.isArray()); if (clients.isArray()) {
auto activeWindow = std::find_if(clients.begin(), clients.end(), [&](Json::Value window) { auto activeWindow = std::find_if(clients.begin(), clients.end(), [&](Json::Value window) {
return window["address"] == workspace_.last_window; return window["address"] == workspace_.last_window;
}); });
if (activeWindow == std::end(clients)) { if (activeWindow == std::end(clients)) {
focused_ = false; focused_ = false;
return; return;
} }
windowData_ = WindowData::parse(*activeWindow); windowData_ = WindowData::parse(*activeWindow);
updateAppIconName(windowData_.class_name, windowData_.initial_class_name); updateAppIconName(windowData_.class_name, windowData_.initial_class_name);
std::vector<Json::Value> workspaceWindows; std::vector<Json::Value> workspaceWindows;
std::copy_if(clients.begin(), clients.end(), std::back_inserter(workspaceWindows), std::copy_if(clients.begin(), clients.end(), std::back_inserter(workspaceWindows),
[&](Json::Value window) { [&](Json::Value window) {
return window["workspace"]["id"] == workspace_.id && window["mapped"].asBool(); return window["workspace"]["id"] == workspace_.id && window["mapped"].asBool();
}); });
swallowing_ = swallowing_ =
std::any_of(workspaceWindows.begin(), workspaceWindows.end(), [&](Json::Value window) { std::any_of(workspaceWindows.begin(), workspaceWindows.end(), [&](Json::Value window) {
return !window["swallowing"].isNull() && window["swallowing"].asString() != "0x0"; return !window["swallowing"].isNull() && window["swallowing"].asString() != "0x0";
}); });
std::vector<Json::Value> visibleWindows; std::vector<Json::Value> visibleWindows;
std::copy_if(workspaceWindows.begin(), workspaceWindows.end(), std::copy_if(workspaceWindows.begin(), workspaceWindows.end(),
std::back_inserter(visibleWindows), std::back_inserter(visibleWindows),
[&](Json::Value window) { return !window["hidden"].asBool(); }); [&](Json::Value window) { return !window["hidden"].asBool(); });
solo_ = 1 == std::count_if(visibleWindows.begin(), visibleWindows.end(), solo_ = 1 == std::count_if(visibleWindows.begin(), visibleWindows.end(),
[&](Json::Value window) { return !window["floating"].asBool(); }); [&](Json::Value window) { return !window["floating"].asBool(); });
allFloating_ = std::all_of(visibleWindows.begin(), visibleWindows.end(), allFloating_ = std::all_of(visibleWindows.begin(), visibleWindows.end(),
[&](Json::Value window) { return window["floating"].asBool(); }); [&](Json::Value window) { return window["floating"].asBool(); });
fullscreen_ = windowData_.fullscreen; fullscreen_ = windowData_.fullscreen;
// Fullscreen windows look like they are solo // Fullscreen windows look like they are solo
if (fullscreen_) { if (fullscreen_) {
solo_ = true; solo_ = true;
} }
// Grouped windows have a tab bar and therefore don't look fullscreen or solo // Grouped windows have a tab bar and therefore don't look fullscreen or solo
if (windowData_.grouped) { if (windowData_.grouped) {
fullscreen_ = false; fullscreen_ = false;
solo_ = false; solo_ = false;
} }
if (solo_) { if (solo_) {
soloClass_ = windowData_.class_name; soloClass_ = windowData_.class_name;
} else { } else {
soloClass_ = ""; soloClass_ = "";
} }
};
} else { } else {
focused_ = false; focused_ = false;
windowData_ = WindowData{}; windowData_ = WindowData{};