Skip to content

Commit 7f35823

Browse files
Mestanesufficientpastsoramanew
authored
feat: add Hyprland lua conf support (caelestia-dots#1553)
* changing dispatchers * gating dispatchers for non-lua config * refractoring? * fix: added usingLua property to HyprExtras for Lua config detection caelestia-dots#1478 * refactor(internal): pass usingLua from QML instead of detecting in C++ * fix(workspaces): resolve undefined workspace id in Lua dispatch * fix(workspaces): guard against undefined workspace and fix Lua dispatch * fix: use Lua syntax in applyOptions when usingLua is set * refactor(hypr): use local usingLua over Hyprland.usingLua * chore: format * fix: only change action if it is dpms on/off * more fixes * fix: lua dispatcher syntax fail thank you karin --------- Co-authored-by: sufficientpast <252132621+sufficientpast@users.noreply.github.com> Co-authored-by: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>
1 parent f86c359 commit 7f35823

9 files changed

Lines changed: 42 additions & 18 deletions

File tree

modules/IdleMonitors.qml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Scope {
2222
else if (action === "unlock")
2323
lock.lock.locked = false;
2424
else if (typeof action === "string")
25-
Hypr.dispatch(action);
25+
Hypr.dispatch(Hypr.usingLua && ["dpms off", "dpms on"].includes(action) ? `hl.dsp.dpms({ action = "${action === "dpms off" ? "disable" : "enable"}" })` : action);
2626
else
2727
Quickshell.execDetached(action);
2828
}

modules/bar/Bar.qml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ ColumnLayout {
8383
const mon = (GlobalConfig.bar.workspaces.perMonitorWorkspaces ? Hypr.monitorFor(screen) : Hypr.focusedMonitor);
8484
const specialWs = mon?.lastIpcObject.specialWorkspace.name;
8585
if (specialWs?.length > 0)
86-
Hypr.dispatch(`togglespecialworkspace ${specialWs.slice(8)}`);
86+
Hypr.dispatch(Hypr.usingLua ? `hl.dsp.workspace.toggle_special("${specialWs.slice(8)}")` : `togglespecialworkspace ${specialWs.slice(8)}`);
8787
else if (angleDelta.y < 0 || (GlobalConfig.bar.workspaces.perMonitorWorkspaces ? mon.activeWorkspace?.id : Hypr.activeWsId) > 1)
88-
Hypr.dispatch(`workspace r${angleDelta.y > 0 ? "-" : "+"}1`);
88+
Hypr.dispatch(Hypr.usingLua ? `hl.dsp.focus({ workspace = "r${angleDelta.y > 0 ? "-" : "+"}1" })` : `workspace r${angleDelta.y > 0 ? "-" : "+"}1`);
8989
} else if (y < screen.height / 2 && Config.bar.scrollActions.volume) {
9090
// Volume scroll on top half
9191
if (angleDelta.y > 0)

modules/bar/components/workspaces/SpecialWorkspaces.qml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,9 @@ Item {
227227

228228
const ws = view.itemAt(event.x, event.y) as SpecialWsDelegate;
229229
if (ws?.modelData)
230-
Hypr.dispatch(`togglespecialworkspace ${ws.modelData.name.slice(8)}`);
230+
Hypr.dispatch(Hypr.usingLua ? `hl.dsp.workspace.toggle_special("${ws.modelData.name.slice(8)}")` : `togglespecialworkspace ${ws.modelData.name.slice(8)}`);
231231
else
232-
Hypr.dispatch("togglespecialworkspace special");
232+
Hypr.dispatch(Hypr.usingLua ? 'hl.dsp.workspace.toggle_special("special")' : "togglespecialworkspace special");
233233
}
234234
}
235235

modules/bar/components/workspaces/Workspaces.qml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,12 @@ StyledClippingRect {
9696
anchors.fill: layout
9797
onClicked: event => {
9898
const ws = (layout.childAt(event.x, event.y) as Workspace)?.ws;
99+
if (!ws)
100+
return;
99101
if (Hypr.activeWsId !== ws)
100-
Hypr.dispatch(`workspace ${ws}`);
102+
Hypr.dispatch(Hypr.usingLua ? `hl.dsp.focus({ workspace = "${ws}" })` : `workspace ${ws}`);
101103
else
102-
Hypr.dispatch("togglespecialworkspace special");
104+
Hypr.dispatch(Hypr.usingLua ? 'hl.dsp.workspace.toggle_special("special")' : "togglespecialworkspace special");
103105
}
104106
}
105107

modules/windowinfo/Buttons.qml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ ColumnLayout {
9595
readonly property bool isCurrent: root.client?.workspace.id === wsId
9696

9797
onClicked: {
98-
Hypr.dispatch(`movetoworkspace ${wsId},address:0x${root.client?.address}`);
98+
Hypr.dispatch(Hypr.usingLua ? `hl.dsp.window.move({ window = "address:0x${root.client?.address}", workspace = "${wsId}", follow = true })` : `movetoworkspace ${wsId},address:0x${root.client?.address}`);
9999
}
100100
101101
color: isCurrent ? Colours.tPalette.m3surfaceContainerHighest : Colours.palette.m3tertiaryContainer
@@ -118,7 +118,7 @@ ColumnLayout {
118118
color: Colours.palette.m3secondaryContainer
119119
onColor: Colours.palette.m3onSecondaryContainer
120120
text: root.client?.lastIpcObject.floating ? qsTr("Tile") : qsTr("Float")
121-
onClicked: Hypr.dispatch(`togglefloating address:0x${root.client?.address}`)
121+
onClicked: Hypr.dispatch(Hypr.usingLua ? `hl.dsp.window.float({ window = "address:0x${root.client?.address}" })` : `togglefloating address:0x${root.client?.address}`)
122122
}
123123
124124
Loader {
@@ -132,15 +132,15 @@ ColumnLayout {
132132
color: Colours.palette.m3secondaryContainer
133133
onColor: Colours.palette.m3onSecondaryContainer
134134
text: root.client?.lastIpcObject.pinned ? qsTr("Unpin") : qsTr("Pin")
135-
onClicked: Hypr.dispatch(`pin address:0x${root.client?.address}`)
135+
onClicked: Hypr.dispatch(Hypr.usingLua ? `hl.dsp.window.pin({ window = "address:0x${root.client?.address}" })` : `pin address:0x${root.client?.address}`)
136136
}
137137
}
138138
139139
Button {
140140
color: Colours.palette.m3errorContainer
141141
onColor: Colours.palette.m3onErrorContainer
142142
text: qsTr("Kill")
143-
onClicked: Hypr.dispatch(`killwindow address:0x${root.client?.address}`)
143+
onClicked: Hypr.dispatch(Hypr.usingLua ? `hl.dsp.window.kill({ window = "address:0x${root.client?.address}" })` : `killwindow address:0x${root.client?.address}`)
144144
}
145145
}
146146

plugin/src/Caelestia/Internal/hyprextras.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,14 @@ void HyprExtras::applyOptions(const QVariantHash& options) {
9090
request.reserve(12 + options.size() * 40);
9191
request += QLatin1String("[[BATCH]]");
9292
for (auto it = options.constBegin(); it != options.constEnd(); ++it) {
93-
request += QLatin1String("keyword ") + it.key() + QLatin1Char(' ') + it.value().toString() + QLatin1Char(';');
93+
if (!m_usingLua) {
94+
request +=
95+
QLatin1String("keyword ") + it.key() + QLatin1Char(' ') + it.value().toString() + QLatin1Char(';');
96+
} else {
97+
auto parts = it.key().split(':');
98+
request += "eval hl.config({ " + parts.join(" = { ") + " = " + it.value().toString() +
99+
QString(" }").repeated(parts.size() - 1) + " });";
100+
}
94101
}
95102

96103
makeRequest(request, [this](bool success, const QByteArray& res) {

plugin/src/Caelestia/Internal/hyprextras.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class HyprExtras : public QObject {
1717

1818
Q_PROPERTY(QVariantHash options READ options NOTIFY optionsChanged)
1919
Q_PROPERTY(caelestia::internal::hypr::HyprDevices* devices READ devices CONSTANT)
20+
Q_PROPERTY(bool usingLua MEMBER m_usingLua NOTIFY usingLuaChanged)
2021

2122
public:
2223
explicit HyprExtras(QObject* parent = nullptr);
@@ -33,6 +34,7 @@ class HyprExtras : public QObject {
3334

3435
signals:
3536
void optionsChanged();
37+
void usingLuaChanged();
3638

3739
private:
3840
using SocketPtr = QSharedPointer<QLocalSocket>;
@@ -41,6 +43,7 @@ class HyprExtras : public QObject {
4143
QString m_eventSocket;
4244
QLocalSocket* m_socket;
4345
bool m_socketValid;
46+
bool m_usingLua = false;
4447

4548
QVariantHash m_options;
4649
HyprDevices* const m_devices;

services/Colours.qml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,13 @@ Singleton {
8383
}
8484

8585
function reloadHyprRules(): void {
86-
const str = "keyword layerrule %1 %2, match:namespace caelestia-drawers";
87-
Hypr.extras.batchMessage([str.arg("blur").arg(transparency.enabled ? 1 : 0), str.arg("ignore_alpha").arg(transparency.base - 0.03)]);
86+
if (Hypr.usingLua) {
87+
const rule = `eval hl.layer_rule({ match = { namespace = "caelestia-drawers" }, %1 })`;
88+
Hypr.extras.batchMessage([rule.arg(`blur = ${transparency.enabled}`), rule.arg(`ignore_alpha = ${transparency.base - 0.03}`)]);
89+
} else {
90+
const str = "keyword layerrule %1 %2, match:namespace caelestia-drawers";
91+
Hypr.extras.batchMessage([str.arg("blur").arg(transparency.enabled ? 1 : 0), str.arg("ignore_alpha").arg(transparency.base - 0.03)]);
92+
}
8893
}
8994

9095
function requestReloadHyprRules(): void {

services/Hypr.qml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Singleton {
1515
readonly property var toplevels: Hyprland.toplevels
1616
readonly property var workspaces: Hyprland.workspaces
1717
readonly property var monitors: Hyprland.monitors
18+
readonly property bool usingLua: Hyprland.usingLua
1819

1920
readonly property HyprlandToplevel activeToplevel: {
2021
const t = Hyprland.activeToplevel;
@@ -57,11 +58,11 @@ Singleton {
5758
if (lastSpecialWorkspace) {
5859
const workspace = workspaces.values.find(w => w.name === lastSpecialWorkspace);
5960
if (workspace && workspace.lastIpcObject.windows > 0) {
60-
dispatch(`workspace ${lastSpecialWorkspace}`);
61+
dispatch(usingLua ? `hl.dsp.focus({ workspace = "${lastSpecialWorkspace}" })` : `workspace ${lastSpecialWorkspace}`);
6162
return;
6263
}
6364
}
64-
dispatch(`workspace ${openSpecials[0].name}`);
65+
dispatch(usingLua ? `hl.dsp.focus({ workspace = "${openSpecials[0].name}" })` : `workspace ${openSpecials[0].name}`);
6566
return;
6667
}
6768

@@ -75,7 +76,7 @@ Singleton {
7576
nextIndex = (currentIndex - 1 + openSpecials.length) % openSpecials.length;
7677
}
7778

78-
dispatch(`workspace ${openSpecials[nextIndex].name}`);
79+
dispatch(usingLua ? `hl.dsp.focus({ workspace = "${openSpecials[nextIndex].name}" })` : `workspace ${openSpecials[nextIndex].name}`);
7980
}
8081

8182
function monitorNames(): list<string> {
@@ -87,7 +88,11 @@ Singleton {
8788
}
8889

8990
function reloadDynamicConfs(): void {
90-
extras.batchMessage(["keyword bindlni ,Caps_Lock,global,caelestia:refreshDevices", "keyword bindlni ,Num_Lock,global,caelestia:refreshDevices"]);
91+
if (usingLua) {
92+
extras.batchMessage(['eval hl.bind("Caps_Lock", hl.dsp.global("caelestia:refreshDevices"), { locked = true, non_consuming = true, ignore_mods = true, release = true })', 'eval hl.bind("Num_Lock", hl.dsp.global("caelestia:refreshDevices"), { locked = true, non_consuming = true, ignore_mods = true, release = true })']);
93+
} else {
94+
extras.batchMessage(["keyword bindlni ,Caps_Lock,global,caelestia:refreshDevices", "keyword bindlni ,Num_Lock,global,caelestia:refreshDevices"]);
95+
}
9196
}
9297

9398
Component.onCompleted: reloadDynamicConfs()
@@ -218,5 +223,7 @@ Singleton {
218223

219224
HyprExtras {
220225
id: extras
226+
227+
usingLua: Hyprland.usingLua
221228
}
222229
}

0 commit comments

Comments
 (0)