Skip to content

Commit fb343ab

Browse files
committed
hyprland/ipc: prefer ID based workspace lookups to name based ones
Should (hopefully) reduce race condition issues.
1 parent d3b1a65 commit fb343ab

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
lines changed

src/wayland/hyprland/ipc/connection.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,8 @@ void HyprlandIpc::onEvent(HyprlandIpcEvent* event) {
342342
if (this->mFocusedMonitor != nullptr) {
343343
auto* workspace = this->findWorkspaceByName(name, true, id);
344344
this->mFocusedMonitor->setActiveWorkspace(workspace);
345-
qCDebug(logHyprlandIpc) << "Workspace" << id << "activated on" << this->mFocusedMonitor->name();
345+
qCDebug(logHyprlandIpc) << "Workspace" << id << "activated on"
346+
<< this->mFocusedMonitor->name();
346347
}
347348
} else if (event->name == "moveworkspacev2") {
348349
auto args = event->parseView(3);
@@ -377,15 +378,28 @@ void HyprlandIpc::onEvent(HyprlandIpcEvent* event) {
377378
HyprlandWorkspace*
378379
HyprlandIpc::findWorkspaceByName(const QString& name, bool createIfMissing, qint32 id) {
379380
const auto& mList = this->mWorkspaces.valueList();
381+
HyprlandWorkspace* workspace = nullptr;
380382

381-
auto workspaceIter =
382-
std::ranges::find_if(mList, [name](const HyprlandWorkspace* m) { return m->name() == name; });
383+
if (id != -1) {
384+
auto workspaceIter =
385+
std::ranges::find_if(mList, [&](const HyprlandWorkspace* m) { return m->id() == id; });
386+
387+
workspace = workspaceIter == mList.end() ? nullptr : *workspaceIter;
388+
}
383389

384-
if (workspaceIter != mList.end()) {
385-
return *workspaceIter;
390+
if (!workspace) {
391+
auto workspaceIter =
392+
std::ranges::find_if(mList, [&](const HyprlandWorkspace* m) { return m->name() == name; });
393+
394+
workspace = workspaceIter == mList.end() ? nullptr : *workspaceIter;
395+
}
396+
397+
if (workspace) {
398+
return workspace;
386399
} else if (createIfMissing) {
387400
qCDebug(logHyprlandIpc) << "Workspace" << name
388-
<< "requested before creation, performing early init";
401+
<< "requested before creation, performing early init with id" << id;
402+
389403
auto* workspace = new HyprlandWorkspace(this);
390404
workspace->updateInitial(id, name);
391405
this->mWorkspaces.insertObject(workspace);
@@ -414,9 +428,8 @@ void HyprlandIpc::refreshWorkspaces(bool canCreate) {
414428

415429
auto id = object.value("id").toInt();
416430

417-
auto workspaceIter = std::ranges::find_if(mList, [&](const HyprlandWorkspace* m) {
418-
return m->id() == id;
419-
});
431+
auto workspaceIter =
432+
std::ranges::find_if(mList, [&](const HyprlandWorkspace* m) { return m->id() == id; });
420433

421434
// Only fall back to name-based filtering as a last resort, for workspaces where
422435
// no ID has been determined yet.

src/wayland/hyprland/ipc/connection.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class HyprlandIpc: public QObject {
8181
[[nodiscard]] ObjectModel<HyprlandWorkspace>* workspaces();
8282

8383
// No byId because these preemptively create objects. The given id is set if created.
84-
HyprlandWorkspace* findWorkspaceByName(const QString& name, bool createIfMissing, qint32 id = 0);
84+
HyprlandWorkspace* findWorkspaceByName(const QString& name, bool createIfMissing, qint32 id = -1);
8585
HyprlandMonitor* findMonitorByName(const QString& name, bool createIfMissing, qint32 id = -1);
8686

8787
// canCreate avoids making ghost workspaces when the connection races

src/wayland/hyprland/ipc/workspace.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ void HyprlandWorkspace::updateInitial(qint32 id, QString name) {
3535
}
3636

3737
void HyprlandWorkspace::updateFromObject(QVariantMap object) {
38+
auto name = object.value("name").value<QString>();
3839
auto monitorId = object.value("monitorID").value<qint32>();
3940
auto monitorName = object.value("monitor").value<QString>();
4041

@@ -48,8 +49,8 @@ void HyprlandWorkspace::updateFromObject(QVariantMap object) {
4849

4950
// No events we currently handle give a workspace id but not a name,
5051
// so we shouldn't set this if it isn't an initial query
51-
if (initial) {
52-
this->mName = object.value("name").value<QString>();
52+
if (initial && name != this->mName) {
53+
this->mName = name;
5354
emit this->nameChanged();
5455
}
5556

0 commit comments

Comments
 (0)