hyprland/ipc: add lua ipc support

This commit is contained in:
outfoxxed 2026-04-26 23:26:54 -07:00
parent 78d0139fed
commit 04bbf571ca
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
6 changed files with 47 additions and 5 deletions

View file

@ -31,6 +31,7 @@ set shell id.
- Added per-corner radius support to Region.
- Added ColorQuantizer region selection.
- Added dialog window support to FloatingWindow.
- Added lua config support to Hyprland module.
## Other Changes

View file

@ -74,10 +74,23 @@ HyprlandIpc::HyprlandIpc() {
// clang-format on
this->makeRequest("j/status", [&](bool success, QByteArray resp) {
if (success) {
this->bUsingLua = [&]() {
if (resp == "unknown request") return false;
auto json = QJsonDocument::fromJson(resp).object();
auto provider = json.value("configProvider");
return provider == "lua";
}();
} else {
qCWarning(logHyprlandIpc) << "Hyprland ipc status request failed.";
}
this->eventSocket.connectToServer(this->mEventSocketPath, QLocalSocket::ReadOnly);
this->refreshMonitors(true);
this->refreshWorkspaces(true);
this->refreshToplevels();
});
}
QString HyprlandIpc::requestSocketPath() const { return this->mRequestSocketPath; }

View file

@ -81,6 +81,8 @@ public:
[[nodiscard]] HyprlandMonitor* monitorFor(QuickshellScreenInfo* screen);
[[nodiscard]] QBindable<bool> bindableUsingLua() const { return &this->bUsingLua; }
[[nodiscard]] QBindable<HyprlandMonitor*> bindableFocusedMonitor() const {
return &this->bFocusedMonitor;
}
@ -116,6 +118,7 @@ signals:
void connected();
void rawEvent(HyprlandIpcEvent* event);
void usingLuaChanged();
void focusedMonitorChanged();
void focusedWorkspaceChanged();
void activeToplevelChanged();
@ -155,6 +158,8 @@ private:
HyprlandIpcEvent event {this};
Q_OBJECT_BINDABLE_PROPERTY(HyprlandIpc, bool, bUsingLua, &HyprlandIpc::usingLuaChanged);
Q_OBJECT_BINDABLE_PROPERTY(
HyprlandIpc,
HyprlandMonitor*,

View file

@ -51,6 +51,10 @@ void HyprlandIpcQml::refreshToplevels() { HyprlandIpc::instance()->refreshToplev
QString HyprlandIpcQml::requestSocketPath() { return HyprlandIpc::instance()->requestSocketPath(); }
QString HyprlandIpcQml::eventSocketPath() { return HyprlandIpc::instance()->eventSocketPath(); }
QBindable<bool> HyprlandIpcQml::bindableUsingLua() {
return HyprlandIpc::instance()->bindableUsingLua();
}
QBindable<HyprlandMonitor*> HyprlandIpcQml::bindableFocusedMonitor() {
return HyprlandIpc::instance()->bindableFocusedMonitor();
}

View file

@ -16,6 +16,10 @@ namespace qs::hyprland::ipc {
class HyprlandIpcQml: public QObject {
Q_OBJECT;
// clang-format off
/// True if Hyprland is running in lua mode. Dispatcher syntax changes when using lua.
///
/// This property will be false until the Hyprland module is initialized.
Q_PROPERTY(bool usingLua READ default NOTIFY usingLuaChanged BINDABLE bindableUsingLua);
/// Path to the request socket (.socket.sock)
Q_PROPERTY(QString requestSocketPath READ requestSocketPath CONSTANT);
/// Path to the event socket (.socket2.sock)
@ -70,6 +74,7 @@ public:
[[nodiscard]] static QString requestSocketPath();
[[nodiscard]] static QString eventSocketPath();
[[nodiscard]] static QBindable<bool> bindableUsingLua();
[[nodiscard]] static QBindable<HyprlandMonitor*> bindableFocusedMonitor();
[[nodiscard]] static QBindable<HyprlandWorkspace*> bindableFocusedWorkspace();
[[nodiscard]] static QBindable<HyprlandToplevel*> bindableActiveToplevel();
@ -83,6 +88,7 @@ signals:
/// See [Hyprland Wiki: IPC](https://wiki.hyprland.org/IPC/) for a list of events.
void rawEvent(qs::hyprland::ipc::HyprlandIpcEvent* event);
void usingLuaChanged();
void focusedMonitorChanged();
void focusedWorkspaceChanged();
void activeToplevelChanged();

View file

@ -151,7 +151,20 @@ void HyprlandWorkspace::clearUrgent() {
}
void HyprlandWorkspace::activate() {
if (this->ipc->bindableUsingLua().value()) {
QString name;
for (const auto c: this->bName.value()) {
switch (c.toLatin1()) {
case '"': name.append("\\\""); break;
case '\\': name.append("\\\\"); break;
default: name.append(c); break;
}
}
this->ipc->dispatch(QString("hl.dsp.focus({ workspace = \"%1\" })").arg(name));
} else {
this->ipc->dispatch(QString("workspace %1").arg(this->bName.value()));
}
}
} // namespace qs::hyprland::ipc