forked from quickshell/quickshell
		
	hyprland/ipc: re-request monitors and workspaces on fail
This commit is contained in:
		
							parent
							
								
									d14ca70984
								
							
						
					
					
						commit
						ef1a4134f0
					
				
					 2 changed files with 93 additions and 78 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue