1
0
Fork 0

hyprland/ipc: prefer ID based workspace lookups to name based ones

Should (hopefully) reduce race condition issues.
This commit is contained in:
outfoxxed 2025-01-27 22:19:28 -08:00
parent d3b1a65911
commit fb343ab639
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
3 changed files with 26 additions and 12 deletions

View file

@ -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.

View file

@ -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

View file

@ -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();
} }