forked from quickshell/quickshell
		
	hyprland/ipc: prefer ID based workspace lookups to name based ones
Should (hopefully) reduce race condition issues.
This commit is contained in:
		
							parent
							
								
									d3b1a65911
								
							
						
					
					
						commit
						fb343ab639
					
				
					 3 changed files with 26 additions and 12 deletions
				
			
		| 
						 | 
					@ -342,7 +342,8 @@ void HyprlandIpc::onEvent(HyprlandIpcEvent* event) {
 | 
				
			||||||
		if (this->mFocusedMonitor != nullptr) {
 | 
							if (this->mFocusedMonitor != nullptr) {
 | 
				
			||||||
			auto* workspace = this->findWorkspaceByName(name, true, id);
 | 
								auto* workspace = this->findWorkspaceByName(name, true, id);
 | 
				
			||||||
			this->mFocusedMonitor->setActiveWorkspace(workspace);
 | 
								this->mFocusedMonitor->setActiveWorkspace(workspace);
 | 
				
			||||||
			qCDebug(logHyprlandIpc) << "Workspace" << id << "activated on" << this->mFocusedMonitor->name();
 | 
								qCDebug(logHyprlandIpc) << "Workspace" << id << "activated on"
 | 
				
			||||||
 | 
								                        << this->mFocusedMonitor->name();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (event->name == "moveworkspacev2") {
 | 
						} else if (event->name == "moveworkspacev2") {
 | 
				
			||||||
		auto args = event->parseView(3);
 | 
							auto args = event->parseView(3);
 | 
				
			||||||
| 
						 | 
					@ -377,15 +378,28 @@ void HyprlandIpc::onEvent(HyprlandIpcEvent* event) {
 | 
				
			||||||
HyprlandWorkspace*
 | 
					HyprlandWorkspace*
 | 
				
			||||||
HyprlandIpc::findWorkspaceByName(const QString& name, bool createIfMissing, qint32 id) {
 | 
					HyprlandIpc::findWorkspaceByName(const QString& name, bool createIfMissing, qint32 id) {
 | 
				
			||||||
	const auto& mList = this->mWorkspaces.valueList();
 | 
						const auto& mList = this->mWorkspaces.valueList();
 | 
				
			||||||
 | 
						HyprlandWorkspace* workspace = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto workspaceIter =
 | 
						if (id != -1) {
 | 
				
			||||||
	    std::ranges::find_if(mList, [name](const HyprlandWorkspace* m) { return m->name() == name; });
 | 
							auto workspaceIter =
 | 
				
			||||||
 | 
							    std::ranges::find_if(mList, [&](const HyprlandWorkspace* m) { return m->id() == id; });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (workspaceIter != mList.end()) {
 | 
							workspace = workspaceIter == mList.end() ? nullptr : *workspaceIter;
 | 
				
			||||||
		return *workspaceIter;
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!workspace) {
 | 
				
			||||||
 | 
							auto workspaceIter =
 | 
				
			||||||
 | 
							    std::ranges::find_if(mList, [&](const HyprlandWorkspace* m) { return m->name() == name; });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							workspace = workspaceIter == mList.end() ? nullptr : *workspaceIter;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (workspace) {
 | 
				
			||||||
 | 
							return workspace;
 | 
				
			||||||
	} else if (createIfMissing) {
 | 
						} else if (createIfMissing) {
 | 
				
			||||||
		qCDebug(logHyprlandIpc) << "Workspace" << name
 | 
							qCDebug(logHyprlandIpc) << "Workspace" << name
 | 
				
			||||||
		                        << "requested before creation, performing early init";
 | 
							                        << "requested before creation, performing early init with id" << id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto* workspace = new HyprlandWorkspace(this);
 | 
							auto* workspace = new HyprlandWorkspace(this);
 | 
				
			||||||
		workspace->updateInitial(id, name);
 | 
							workspace->updateInitial(id, name);
 | 
				
			||||||
		this->mWorkspaces.insertObject(workspace);
 | 
							this->mWorkspaces.insertObject(workspace);
 | 
				
			||||||
| 
						 | 
					@ -414,9 +428,8 @@ void HyprlandIpc::refreshWorkspaces(bool canCreate) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto id = object.value("id").toInt();
 | 
								auto id = object.value("id").toInt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto workspaceIter = std::ranges::find_if(mList, [&](const HyprlandWorkspace* m) {
 | 
								auto workspaceIter =
 | 
				
			||||||
				return m->id() == id;
 | 
								    std::ranges::find_if(mList, [&](const HyprlandWorkspace* m) { return m->id() == id; });
 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Only fall back to name-based filtering as a last resort, for workspaces where
 | 
								// Only fall back to name-based filtering as a last resort, for workspaces where
 | 
				
			||||||
			// no ID has been determined yet.
 | 
								// no ID has been determined yet.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,7 +81,7 @@ public:
 | 
				
			||||||
	[[nodiscard]] ObjectModel<HyprlandWorkspace>* workspaces();
 | 
						[[nodiscard]] ObjectModel<HyprlandWorkspace>* workspaces();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// No byId because these preemptively create objects. The given id is set if created.
 | 
						// No byId because these preemptively create objects. The given id is set if created.
 | 
				
			||||||
	HyprlandWorkspace* findWorkspaceByName(const QString& name, bool createIfMissing, qint32 id = 0);
 | 
						HyprlandWorkspace* findWorkspaceByName(const QString& name, bool createIfMissing, qint32 id = -1);
 | 
				
			||||||
	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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,7 @@ void HyprlandWorkspace::updateInitial(qint32 id, QString name) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HyprlandWorkspace::updateFromObject(QVariantMap object) {
 | 
					void HyprlandWorkspace::updateFromObject(QVariantMap object) {
 | 
				
			||||||
 | 
						auto name = object.value("name").value<QString>();
 | 
				
			||||||
	auto monitorId = object.value("monitorID").value<qint32>();
 | 
						auto monitorId = object.value("monitorID").value<qint32>();
 | 
				
			||||||
	auto monitorName = object.value("monitor").value<QString>();
 | 
						auto monitorName = object.value("monitor").value<QString>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,8 +49,8 @@ void HyprlandWorkspace::updateFromObject(QVariantMap object) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// No events we currently handle give a workspace id but not a name,
 | 
						// No events we currently handle give a workspace id but not a name,
 | 
				
			||||||
	// so we shouldn't set this if it isn't an initial query
 | 
						// so we shouldn't set this if it isn't an initial query
 | 
				
			||||||
	if (initial) {
 | 
						if (initial && name != this->mName) {
 | 
				
			||||||
		this->mName = object.value("name").value<QString>();
 | 
							this->mName = name;
 | 
				
			||||||
		emit this->nameChanged();
 | 
							emit this->nameChanged();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue