forked from quickshell/quickshell
hyprland/ipc: re-request monitors and workspaces on fail
This commit is contained in:
parent
d14ca70984
commit
ef1a4134f0
|
@ -377,59 +377,66 @@ HyprlandIpc::findWorkspaceByName(const QString& name, bool createIfMissing, qint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HyprlandIpc::refreshWorkspaces(bool canCreate) {
|
void HyprlandIpc::refreshWorkspaces(bool canCreate, bool tryAgain) {
|
||||||
if (this->requestingWorkspaces) return;
|
if (this->requestingWorkspaces) return;
|
||||||
this->requestingWorkspaces = true;
|
this->requestingWorkspaces = true;
|
||||||
|
|
||||||
this->makeRequest("j/workspaces", [this, canCreate](bool success, const QByteArray& resp) {
|
this->makeRequest(
|
||||||
this->requestingWorkspaces = false;
|
"j/workspaces",
|
||||||
if (!success) return;
|
[this, canCreate, tryAgain](bool success, const QByteArray& resp) {
|
||||||
|
this->requestingWorkspaces = false;
|
||||||
|
if (!success) {
|
||||||
|
// sometimes fails randomly, so we give it another shot.
|
||||||
|
if (tryAgain) this->refreshWorkspaces(canCreate, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
qCDebug(logHyprlandIpc) << "parsing workspaces response";
|
qCDebug(logHyprlandIpc) << "parsing workspaces response";
|
||||||
auto json = QJsonDocument::fromJson(resp).array();
|
auto json = QJsonDocument::fromJson(resp).array();
|
||||||
|
|
||||||
const auto& mList = this->mWorkspaces.valueList();
|
const auto& mList = this->mWorkspaces.valueList();
|
||||||
auto names = QVector<QString>();
|
auto names = QVector<QString>();
|
||||||
|
|
||||||
for (auto entry: json) {
|
for (auto entry: json) {
|
||||||
auto object = entry.toObject().toVariantMap();
|
auto object = entry.toObject().toVariantMap();
|
||||||
auto name = object.value("name").toString();
|
auto name = object.value("name").toString();
|
||||||
|
|
||||||
auto workspaceIter =
|
auto workspaceIter =
|
||||||
std::find_if(mList.begin(), mList.end(), [name](const HyprlandWorkspace* m) {
|
std::find_if(mList.begin(), mList.end(), [name](const HyprlandWorkspace* m) {
|
||||||
return m->name() == name;
|
return m->name() == name;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* workspace = workspaceIter == mList.end() ? nullptr : *workspaceIter;
|
auto* workspace = workspaceIter == mList.end() ? nullptr : *workspaceIter;
|
||||||
auto existed = workspace != nullptr;
|
auto existed = workspace != nullptr;
|
||||||
|
|
||||||
if (workspace == nullptr) {
|
if (workspace == nullptr) {
|
||||||
if (!canCreate) continue;
|
if (!canCreate) continue;
|
||||||
workspace = new HyprlandWorkspace(this);
|
workspace = new HyprlandWorkspace(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
workspace->updateFromObject(object);
|
workspace->updateFromObject(object);
|
||||||
|
|
||||||
if (!existed) {
|
if (!existed) {
|
||||||
this->mWorkspaces.insertObject(workspace);
|
this->mWorkspaces.insertObject(workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
names.push_back(name);
|
names.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto removedWorkspaces = QVector<HyprlandWorkspace*>();
|
auto removedWorkspaces = QVector<HyprlandWorkspace*>();
|
||||||
|
|
||||||
for (auto* workspace: mList) {
|
for (auto* workspace: mList) {
|
||||||
if (!names.contains(workspace->name())) {
|
if (!names.contains(workspace->name())) {
|
||||||
removedWorkspaces.push_back(workspace);
|
removedWorkspaces.push_back(workspace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto* workspace: removedWorkspaces) {
|
for (auto* workspace: removedWorkspaces) {
|
||||||
this->mWorkspaces.removeObject(workspace);
|
this->mWorkspaces.removeObject(workspace);
|
||||||
delete workspace;
|
delete workspace;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HyprlandMonitor*
|
HyprlandMonitor*
|
||||||
|
@ -484,59 +491,67 @@ void HyprlandIpc::onFocusedMonitorDestroyed() {
|
||||||
emit this->focusedMonitorChanged();
|
emit this->focusedMonitorChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HyprlandIpc::refreshMonitors(bool canCreate) {
|
void HyprlandIpc::refreshMonitors(bool canCreate, bool tryAgain) {
|
||||||
if (this->requestingMonitors) return;
|
if (this->requestingMonitors) return;
|
||||||
this->requestingMonitors = true;
|
this->requestingMonitors = true;
|
||||||
|
|
||||||
this->makeRequest("j/monitors", [this, canCreate](bool success, const QByteArray& resp) {
|
this->makeRequest(
|
||||||
this->requestingMonitors = false;
|
"j/monitors",
|
||||||
if (!success) return;
|
[this, canCreate, tryAgain](bool success, const QByteArray& resp) {
|
||||||
|
this->requestingMonitors = false;
|
||||||
|
if (!success) {
|
||||||
|
// sometimes fails randomly, so we give it another shot.
|
||||||
|
if (tryAgain) this->refreshMonitors(canCreate, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
qCDebug(logHyprlandIpc) << "parsing monitors response";
|
qCDebug(logHyprlandIpc) << "parsing monitors response";
|
||||||
auto json = QJsonDocument::fromJson(resp).array();
|
auto json = QJsonDocument::fromJson(resp).array();
|
||||||
|
|
||||||
const auto& mList = this->mMonitors.valueList();
|
const auto& mList = this->mMonitors.valueList();
|
||||||
auto ids = QVector<qint32>();
|
auto ids = QVector<qint32>();
|
||||||
|
|
||||||
for (auto entry: json) {
|
for (auto entry: json) {
|
||||||
auto object = entry.toObject().toVariantMap();
|
auto object = entry.toObject().toVariantMap();
|
||||||
auto id = object.value("id").toInt();
|
auto id = object.value("id").toInt();
|
||||||
|
|
||||||
auto monitorIter = std::find_if(mList.begin(), mList.end(), [id](const HyprlandMonitor* m) {
|
auto monitorIter =
|
||||||
return m->id() == id;
|
std::find_if(mList.begin(), mList.end(), [id](const HyprlandMonitor* m) {
|
||||||
});
|
return m->id() == id;
|
||||||
|
});
|
||||||
|
|
||||||
auto* monitor = monitorIter == mList.end() ? nullptr : *monitorIter;
|
auto* monitor = monitorIter == mList.end() ? nullptr : *monitorIter;
|
||||||
auto existed = monitor != nullptr;
|
auto existed = monitor != nullptr;
|
||||||
|
|
||||||
if (monitor == nullptr) {
|
if (monitor == nullptr) {
|
||||||
if (!canCreate) continue;
|
if (!canCreate) continue;
|
||||||
monitor = new HyprlandMonitor(this);
|
monitor = new HyprlandMonitor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor->updateFromObject(object);
|
monitor->updateFromObject(object);
|
||||||
|
|
||||||
if (!existed) {
|
if (!existed) {
|
||||||
this->mMonitors.insertObject(monitor);
|
this->mMonitors.insertObject(monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
ids.push_back(id);
|
ids.push_back(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto removedMonitors = QVector<HyprlandMonitor*>();
|
auto removedMonitors = QVector<HyprlandMonitor*>();
|
||||||
|
|
||||||
for (auto* monitor: mList) {
|
for (auto* monitor: mList) {
|
||||||
if (!ids.contains(monitor->id())) {
|
if (!ids.contains(monitor->id())) {
|
||||||
removedMonitors.push_back(monitor);
|
removedMonitors.push_back(monitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto* monitor: removedMonitors) {
|
for (auto* monitor: removedMonitors) {
|
||||||
this->mMonitors.removeObject(monitor);
|
this->mMonitors.removeObject(monitor);
|
||||||
// see comment in onEvent
|
// see comment in onEvent
|
||||||
monitor->deleteLater();
|
monitor->deleteLater();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace qs::hyprland::ipc
|
} // namespace qs::hyprland::ipc
|
||||||
|
|
|
@ -81,8 +81,8 @@ public:
|
||||||
HyprlandMonitor* findMonitorByName(const QString& name, bool createIfMissing, qint32 id = -1);
|
HyprlandMonitor* findMonitorByName(const QString& name, bool createIfMissing, qint32 id = -1);
|
||||||
|
|
||||||
// canCreate avoids making ghost workspaces when the connection races
|
// canCreate avoids making ghost workspaces when the connection races
|
||||||
void refreshWorkspaces(bool canCreate);
|
void refreshWorkspaces(bool canCreate, bool tryAgain = true);
|
||||||
void refreshMonitors(bool canCreate);
|
void refreshMonitors(bool canCreate, bool tryAgain = true);
|
||||||
|
|
||||||
// The last argument may contain commas, so the count is required.
|
// The last argument may contain commas, so the count is required.
|
||||||
[[nodiscard]] static QVector<QByteArrayView> parseEventArgs(QByteArrayView event, quint16 count);
|
[[nodiscard]] static QVector<QByteArrayView> parseEventArgs(QByteArrayView event, quint16 count);
|
||||||
|
|
Loading…
Reference in a new issue