27#include "qi3pc_global.h"
28#include <QtNetwork/qlocalsocket.h>
31#include <QJsonDocument>
33#include <QMutexLocker>
34#include <QProcessEnvironment>
41#include <QLoggingCategory>
43Q_DECLARE_LOGGING_CATEGORY(Qi3pcLogger);
52class QI3PCSHARED_EXPORT
qi3pc :
public QObject
68 Workspace = I3_IPC_EVENT_WORKSPACE,
69 Output = I3_IPC_EVENT_OUTPUT,
70 Mode = I3_IPC_EVENT_MODE,
71 Window = I3_IPC_EVENT_WINDOW,
72 BarUpdate = I3_IPC_EVENT_BARCONFIG_UPDATE,
73 Binding = I3_IPC_EVENT_BINDING,
74 Shutdown = I3_IPC_EVENT_SHUTDOWN,
75 Tick = I3_IPC_EVENT_TICK
86 Command = I3_IPC_REPLY_TYPE_COMMAND,
87 Workspaces = I3_IPC_REPLY_TYPE_WORKSPACES,
88 Subscribe = I3_IPC_REPLY_TYPE_SUBSCRIBE,
89 Outputs = I3_IPC_REPLY_TYPE_OUTPUTS,
90 Tree = I3_IPC_REPLY_TYPE_TREE,
91 Marks = I3_IPC_REPLY_TYPE_MARKS,
92 BarConfig = I3_IPC_REPLY_TYPE_BAR_CONFIG,
93 Version = I3_IPC_REPLY_TYPE_VERSION,
94 BindingModes = I3_IPC_REPLY_TYPE_BINDING_MODES,
95 Config = I3_IPC_REPLY_TYPE_CONFIG,
96 Tick = I3_IPC_REPLY_TYPE_TICK,
97 Sync = I3_IPC_REPLY_TYPE_SYNC,
98 BindingState = I3_IPC_REPLY_TYPE_GET_BINDING_STATE
179 using DataObject = std::optional<std::pair<QJsonObject, qint64>>;
182 using DataArray = std::optional<std::pair<QJsonArray, qint64>>;
185 using DataString = std::optional<std::pair<QString, qint64>>;
238 static std::optional<ParseError>
FromJSON(
const QJsonObject& json);
245 inline static constexpr auto _MEMBERS = std::to_array<std::pair<const char*, QStringMemberPtr>>
254 using Error = std::optional<ParseError>;
270 using Message = std::optional<std::pair<QJsonDocument, quint32>>;
276 explicit qi3pc(QObject* parent =
nullptr);
328 void subscribe(
const QStringList& events);
366 template<IpcType Type>
367 requires(Type != IpcType::Subscribe && Type != IpcType::Tick)
376 void sendTick(
const QByteArray& payload = QByteArray());
384 const DataArray& workspaces()
const;
392 const DataObject& tree()
const;
400 const DataArray& outputs()
const;
408 const DataArray& marks()
const;
418 const DataObject& barConfigs()
const;
427 const DataObject& version()
const;
435 const DataArray& bindingModes()
const;
443 const DataObject& config()
const;
451 const DataString& bindingState()
const;
460 void fetchWorkspaces();
496 void fetchBarConfig(
const QString&
id);
504 void fetchBarConfigs();
522 void fetchBindingModes();
538 void fetchBindingState();
546 Message processMessage(QLocalSocket& socket);
562 void processWorkspaceEvent(
const QJsonDocument& doc);
568 void processOutputEvent(
const QJsonDocument& doc);
574 void processModeEvent(
const QJsonDocument& doc);
580 void processWindowEvent(
const QJsonDocument& doc);
586 void processBarUpdateEvent(
const QJsonDocument& doc);
592 void processBindingEvent(
const QJsonDocument& doc);
598 void processShutdownEvent(
const QJsonDocument& doc);
604 void processTickEvent(
const QJsonDocument& doc);
610 void processCommandReply(
const QJsonDocument& doc);
616 void processWorkspaceReply(
const QJsonDocument& doc);
622 void processOutputReply(
const QJsonDocument& doc);
628 void processTreeReply(
const QJsonDocument& doc);
634 void processMarkReply(
const QJsonDocument& doc);
640 void processBarConfigReply(
const QJsonDocument& doc);
646 void processVersionReply(
const QJsonDocument& doc);
652 void processBindingModesReply(
const QJsonDocument& doc);
658 void processConfigReply(
const QJsonDocument& doc);
664 void processTickReply(
const QJsonDocument& doc);
670 void processSyncReply(
const QJsonDocument& doc);
676 void processBindingStateReply(
const QJsonDocument& doc);
683 static WorkspaceChange WorkspaceChangeFromString(
const QString& s);
690 static WindowChange WindowChangeFromString(
const QString& s);
697 static ShutdownChange ShutdownChangeFromString(
const QString& s);
704 static OutputChange OutputChangeFromString(
const QString& s);
711 static BindingChange BindingChangeFromString(
const QString& s);
720 static void WritePayload(QLocalSocket& socket,
const QByteArray& payload, IpcType type);
783 const QJsonObject& current,
784 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.
Container for the attributes of a parsing error from i3wm when trying to run an unparsable command;.
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.