From 14aa1793df499e02b72d3ecd6f4461f0b2befa37 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Thu, 27 Mar 2025 15:56:53 -0700 Subject: [PATCH] i3/ipc: fix workspace and monitor focus being unset on launch --- src/x11/i3/ipc/connection.cpp | 20 ++++++++++++++++++-- src/x11/i3/ipc/connection.hpp | 2 +- src/x11/i3/ipc/monitor.cpp | 7 ++++--- src/x11/i3/ipc/monitor.hpp | 1 + src/x11/i3/ipc/workspace.cpp | 5 ++--- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/x11/i3/ipc/connection.cpp b/src/x11/i3/ipc/connection.cpp index 774c2c98..3c1015fa 100644 --- a/src/x11/i3/ipc/connection.cpp +++ b/src/x11/i3/ipc/connection.cpp @@ -99,6 +99,8 @@ void I3Ipc::subscribe() { this->makeRequest(message); + // Workspaces must be refreshed before monitors or no focus will be + // detected on launch. this->refreshWorkspaces(); this->refreshMonitors(); } @@ -250,6 +252,10 @@ void I3Ipc::handleGetWorkspacesEvent(I3IpcEvent* event) { this->mWorkspaces.insertObjectSorted(workspace, &I3Ipc::compareWorkspaces); } + if (!this->bFocusedWorkspace && object.value("focused").value()) { + this->bFocusedMonitor = workspace->bindableMonitor().value(); + } + names.push_back(name); } @@ -466,13 +472,23 @@ I3Workspace* I3Ipc::findWorkspaceByName(const QString& name) { return workspaceIter == list.end() ? nullptr : *workspaceIter; } -I3Monitor* I3Ipc::findMonitorByName(const QString& name) { +I3Monitor* I3Ipc::findMonitorByName(const QString& name, bool createIfMissing) { auto list = this->mMonitors.valueList(); auto monitorIter = std::ranges::find_if(list, [name](I3Monitor* m) { return m->bindableName().value() == name; }); - return monitorIter == list.end() ? nullptr : *monitorIter; + if (monitorIter != list.end()) { + return *monitorIter; + } else if (createIfMissing) { + qCDebug(logI3Ipc) << "Monitor" << name << "requested before creation, performing early init"; + auto* monitor = new I3Monitor(this); + monitor->updateInitial(name); + this->mMonitors.insertObject(monitor); + return monitor; + } else { + return nullptr; + } } ObjectModel* I3Ipc::monitors() { return &this->mMonitors; } diff --git a/src/x11/i3/ipc/connection.hpp b/src/x11/i3/ipc/connection.hpp index d29f4857..af480c55 100644 --- a/src/x11/i3/ipc/connection.hpp +++ b/src/x11/i3/ipc/connection.hpp @@ -89,7 +89,7 @@ public: static QByteArray buildRequestMessage(EventCode cmd, const QByteArray& payload = QByteArray()); I3Workspace* findWorkspaceByName(const QString& name); - I3Monitor* findMonitorByName(const QString& name); + I3Monitor* findMonitorByName(const QString& name, bool createIfMissing = false); I3Workspace* findWorkspaceByID(qint32 id); void setFocusedMonitor(I3Monitor* monitor); diff --git a/src/x11/i3/ipc/monitor.cpp b/src/x11/i3/ipc/monitor.cpp index 0098f63a..1bc593cd 100644 --- a/src/x11/i3/ipc/monitor.cpp +++ b/src/x11/i3/ipc/monitor.cpp @@ -43,17 +43,18 @@ void I3Monitor::updateFromObject(const QVariantMap& obj) { if (!this->bActiveWorkspace || activeWorkspaceName != this->bActiveWorkspace->bindableName().value()) { - auto* workspace = this->ipc->findWorkspaceByName(activeWorkspaceName); - if (activeWorkspaceName.isEmpty() || workspace == nullptr) { // is null when output is disabled + if (activeWorkspaceName.isEmpty()) { this->bActiveWorkspace = nullptr; } else { - this->bActiveWorkspace = workspace; + this->bActiveWorkspace = this->ipc->findWorkspaceByName(activeWorkspaceName); } }; Qt::endPropertyUpdateGroup(); } +void I3Monitor::updateInitial(const QString& name) { this->bName = name; } + void I3Monitor::setFocusedWorkspace(I3Workspace* workspace) { this->bActiveWorkspace = workspace; }; } // namespace qs::i3::ipc diff --git a/src/x11/i3/ipc/monitor.hpp b/src/x11/i3/ipc/monitor.hpp index d184235f..00269a1b 100644 --- a/src/x11/i3/ipc/monitor.hpp +++ b/src/x11/i3/ipc/monitor.hpp @@ -61,6 +61,7 @@ public: [[nodiscard]] QVariantMap lastIpcObject() const; void updateFromObject(const QVariantMap& obj); + void updateInitial(const QString& name); void setFocusedWorkspace(I3Workspace* workspace); diff --git a/src/x11/i3/ipc/workspace.cpp b/src/x11/i3/ipc/workspace.cpp index 28fc0912..7d0b7305 100644 --- a/src/x11/i3/ipc/workspace.cpp +++ b/src/x11/i3/ipc/workspace.cpp @@ -44,11 +44,10 @@ void I3Workspace::updateFromObject(const QVariantMap& obj) { auto monitorName = obj.value("output").value(); if (!this->bMonitor || monitorName != this->bMonitor->bindableName().value()) { - auto* monitor = this->ipc->findMonitorByName(monitorName); - if (monitorName.isEmpty() || monitor == nullptr) { // is null when output is disabled + if (monitorName.isEmpty()) { this->bMonitor = nullptr; } else { - this->bMonitor = monitor; + this->bMonitor = this->ipc->findMonitorByName(monitorName, true); } }