feat: Add support for swww and wallust and clean up a few things

This commit is contained in:
ferreo 2025-07-13 14:09:59 +01:00
parent d828e3d323
commit bd0135ec03
22 changed files with 1053 additions and 281 deletions

View file

@ -1,70 +0,0 @@
import QtQuick
import Quickshell.Io
QtObject {
// List all known devices
function listDevices(callback) {
var proc = Qt.createQmlObject('
import Quickshell.Io;\n\
Process {\n\
command: ["bluetoothctl", "devices"],\n\
running: true;\n\
stdout: StdioCollector {\n\
onStreamFinished: {\n\
var lines = this.text.split("\n");\n\
var devs = [];\n\
for (var i = 0; i < lines.length; ++i) {\n\
var line = lines[i].trim();\n\
if (line.startsWith("Device ")) {\n\
var parts = line.split(" ");\n\
var mac = parts[1];\n\
var name = parts.slice(2).join(" ");\n\
devs.push({ mac: mac, name: name });\n\
}\n\
}\n\
callback(devs);\n\
parent.destroy();\n\
}\n\
}\n\
}', this);
}
// Check if a device is connected
function checkConnected(mac, callback) {
var proc = Qt.createQmlObject('
import Quickshell.Io;\n\
Process {\n\
command: ["bluetoothctl", "info", "' + mac + '"],\n\
running: true;\n\
stdout: StdioCollector {\n\
onStreamFinished: {\n\
var connected = this.text.indexOf("Connected: yes") !== -1;\n\
callback(connected);\n\
parent.destroy();\n\
}\n\
}\n\
}', this);
}
// Connect to a device
function connect(mac, callback) {
var proc = Qt.createQmlObject('
import Quickshell.Io;\n\
Process {\n\
command: ["bluetoothctl", "connect", "' + mac + '"],\n\
running: true;\n\
stdout: StdioCollector { onStreamFinished: { callback(true); parent.destroy(); } }\n\
}', this);
}
// Disconnect from a device
function disconnect(mac, callback) {
var proc = Qt.createQmlObject('
import Quickshell.Io;\n\
Process {\n\
command: ["bluetoothctl", "disconnect", "' + mac + '"],\n\
running: true;\n\
stdout: StdioCollector { onStreamFinished: { callback(true); parent.destroy(); } }\n\
}', this);
}
}

View file

@ -675,4 +675,4 @@ var noTarget = prepare('')
// Hacked version of https://github.com/lemire/FastPriorityQueue.js
var fastpriorityqueue=r=>{var e=[],o=0,a={},v=r=>{for(var a=0,v=e[a],c=1;c<o;){var s=c+1;a=c,s<o&&e[s]._score<e[c]._score&&(a=s),e[a-1>>1]=e[a],c=1+(a<<1)}for(var f=a-1>>1;a>0&&v._score<e[f]._score;f=(a=f)-1>>1)e[a]=e[f];e[a]=v};return a.add=(r=>{var a=o;e[o++]=r;for(var v=a-1>>1;a>0&&r._score<e[v]._score;v=(a=v)-1>>1)e[a]=e[v];e[a]=r}),a.poll=(r=>{if(0!==o){var a=e[0];return e[0]=e[--o],v(),a}}),a.peek=(r=>{if(0!==o)return e[0]}),a.replaceTop=(r=>{e[0]=r,v()}),a}
var q = fastpriorityqueue() // reuse this
var q = fastpriorityqueue() // reuse this

View file

@ -1,7 +0,0 @@
pragma Singleton
import QtQuick
QtObject {
// Global username, set at app startup
property string userName: "User"
}

View file

@ -1,68 +0,0 @@
pragma Singleton
import QtQuick
import Quickshell.Io
QtObject {
id: processesRoot
property string userName: "User"
property string uptimeText: "--:--"
property int uptimeUpdateTrigger: 0
property Process whoamiProcess: Process {
command: ["whoami"]
running: false
stdout: StdioCollector {
onStreamFinished: {
processesRoot.userName = this.text.trim()
whoamiProcess.running = false
}
}
}
property Process shutdownProcess: Process {
command: ["shutdown", "-h", "now"]
running: false
}
property Process rebootProcess: Process {
command: ["reboot"]
running: false
}
property Process logoutProcess: Process {
command: ["niri", "msg", "action", "quit", "--skip-confirmation"]
running: false
}
property Process uptimeProcess: Process {
command: ["sh", "-c", "uptime | awk -F 'up ' '{print $2}' | awk -F ',' '{print $1}' | xargs"]
running: false
stdout: StdioCollector {
onStreamFinished: {
processesRoot.uptimeText = this.text.trim()
uptimeProcess.running = false
}
}
}
Component.onCompleted: {
whoamiProcess.running = true
updateUptime()
}
function shutdown() {
shutdownProcess.running = true
}
function reboot() {
rebootProcess.running = true
}
function logout() {
logoutProcess.running = true
}
function updateUptime() {
uptimeProcess.running = true
}
onUptimeUpdateTriggerChanged: {
uptimeProcess.running = true
}
}

View file

@ -1,53 +0,0 @@
import QtQuick
Item {
id: root
property bool running: false
property color color: "white"
property int size: 16
property int strokeWidth: 2
property int duration: 1000
implicitWidth: size
implicitHeight: size
Canvas {
id: spinnerCanvas
anchors.fill: parent
onPaint: {
var ctx = getContext("2d")
ctx.reset()
var centerX = width / 2
var centerY = height / 2
var radius = Math.min(width, height) / 2 - strokeWidth / 2
ctx.strokeStyle = root.color
ctx.lineWidth = root.strokeWidth
ctx.lineCap = "round"
// Draw arc with gap (270 degrees with 90 degree gap)
ctx.beginPath()
ctx.arc(centerX, centerY, radius, -Math.PI/2 + rotationAngle, -Math.PI/2 + rotationAngle + Math.PI * 1.5)
ctx.stroke()
}
property real rotationAngle: 0
onRotationAngleChanged: {
requestPaint()
}
NumberAnimation {
target: spinnerCanvas
property: "rotationAngle"
running: root.running
from: 0
to: 2 * Math.PI
duration: root.duration
loops: Animation.Infinite
}
}
}

View file

@ -1,58 +0,0 @@
pragma Singleton
import QtQuick
import Quickshell.Io
Item {
id: manager
// Hardcoded directory for v1
property string wallpaperDirectory: "/home/lysec/nixos/assets/wallpapers"
property var wallpaperList: []
property string currentWallpaper: ""
property bool scanning: false
// Log initial state
Component.onCompleted: {
loadWallpapers()
}
// Scan directory for wallpapers
function loadWallpapers() {
scanning = true;
wallpaperList = [];
findProcess.tempList = [];
findProcess.running = true;
}
function setCurrentWallpaper(path) {
currentWallpaper = path;
}
Process {
id: findProcess
property var tempList: []
running: false
command: ["find", manager.wallpaperDirectory, "-type", "f", "-name", "*.png", "-o", "-name", "*.jpg", "-o", "-name", "*.jpeg"]
onRunningChanged: {
}
stdout: StdioCollector {
onStreamFinished: {
var lines = text.split("\n");
for (var i = 0; i < lines.length; ++i) {
var trimmed = lines[i].trim();
if (trimmed) {
findProcess.tempList.push(trimmed);
}
}
}
}
stderr: StdioCollector {
onStreamFinished: {
}
}
onExited: {
manager.wallpaperList = findProcess.tempList.slice();
scanning = false;
}
}
}