pragma ComponentBehavior: Bound import QtQuick import Quickshell import Quickshell.Io // Persistent widget-usage tracker: counts how often each bar widget is // opened and exposes a usage-sorted layout order. The order is snapshotted // at file load so the bar stays stable within a session and re-sorts across // restarts, while counts keep accumulating live and persist to disk. Item { id: root // Canonical widget set; array order is the tie-break for equal counts. // "clock" is intentionally absent: it is pinned at a constant bar-center // position by Bar.qml, so it must never drift in the usage-sorted order. readonly property var widgets: ["launcher", "media", "noko", "system", "clipboard", "vault", "audio", "brightness", "connectivity", "power", "notifications", "tray", "idle"] // Snapshotted once at load (see FileView.onLoaded); the bar binds to this. property var layoutOrder: widgets property bool snapshotted: false property alias usageStore: usageStoreObject function snapshot() { if (root.snapshotted) return; root.snapshotted = true; root.layoutOrder = root.ordered(); } function countFor(name) { const counts = root.usageStore.counts || ({}); return Number(counts[String(name)] || 0); } // widgets sorted by usage desc, ties broken by canonical order function ordered() { return root.widgets.slice().map((name, index) => { return { "name": name, "index": index, "count": root.countFor(name) }; }).sort((a, b) => { return (b.count - a.count) || (a.index - b.index); }).map(entry => { return entry.name; }); } function record(name) { const key = String(name); if (root.widgets.indexOf(key) < 0) return root.stateJson(); const next = Object.assign({}, root.usageStore.counts); next[key] = (Number(next[key]) || 0) + 1; root.usageStore.counts = next; root.saveCounts(); return root.stateJson(); } function stateJson() { return JSON.stringify({ "backend": "Usage.qml", "path": usageFile.path, "counts": root.usageStore.counts || ({}), "layoutOrder": root.layoutOrder, "liveOrder": root.ordered() }); } function loadCounts() { let data = {}; try { data = JSON.parse(usageFile.text() || "{}"); } catch (error) { data = {}; } root.usageStore.counts = data.counts || {}; root.snapshot(); } function saveCounts() { usageFile.setText(JSON.stringify({ "counts": root.usageStore.counts || {} }, null, 2)); } QtObject { id: usageStoreObject property var counts: ({}) } FileView { id: usageFile // Single writer (this shell), so no watchChanges: a reload on our own // write would re-snapshot layoutOrder mid-session. path: Quickshell.statePath("nuguland-widget-usage.json") printErrors: false onLoaded: root.loadCounts() onLoadFailed: root.snapshot() } }