4#include "qi3pc_global.h"
5#include <QtNetwork/qlocalsocket.h>
8#include <QJsonDocument>
10#include <QMutexLocker>
11#include <QProcessEnvironment>
18#include <QLoggingCategory>
20Q_DECLARE_LOGGING_CATEGORY(Qi3pcLogger);
29class QI3PCSHARED_EXPORT
qi3pc :
public QObject
45 Workspace = I3_IPC_EVENT_WORKSPACE,
46 Output = I3_IPC_EVENT_OUTPUT,
47 Mode = I3_IPC_EVENT_MODE,
48 Window = I3_IPC_EVENT_WINDOW,
49 BarUpdate = I3_IPC_EVENT_BARCONFIG_UPDATE,
50 Binding = I3_IPC_EVENT_BINDING,
51 Shutdown = I3_IPC_EVENT_SHUTDOWN,
52 Tick = I3_IPC_EVENT_TICK
63 Command = I3_IPC_REPLY_TYPE_COMMAND,
64 Workspaces = I3_IPC_REPLY_TYPE_WORKSPACES,
65 Subscribe = I3_IPC_REPLY_TYPE_SUBSCRIBE,
66 Outputs = I3_IPC_REPLY_TYPE_OUTPUTS,
67 Tree = I3_IPC_REPLY_TYPE_TREE,
68 Marks = I3_IPC_REPLY_TYPE_MARKS,
69 BarConfig = I3_IPC_REPLY_TYPE_BAR_CONFIG,
70 Version = I3_IPC_REPLY_TYPE_VERSION,
71 BindingModes = I3_IPC_REPLY_TYPE_BINDING_MODES,
72 Config = I3_IPC_REPLY_TYPE_CONFIG,
73 Tick = I3_IPC_REPLY_TYPE_TICK,
74 Sync = I3_IPC_REPLY_TYPE_SYNC,
75 BindingState = I3_IPC_REPLY_TYPE_GET_BINDING_STATE
156 using DataObject = std::optional<std::pair<QJsonObject, qint64>>;
159 using DataArray = std::optional<std::pair<QJsonArray, qint64>>;
162 using DataString = std::optional<std::pair<QString, qint64>>;
215 static std::optional<ParseError>
FromJSON(
const QJsonObject& json);
222 inline static constexpr auto _MEMBERS = std::to_array<std::pair<const char*, QStringMemberPtr>>
231 using Error = std::optional<ParseError>;
247 using Message = std::optional<std::pair<QJsonDocument, quint32>>;
253 explicit qi3pc(QObject* parent =
nullptr);
305 void subscribe(
const QStringList& events);
343 template<IpcType Type>
344 requires(Type != IpcType::Subscribe && Type != IpcType::Tick)
353 void sendTick(
const QByteArray& payload = QByteArray());
361 const DataArray& workspaces()
const;
369 const DataObject& tree()
const;
377 const DataArray& outputs()
const;
385 const DataArray& marks()
const;
395 const DataObject& barConfigs()
const;
404 const DataObject& version()
const;
412 const DataArray& bindingModes()
const;
420 const DataObject& config()
const;
428 const DataString& bindingState()
const;
437 void fetchWorkspaces();
473 void fetchBarConfig(
const QString&
id);
481 void fetchBarConfigs();
499 void fetchBindingModes();
515 void fetchBindingState();
523 Message processMessage(QLocalSocket& socket);
539 void processWorkspaceEvent(
const QJsonDocument& doc);
545 void processOutputEvent(
const QJsonDocument& doc);
551 void processModeEvent(
const QJsonDocument& doc);
557 void processWindowEvent(
const QJsonDocument& doc);
563 void processBarUpdateEvent(
const QJsonDocument& doc);
569 void processBindingEvent(
const QJsonDocument& doc);
575 void processShutdownEvent(
const QJsonDocument& doc);
581 void processTickEvent(
const QJsonDocument& doc);
587 void processCommandReply(
const QJsonDocument& doc);
593 void processWorkspaceReply(
const QJsonDocument& doc);
599 void processOutputReply(
const QJsonDocument& doc);
605 void processTreeReply(
const QJsonDocument& doc);
611 void processMarkReply(
const QJsonDocument& doc);
617 void processBarConfigReply(
const QJsonDocument& doc);
623 void processVersionReply(
const QJsonDocument& doc);
629 void processBindingModesReply(
const QJsonDocument& doc);
635 void processConfigReply(
const QJsonDocument& doc);
641 void processTickReply(
const QJsonDocument& doc);
647 void processSyncReply(
const QJsonDocument& doc);
653 void processBindingStateReply(
const QJsonDocument& doc);
660 static WorkspaceChange WorkspaceChangeFromString(
const QString& s);
667 static WindowChange WindowChangeFromString(
const QString& s);
674 static ShutdownChange ShutdownChangeFromString(
const QString& s);
681 static OutputChange OutputChangeFromString(
const QString& s);
688 static BindingChange BindingChangeFromString(
const QString& s);
697 static void WritePayload(QLocalSocket& socket,
const QByteArray& payload, IpcType type);
760 const QJsonObject& current,
761 const QJsonObject& old);
ShutdownChange
Types of change a shutdown event can have.
void configUpdated(const qi3pc::DataObject &config)
Signal emitted when the (cached) config have been updated.
void treeUpdated(const qi3pc::DataObject &tree)
Signal emitted when the layout tree cache have been updated.
WindowChange
Types of change a window event can have.
void barConfigUpdated(const QJsonObject &config)
Signal emitted when a specific bar's (cached) config have been updated. At this point the configurati...
void sendMessage(const QByteArray &payload=QByteArray())
Send a message with the specified type and payload to i3.
std::vector< std::pair< bool, Error > > CommandResults
Pairs of qi3pc::Error and boolean.
std::optional< std::pair< QJsonDocument, quint32 > > Message
Optional pair of a JSON document with a qi3pc::IpcType received with a message or an event before it ...
void barUpdateEvent(const QJsonObject &doc)
Signal emitted when a bar's configuration have been updated.
QLocalSocket m_messageSocket
void workspacesUpdated(const qi3pc::DataArray &workspaces)
Signal emitted when the (cached) list of workspaces have been updated.
void synced(bool success)
Signal emitted when a sync message have been replied to by i3.
std::optional< ParseError > Error
Optional qi3pc::ParseError. The optional is empty when the error could not be parsed.
void tickSent(bool success)
Signal emitted when a tick have been processed by i3.
QString socketPath() const
Get the socket path selected at construction.
const DataArray & marks() const
Get the (cached) list of set marks.
void subscribed(bool success)
Signal emitted when a subscribe message have been replied to.
DataString m_bindingState
void bindingStateUpdated(const qi3pc::DataString &state)
Signal emitted when the (cached) current binding state have been updated.
void outputEvent(qi3pc::OutputChange change)
Signal emitted when the output(s) change.
void versionUpdated(const qi3pc::DataObject &version)
Signal emitted when the (cached) i3 version have been updated.
void outputsUpdated(const qi3pc::DataArray &outputs)
Signal emitted when (cached) outputs have been updated.
bool connect()
Start listening to messages and events from the window manager.
void modeEvent(QString change, bool pango)
Signal emitted when the binding mode changes.
static constexpr auto IpcMagicLength
void windowEvent(qi3pc::WindowChange change, const QJsonObject &container)
Signal emitted when a window changes.
QLocalSocket m_eventSocket
void subscribe(const QStringList &events)
Subscribe to a list of events.
const DataArray & workspaces() const
Get the list of (cached) workspaces.
void newBarConfig(const QString &id)
Signal emitted when a new bar config have been added to the cache.
bool disconnect()
Stop listening to messages and events from the window manager.
static QString FindSocketPath()
Find the path to the i3 ipc local unix socket.
static void WritePayload(QLocalSocket &socket, const QByteArray &payload, IpcType type)
Send a message with the specified type and payload to i3 using the specified socket.
IpcType
Types of message/replies the API send/expect to/from i3wm.
static constexpr auto IpcMagicString
void tickEvent(const QString &payload)
Signal emitted when subscribing to tick events or when a tick message have been sent to the ipc conne...
BindingChange
Types of change a binding event can have.
void marksUpdated(const qi3pc::DataArray &marks)
Signal emitted when the (cached) list of marks have been updated.
void commandRan(CommandResults result)
Signal emitted when a command have been ran by i3.
OutputChange
Types of change an output event can have.
std::optional< std::pair< QJsonObject, qint64 > > DataObject
Optional pair of a JSON object with its last update time.
WorkspaceChange
Types of change a workspace event can have.
qi3pc(QObject *parent=nullptr)
Construct a qi3pc object.
void bindingEvent(qi3pc::BindingChange change, const QJsonObject &binding, const QString &mode)
Signal emitteed when a binding have been triggered to run a command.
const DataObject & tree() const
Get the (cached) i3 layout tree.
void shutdownEvent(qi3pc::ShutdownChange change)
Signal emitted when the ipc socket is about to shutdown.
const DataObject & config() const
Get the (cached) data read from the config file.
void workspaceEvent(qi3pc::WorkspaceChange change, const QJsonObject ¤t, const QJsonObject &old)
Signal emitted with a workspace event's data preprocessed.
std::optional< std::pair< QString, qint64 > > DataString
Optional pair of a string with its last update time.
static QString FindSocketPathFromI3Binary()
Find the path to the i3 ipc local unix socket using the i3 binary.
void bindingModesUpdated(const qi3pc::DataArray &modes)
Signal emitted when the (cached) list of modes have been updated.
std::optional< std::pair< QJsonArray, qint64 > > DataArray
Optional pair of a JSON array with its last update time.
const DataObject & version() const
Get the (cached) i3 version object.
bool isConnected()
Check if the connection to the ipc socket is established.
const DataArray & outputs() const
Get the (cached) list of outputs.
IpcEvent
Types of events offered by i3wm's IPC API.
The Err struct contains the attributes of a parsing error from i3wm when trying to run an unparsable ...
static constexpr auto _MEMBERS
Mapping of i3wm's parse error reply's attributes to members of ParseError.
QString errorPosition
The position where the error was detected in the input.
QString ParseError::* QStringMemberPtr
QString member pointer of ParseError.
QString input
The command that failed to run.
QString toString() const
Convert to a json like string.
QString error
Human readble error message.
bool operator==(const ParseError &other) const
Memberwise comparison of this ParseError and another.
static std::optional< ParseError > FromJSON(const QJsonObject &json)
Build an optional ParseError from a QJsonObject.