···
13
13
; Variables with polling - set initial values to avoid empty string errors
14
14
(defpoll time :interval "1s" :initial "00:00" "date '+%H:%M'")
15
15
(defpoll date :interval "60s" :initial "0000-00-00" "date '+%Y-%m-%d'")
16
16
-
(defpoll cpu :interval "2s" :initial 0 "${lib.getExe cpuScript}")
16
16
+
(defpoll cpu :interval "2s" :initial '{"usage": 0, "load": "0.00", "freq": 0}' "${lib.getExe cpuScript}")
17
17
(defpoll memory :interval "2s" :initial 0 "${lib.getExe memScript}")
18
18
-
(defpoll temperature :interval "2s" :initial 0 "${lib.getExe tempScript}")
18
18
+
(defpoll temperature :interval "2s" :initial '{"temp": 0, "fan": 0}' "${lib.getExe tempScript}")
19
19
(defpoll battery :interval "10s" :initial '{"capacity": "100", "icon": "", "watts": "0", "time_remaining": "--", "status": "Full"}' "${lib.getExe batteryScript}")
20
20
(defpoll volume :interval "1s" :initial '{"level": "0", "icon": ""}' "${lib.getExe volumeScript}")
21
21
(defpoll network :interval "5s" :initial " ..." "${lib.getExe networkScript}")
22
22
+
(defpoll brightness :interval "1s" :initial 100 "${lib.getExe brightnessScript}")
23
23
+
(defpoll idle-inhibited :interval "0.5s" :initial "false" "${lib.getExe idleStatusScript}")
22
24
(deflisten workspaces :initial '[]' "${lib.getExe workspacesScript}")
23
25
24
26
; Widget definitions
···
40
42
(box :class "right" :orientation "h" :space-evenly false :halign "end" :spacing 8
41
43
(network-widget)
42
44
(volume-widget)
43
43
-
(graph-widget :value cpu :icon "" :class "cpu" :unit "%")
45
45
+
(graph-widget :value {cpu.usage} :icon "" :class "cpu" :unit "%" :tooltip "Load: ''${cpu.load} | ''${cpu.freq} MHz")
44
46
(graph-widget :value memory :icon "" :class "memory" :unit "%")
45
45
-
(graph-widget :value temperature :icon "" :class "temp" :unit "°")
47
47
+
(graph-widget :value {temperature.temp} :icon "" :class "temp" :unit "°" :tooltip "Fan: ''${temperature.fan} RPM")
48
48
+
(brightness-widget)
46
49
(battery-widget)
50
50
+
(idle-inhibitor)
47
51
(label :class "date" :text "''${date}")
48
52
(systray :class "systray" :icon-size 18 :spacing 4)))
49
53
···
54
58
:onclick "swaymsg workspace ''${ws.name}"
55
59
{ws.name}))))
56
60
57
57
-
(defwidget graph-widget [value icon class unit]
61
61
+
(defwidget graph-widget [value icon class unit ?tooltip]
58
62
(box :class "graph-module ''${class}" :orientation "h" :space-evenly false :spacing 4
63
63
+
:tooltip {tooltip ?: ""}
59
64
(graph :class "graph"
60
65
:value value
61
66
:thickness 3
···
79
84
(defwidget network-widget []
80
85
(box :class "network" :orientation "h" :space-evenly false
81
86
(label :text "''${network}")))
87
87
+
88
88
+
(defwidget brightness-widget []
89
89
+
(button :class "brightness" :onclick "/run/current-system/sw/bin/switch-theme toggle"
90
90
+
(label :text "''${brightness}% ")))
91
91
+
92
92
+
(defwidget idle-inhibitor []
93
93
+
(button :class {idle-inhibited == "true" ? "idle-inhibitor active" : "idle-inhibitor"}
94
94
+
:onclick "${lib.getExe idleToggleScript}"
95
95
+
{idle-inhibited == "true" ? "" : ""}))
82
96
83
97
; Window definition - screen name passed as argument
84
98
(defwindow bar [screen]
···
153
167
min-height: 20px;
154
168
}
155
169
156
156
-
.battery, .volume, .network, .date {
170
170
+
.battery, .volume, .network, .date, .brightness {
157
171
padding: 0 8px;
158
172
margin: 0 2px;
159
173
border-radius: 4px;
160
174
background-color: #24283b;
175
175
+
}
176
176
+
177
177
+
.idle-inhibitor {
178
178
+
padding: 0 8px;
179
179
+
margin: 0 2px;
180
180
+
border-radius: 4px;
181
181
+
background-color: #24283b;
182
182
+
&.active {
183
183
+
background-color: #bb9af7;
184
184
+
color: #1a1b26;
185
185
+
}
186
186
+
&:hover {
187
187
+
background-color: #414868;
188
188
+
}
161
189
}
162
190
163
191
.systray {
···
176
204
177
205
cpuScript = pkgs.writeShellApplication {
178
206
name = "eww-cpu";
207
207
+
runtimeInputs = [ pkgs.jq ];
179
208
text = ''
180
209
STATE_FILE="/tmp/eww-cpu-state"
181
210
read -r _cpu user nice system idle _rest < /proc/stat
···
186
215
diff_total=$((total - prev_total))
187
216
diff_idle=$((idle - prev_idle))
188
217
if [ "$diff_total" -gt 0 ]; then
189
189
-
echo $((100 * (diff_total - diff_idle) / diff_total))
218
218
+
usage=$((100 * (diff_total - diff_idle) / diff_total))
190
219
else
191
191
-
echo 0
220
220
+
usage=0
192
221
fi
193
222
else
194
194
-
echo 0
223
223
+
usage=0
195
224
fi
196
225
echo "$total $idle" > "$STATE_FILE"
226
226
+
227
227
+
# Get load average (1 min)
228
228
+
load=$(cut -d' ' -f1 /proc/loadavg)
229
229
+
230
230
+
# Get average CPU frequency in MHz
231
231
+
freq=0
232
232
+
count=0
233
233
+
for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq; do
234
234
+
if [ -f "$f" ]; then
235
235
+
val=$(cat "$f")
236
236
+
freq=$((freq + val))
237
237
+
count=$((count + 1))
238
238
+
fi
239
239
+
done
240
240
+
if [ "$count" -gt 0 ]; then
241
241
+
freq=$((freq / count / 1000))
242
242
+
fi
243
243
+
244
244
+
jq -n --argjson usage "$usage" --arg load "$load" --argjson freq "$freq" \
245
245
+
'{usage: $usage, load: $load, freq: $freq}'
197
246
'';
198
247
};
199
248
···
207
256
208
257
tempScript = pkgs.writeShellApplication {
209
258
name = "eww-temp";
259
259
+
runtimeInputs = [ pkgs.jq ];
210
260
text = ''
211
211
-
temp_raw=$(cat /sys/class/thermal/thermal_zone0/temp)
212
212
-
echo $((temp_raw / 1000))
261
261
+
temp_raw=$(cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null || echo 0)
262
262
+
temp=$((temp_raw / 1000))
263
263
+
264
264
+
# Find gpdfan hwmon for fan speed
265
265
+
fan=0
266
266
+
for hwmon in /sys/class/hwmon/hwmon*; do
267
267
+
if [ "$(cat "$hwmon/name" 2>/dev/null)" = "gpdfan" ]; then
268
268
+
fan=$(cat "$hwmon/fan1_input" 2>/dev/null || echo 0)
269
269
+
break
270
270
+
fi
271
271
+
done
272
272
+
273
273
+
jq -n --argjson temp "$temp" --argjson fan "$fan" '{temp: $temp, fan: $fan}'
213
274
'';
214
275
};
215
276
···
340
401
'';
341
402
};
342
403
404
404
+
brightnessScript = pkgs.writeShellApplication {
405
405
+
name = "eww-brightness";
406
406
+
runtimeInputs = [ pkgs.brightnessctl ];
407
407
+
text = ''
408
408
+
brightnessctl -m | cut -d, -f4 | tr -d '%'
409
409
+
'';
410
410
+
};
411
411
+
412
412
+
idleToggleScript = pkgs.writeShellApplication {
413
413
+
name = "eww-idle-toggle";
414
414
+
runtimeInputs = [ pkgs.systemd ];
415
415
+
text = ''
416
416
+
if systemctl --user is-active --quiet sway-idle-inhibit.service; then
417
417
+
systemctl --user stop sway-idle-inhibit.service
418
418
+
else
419
419
+
systemctl --user start sway-idle-inhibit.service
420
420
+
fi
421
421
+
'';
422
422
+
};
423
423
+
424
424
+
idleStatusScript = pkgs.writeShellApplication {
425
425
+
name = "eww-idle-status";
426
426
+
runtimeInputs = [ pkgs.systemd ];
427
427
+
text = ''
428
428
+
if systemctl --user is-active --quiet sway-idle-inhibit.service; then
429
429
+
echo "true"
430
430
+
else
431
431
+
echo "false"
432
432
+
fi
433
433
+
'';
434
434
+
};
435
435
+
343
436
ewwConfigDir = pkgs.runCommand "eww-config" { } ''
344
437
mkdir -p $out
345
438
cp ${ewwYuck} $out/eww.yuck
···
378
471
pkgs.bash
379
472
pkgs.sway
380
473
];
474
474
+
environment.EWW_CONFIG = "${ewwConfigDir}";
381
475
serviceConfig = {
382
476
Type = "simple";
383
383
-
ExecStart = "${pkgs.eww}/bin/eww daemon --config ${ewwConfigDir} --no-daemonize";
384
384
-
ExecStop = "${pkgs.eww}/bin/eww --config ${ewwConfigDir} kill";
477
477
+
ExecStart = "${lib.getExe pkgs.eww} daemon --config ${ewwConfigDir} --no-daemonize";
478
478
+
ExecStop = "${lib.getExe pkgs.eww} --config ${ewwConfigDir} kill";
385
479
Restart = "on-failure";
386
480
RestartSec = 1;
481
481
+
};
482
482
+
};
483
483
+
484
484
+
# Idle inhibit service - toggled by eww button
485
485
+
systemd.user.services.sway-idle-inhibit = {
486
486
+
description = "Inhibit idle/sleep";
487
487
+
serviceConfig = {
488
488
+
Type = "simple";
489
489
+
ExecStart = "${pkgs.systemd}/bin/systemd-inhibit --what=idle:sleep --who=eww --why='User requested' --mode=block sleep infinity";
387
490
};
388
491
};
389
492