#pragma once #include #include #include #include #include #include class SwayIpcClient : public QObject { Q_OBJECT public: enum MessageType : quint32 { RunCommand = 0, GetWorkspaces = 1, Subscribe = 2, GetOutputs = 3, GetTree = 4, GetMarks = 5, GetVersion = 7 }; enum EventType : quint32 { WorkspaceEvent = 0x80000000u, OutputEvent = 0x80000001u, WindowEvent = 0x80000003u, BindingEvent = 0x80000005u, ShutdownEvent = 0x80000006u }; explicit SwayIpcClient(QObject *parent = nullptr); ~SwayIpcClient() override; bool connectToSway(); void disconnectFromSway(); bool isConnected() const; QJsonDocument request(quint32 type, const QByteArray &payload = {}); bool subscribe(const QStringList &events); static QString socketPath(); signals: void connectedChanged(); void disconnected(); void eventReceived(quint32 type, const QJsonDocument &payload); private: struct Message { quint32 type = 0; QByteArray payload; }; bool writeMessage(QLocalSocket *socket, quint32 type, const QByteArray &payload); bool readMessage(QLocalSocket *socket, Message *message, int timeoutMs); void appendIncoming(QLocalSocket *socket, QByteArray *buffer); bool takeMessage(QByteArray *buffer, Message *message); void processEventSocket(); void flushPendingEvents(); void handleCommandDisconnected(); void handleEventDisconnected(); QLocalSocket *m_command = nullptr; QLocalSocket *m_event = nullptr; QByteArray m_eventBuffer; QVector m_pendingEvents; int m_inRequest = 0; bool m_connected = false; };