diff --git a/src/wayland/hyprland/ipc/monitor.hpp b/src/wayland/hyprland/ipc/monitor.hpp index 83481d4..b9ac434 100644 --- a/src/wayland/hyprland/ipc/monitor.hpp +++ b/src/wayland/hyprland/ipc/monitor.hpp @@ -9,10 +9,11 @@ #include #include "connection.hpp" -#include "workspace.hpp" namespace qs::hyprland::ipc { +class HyprlandWorkspace; + class HyprlandMonitor: public QObject { Q_OBJECT; // clang-format off @@ -31,9 +32,9 @@ class HyprlandMonitor: public QObject { /// > property, run @@Hyprland.refreshMonitors() and wait for this property to update. Q_PROPERTY(QVariantMap lastIpcObject READ lastIpcObject NOTIFY lastIpcObjectChanged); /// The currently active workspace on this monitor. May be null. - Q_PROPERTY(qs::hyprland::ipc::HyprlandWorkspace* activeWorkspace READ default NOTIFY activeWorkspaceChanged); + Q_PROPERTY(qs::hyprland::ipc::HyprlandWorkspace* activeWorkspace READ default NOTIFY activeWorkspaceChanged BINDABLE bindableActiveWorkspace); /// If the monitor is currently focused. - Q_PROPERTY(bool focused READ default NOTIFY focusedChanged); + Q_PROPERTY(bool focused READ default NOTIFY focusedChanged BINDABLE bindableFocused); // clang-format on QML_ELEMENT; QML_UNCREATABLE("HyprlandMonitors must be retrieved from the HyprlandIpc object."); diff --git a/src/wayland/hyprland/ipc/workspace.cpp b/src/wayland/hyprland/ipc/workspace.cpp index e7aa93d..3aefdde 100644 --- a/src/wayland/hyprland/ipc/workspace.cpp +++ b/src/wayland/hyprland/ipc/workspace.cpp @@ -7,12 +7,27 @@ #include #include +#include "connection.hpp" #include "monitor.hpp" namespace qs::hyprland::ipc { QVariantMap HyprlandWorkspace::lastIpcObject() const { return this->mLastIpcObject; } +HyprlandWorkspace::HyprlandWorkspace(HyprlandIpc* ipc): QObject(ipc), ipc(ipc) { + Qt::beginPropertyUpdateGroup(); + + this->bActive.setBinding([this]() { + return this->bMonitor.value() && this->bMonitor->bindableActiveWorkspace().value() == this; + }); + + this->bFocused.setBinding([this]() { + return this->bActive.value() && this->bMonitor->bindableFocused().value(); + }); + + Qt::endPropertyUpdateGroup(); +} + void HyprlandWorkspace::updateInitial(qint32 id, const QString& name) { Qt::beginPropertyUpdateGroup(); this->bId = id; @@ -38,7 +53,7 @@ void HyprlandWorkspace::updateFromObject(QVariantMap object) { } if (!monitorName.isEmpty() - && (this->mMonitor == nullptr || this->mMonitor->bindableName().value() != monitorName)) + && (this->bMonitor == nullptr || this->bMonitor->bindableName().value() != monitorName)) { auto* monitor = this->ipc->findMonitorByName(monitorName, true, monitorId); this->setMonitor(monitor); @@ -48,45 +63,25 @@ void HyprlandWorkspace::updateFromObject(QVariantMap object) { emit this->lastIpcObjectChanged(); } -HyprlandMonitor* HyprlandWorkspace::monitor() const { return this->mMonitor; } - void HyprlandWorkspace::setMonitor(HyprlandMonitor* monitor) { - if (monitor == this->mMonitor) return; + auto* oldMonitor = this->bMonitor.value(); + if (monitor == oldMonitor) return; - if (this->mMonitor != nullptr) { - QObject::disconnect(this->mMonitor, nullptr, this, nullptr); + if (oldMonitor != nullptr) { + QObject::disconnect(oldMonitor, nullptr, this, nullptr); } - this->mMonitor = monitor; - - Qt::beginPropertyUpdateGroup(); - if (monitor != nullptr) { QObject::connect(monitor, &QObject::destroyed, this, &HyprlandWorkspace::onMonitorDestroyed); - - this->bActive.setBinding([this]() { - return this->mMonitor->bindableActiveWorkspace().value() == this; - }); - - this->bFocused.setBinding([this]() { - return this->bActive.value() && this->mMonitor->bindableFocused().value(); - }); - } else { - this->bActive = false; - this->bFocused = false; } - Qt::endPropertyUpdateGroup(); - emit this->monitorChanged(); + this->bMonitor = monitor; } -void HyprlandWorkspace::onMonitorDestroyed() { - this->mMonitor = nullptr; - emit this->monitorChanged(); -} +void HyprlandWorkspace::onMonitorDestroyed() { this->bMonitor = nullptr; } void HyprlandWorkspace::activate() { - HyprlandIpc::instance()->dispatch(QString("workspace %1").arg(this->bId.value())); + this->ipc->dispatch(QString("workspace %1").arg(this->bId.value())); } } // namespace qs::hyprland::ipc diff --git a/src/wayland/hyprland/ipc/workspace.hpp b/src/wayland/hyprland/ipc/workspace.hpp index d7c0c0e..a67a7fe 100644 --- a/src/wayland/hyprland/ipc/workspace.hpp +++ b/src/wayland/hyprland/ipc/workspace.hpp @@ -12,8 +12,11 @@ namespace qs::hyprland::ipc { +class HyprlandMonitor; + class HyprlandWorkspace: public QObject { Q_OBJECT; + // clang-format off Q_PROPERTY(qint32 id READ default NOTIFY idChanged BINDABLE bindableId); Q_PROPERTY(QString name READ default NOTIFY nameChanged BINDABLE bindableName); /// If this workspace is currently active on its monitor. See also @@focused. @@ -27,12 +30,13 @@ class HyprlandWorkspace: public QObject { /// > Hyprland. If you need a value that is subject to change and does not have a dedicated /// > property, run @@Hyprland.refreshWorkspaces() and wait for this property to update. Q_PROPERTY(QVariantMap lastIpcObject READ lastIpcObject NOTIFY lastIpcObjectChanged); - Q_PROPERTY(HyprlandMonitor* monitor READ monitor NOTIFY monitorChanged); + Q_PROPERTY(qs::hyprland::ipc::HyprlandMonitor* monitor READ default NOTIFY monitorChanged BINDABLE bindableMonitor); + // clang-format on QML_ELEMENT; QML_UNCREATABLE("HyprlandWorkspaces must be retrieved from the HyprlandIpc object."); public: - explicit HyprlandWorkspace(HyprlandIpc* ipc): QObject(ipc), ipc(ipc) {} + explicit HyprlandWorkspace(HyprlandIpc* ipc); void updateInitial(qint32 id, const QString& name); void updateFromObject(QVariantMap object); @@ -49,10 +53,10 @@ public: [[nodiscard]] QBindable bindableName() { return &this->bName; } [[nodiscard]] QBindable bindableActive() { return &this->bActive; } [[nodiscard]] QBindable bindableFocused() { return &this->bFocused; } + [[nodiscard]] QBindable bindableMonitor() { return &this->bMonitor; } [[nodiscard]] QVariantMap lastIpcObject() const; - [[nodiscard]] HyprlandMonitor* monitor() const; void setMonitor(HyprlandMonitor* monitor); signals: @@ -70,13 +74,13 @@ private: HyprlandIpc* ipc; QVariantMap mLastIpcObject; - HyprlandMonitor* mMonitor = nullptr; // clang-format off Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(HyprlandWorkspace, qint32, bId, -1, &HyprlandWorkspace::idChanged); Q_OBJECT_BINDABLE_PROPERTY(HyprlandWorkspace, QString, bName, &HyprlandWorkspace::nameChanged); Q_OBJECT_BINDABLE_PROPERTY(HyprlandWorkspace, bool, bActive, &HyprlandWorkspace::activeChanged); Q_OBJECT_BINDABLE_PROPERTY(HyprlandWorkspace, bool, bFocused, &HyprlandWorkspace::focusedChanged); + Q_OBJECT_BINDABLE_PROPERTY(HyprlandWorkspace, HyprlandMonitor*, bMonitor, &HyprlandWorkspace::monitorChanged); // clang-format on };