This repository was archived by the owner on Nov 8, 2026. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathService.qml
More file actions
120 lines (119 loc) · 4.38 KB
/
Copy pathService.qml
File metadata and controls
120 lines (119 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import QtQuick
import Quickshell
import Quickshell.Io
Item {
id: root
visible: false
readonly property string pluginId: "io.github.macifyer.pallet"
readonly property string description: "Pallet command palette"
readonly property string combo: "ALT + SPACE"
readonly property int modmask: 8
readonly property string key: "SPACE"
readonly property int keycode: 65
readonly property string summon: "omarchy-shell shell toggle " + pluginId
property bool bound: false
property bool verifyPending: false
Component.onCompleted: bindsReader.running = true
Component.onDestruction: {
if (root.bound)
Quickshell.execDetached(["hyprctl", "eval", "hl.unbind(" + luaQuote(root.combo) + ")"]);
}
Process {
id: bindsReader
command: ["hyprctl", "binds", "-j"]
stdout: StdioCollector {
waitForEnd: true
onStreamFinished: root.planBinds(String(text || ""))
}
}
Timer {
id: verifyTimer
interval: 500
onTriggered: {
root.verifyPending = true;
bindsReader.running = true;
}
}
Timer {
id: heartbeat
interval: 4000
repeat: true
running: true
onTriggered: bindsReader.running = true
}
Process {
id: reloadWatcher
running: true
command: ["sh", "-c", "command -v socat >/dev/null && socat -U - UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | while IFS= read -r line; do case \"$line\" in configreloaded*) echo reload;; esac; done"]
stdout: SplitParser {
onRead: data => {
if (data.trim() === "reload")
bindsReader.running = true;
}
}
}
function luaQuote(text: string): string {
return '"' + String(text).replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n") + '"';
}
function keyOf(bind: var): string {
return bind.key ? String(bind.key).toUpperCase() : (bind.keycode ? "CODE:" + bind.keycode : "");
}
function formatCombo(mask: int, key: string): string {
const names = [];
if (mask & 64) names.push("SUPER");
if (mask & 4) names.push("CTRL");
if (mask & 8) names.push("ALT");
if (mask & 1) names.push("SHIFT");
names.push(key);
return names.join(" + ");
}
function matchesOurs(bind: var): bool {
const sameKey = (bind.key ?? "").toUpperCase() === root.key
|| Number(bind.keycode) === root.keycode;
const sameMods = Number(bind.modmask) === root.modmask;
return sameKey && sameMods;
}
function planBinds(jsonText: string): void {
let binds = [];
try {
binds = JSON.parse(jsonText);
} catch (err) {
console.warn("pallet: cannot parse hyprctl binds -j");
return;
}
for (const bind of binds) {
if ((bind.description ?? "") !== root.description)
continue;
if (matchesOurs(bind)) {
root.bound = true;
if (root.verifyPending) {
root.verifyPending = false;
console.log("pallet: confirmed ALT+SPACE -> " + root.summon);
}
return;
}
Quickshell.execDetached(["hyprctl", "eval",
"hl.unbind(" + luaQuote(formatCombo(Number(bind.modmask), keyOf(bind))) + ")"]);
}
if (root.verifyPending) {
root.verifyPending = false;
console.warn("pallet: ALT+SPACE registration did not land; retrying");
}
for (const other of binds) {
if (matchesOurs(other)) {
if (!root.bound)
console.warn("pallet: ALT+SPACE is already bound to '"
+ (other.description || ((other.dispatcher ?? "") + " " + (other.arg ?? "")))
+ "'; leaving it alone. Bind Pallet yourself: " + root.summon);
root.bound = false;
return;
}
}
const lua = "hl.bind(" + luaQuote(root.combo)
+ ", hl.dsp.exec_cmd(" + luaQuote(root.summon) + ")"
+ ", { description = " + luaQuote(root.description) + " })";
Quickshell.execDetached(["hyprctl", "eval", lua]);
root.bound = true;
verifyTimer.restart();
}
}