#pragma once #include #include #include #include #include #include #include #include namespace qs::i3::ipc { constexpr std::string MAGIC = "i3-ipc"; enum EventCode { RunCommand = 0, GetWorkspaces = 1, Subscribe = 2, GetOutputs = 3, GetTree = 4, Workspace = 0x80000000, Output = 0x80000001, Mode = 0x80000002, Window = 0x80000003, BarconfigUpdate = 0x80000004, Binding = 0x80000005, Shutdown = 0x80000006, Tick = 0x80000007, BarStateUpdate = 0x80000014, Input = 0x80000015, Unknown = 999, }; using Event = std::tuple; ///! I3/Sway IPC Events /// Emitted by @@I3.rawEvent(s) class I3IpcEvent: public QObject { Q_OBJECT; Q_PROPERTY(QString type READ type CONSTANT); Q_PROPERTY(QString data READ data CONSTANT); QML_NAMED_ELEMENT(I3Event); QML_UNCREATABLE("I3IpcEvents cannot be created."); public: I3IpcEvent(QObject* parent): QObject(parent) {} [[nodiscard]] QString type() const; [[nodiscard]] QString data() const; EventCode mCode = EventCode::Unknown; QJsonDocument mData; static EventCode intToEvent(uint32_t raw); static QString eventToString(EventCode event); }; /// Base class that manages the IPC socket, subscriptions and event reception. class I3Ipc: public QObject { Q_OBJECT; public: explicit I3Ipc(const QList& events); [[nodiscard]] QString socketPath() const; void makeRequest(const QByteArray& request); void dispatch(const QString& payload); void connect(); [[nodiscard]] QByteArray static buildRequestMessage( EventCode cmd, const QByteArray& payload = QByteArray() ); signals: void connected(); void rawEvent(I3IpcEvent* event); protected slots: void eventSocketError(QLocalSocket::LocalSocketError error) const; void eventSocketStateChanged(QLocalSocket::LocalSocketState state); void eventSocketReady(); void subscribe(); protected: void reconnectIPC(); QVector> parseResponse(); QLocalSocket liveEventSocket; QDataStream liveEventSocketDs; QString mSocketPath; bool valid = false; I3IpcEvent event {this}; private: QList mEvents; }; } // namespace qs::i3::ipc