···
1
1
import Quickshell
2
2
import Quickshell.Wayland
3
3
+
import Quickshell.Widgets
3
4
import Quickshell.Io
4
5
import Quickshell.Services.SystemTray
5
6
import QtQuick
···
65
66
readonly property string iconBatCharge: "\uf0e7"
66
67
// Power
67
68
readonly property string iconPower: "\u23fb"
68
68
-
// GitHub
69
69
-
readonly property string iconGithub: "\uf09b"
70
70
-
71
69
// System data
72
70
property int cpuUsage: 0
73
71
property int memUsage: 0
···
86
84
property string powerProfile: ""
87
85
property string powerBackend: "" // "system76" or "ppd"
88
86
property string weather: ""
89
89
-
property int ghNotifications: 0
90
90
-
property int ghLastCount: 0
91
87
92
88
anchors {
93
89
top: true
···
275
271
Component.onCompleted: running = true
276
272
}
277
273
278
278
-
// GitHub notifications
279
279
-
Process {
280
280
-
id: ghProc
281
281
-
command: ["sh", "-c", "gh api notifications --jq '[.[] | select(.unread)] | length' 2>/dev/null || echo 0"]
282
282
-
stdout: SplitParser {
283
283
-
onRead: data => {
284
284
-
if (!data) return
285
285
-
var count = parseInt(data.trim()) || 0
286
286
-
root.ghNotifications = count
287
287
-
// Send desktop notification if count increased
288
288
-
if (count > root.ghLastCount && count > 0) {
289
289
-
ghNotifyProc.running = true
290
290
-
}
291
291
-
root.ghLastCount = count
292
292
-
}
293
293
-
}
294
294
-
Component.onCompleted: running = true
295
295
-
}
296
296
-
297
297
-
// Desktop notification for new GitHub notifications
298
298
-
Process {
299
299
-
id: ghNotifyProc
300
300
-
command: ["notify-send", "-a", "GitHub", "GitHub", "You have new notifications"]
301
301
-
}
302
302
-
303
274
// Open Steam window via niri focus, fallback to spawning
304
275
Process {
305
276
id: steamOpenProc
306
277
command: ["sh", "-c", "WID=$(niri msg --json windows | jq -r '.[] | select(.app_id | test(\"steam\"; \"i\")) | .id' | head -n1); if [ -n \"$WID\" ]; then niri msg action focus-window --id \"$WID\"; else steam steam://open/games; fi"]
307
278
}
308
279
309
309
-
// GitHub timer (refresh every 2 minutes)
310
310
-
Timer {
311
311
-
interval: 120000
312
312
-
running: true
313
313
-
repeat: true
314
314
-
onTriggered: ghProc.running = true
315
315
-
}
316
316
-
317
280
// Weather timer (refresh every 15 minutes)
318
281
Timer {
319
282
interval: 900000
···
340
303
}
341
304
}
342
305
343
343
-
// Left section - time, weather, github
306
306
+
// Left section - time, weather, tray
344
307
RowLayout {
345
308
anchors.left: parent.left
346
309
anchors.leftMargin: 12
···
369
332
visible: root.weather !== ""
370
333
}
371
334
372
372
-
Rectangle { width: 1; height: 16; color: root.colOverlay0 }
373
373
-
374
374
-
Text {
375
375
-
color: root.ghNotifications > 0 ? root.colBlue : root.colOverlay0
376
376
-
font { family: root.fontFamily; pixelSize: root.fontSize }
377
377
-
text: root.iconGithub + (root.ghNotifications > 0 ? " " + root.ghNotifications : "")
378
378
-
MouseArea {
379
379
-
anchors.fill: parent
380
380
-
cursorShape: Qt.PointingHandCursor
381
381
-
onClicked: ghOpenProc.running = true
382
382
-
}
383
383
-
}
384
384
-
385
385
-
Process {
386
386
-
id: ghOpenProc
387
387
-
command: ["xdg-open", "https://github.com/notifications"]
388
388
-
}
389
389
-
390
335
Rectangle { width: 1; height: 16; color: root.colOverlay0; visible: trayRepeater.count > 0 }
391
336
392
337
Repeater {
393
338
id: trayRepeater
394
339
model: SystemTray.items.values
395
395
-
delegate: Text {
340
340
+
delegate: Item {
396
341
id: trayDelegate
397
342
required property var modelData
398
398
-
color: root.colLavender
399
399
-
font { family: root.fontFamily; pixelSize: root.fontSize }
400
400
-
text: trayDelegate.modelData.title || trayDelegate.modelData.id
343
343
+
width: trayIcon.width
344
344
+
height: trayIcon.height
345
345
+
346
346
+
IconImage {
347
347
+
id: trayIcon
348
348
+
implicitSize: 16
349
349
+
source: Quickshell.iconPath(trayDelegate.modelData.icon, true) || trayDelegate.modelData.icon
350
350
+
}
351
351
+
401
352
MouseArea {
402
353
anchors.fill: parent
403
354
cursorShape: Qt.PointingHandCursor
404
355
onClicked: {
405
356
if (trayDelegate.modelData.id.toLowerCase().indexOf("steam") !== -1) {
406
357
steamOpenProc.running = true
358
358
+
} else if (trayDelegate.modelData.onlyMenu || trayDelegate.modelData.hasMenu) {
359
359
+
trayDelegate.modelData.display(root, trayDelegate.x, root.height)
407
360
} else {
408
361
trayDelegate.modelData.activate()
409
362
}