colour -> color, behaviour -> behavior, centre -> center, favourite -> favorite, and about twenty other pairs, applied consistently across comments, docs, error/UI copy, and a handful of QML identifiers that used the British spelling as their actual name: SystemSettings' serialiseValue/serialiseTable/normaliseGradient, Displays' normaliseModes, Wallpaper's normalisePolicy, SettingsBackup's serialiseHomeState, DateTime's ntpSynchronised property, Clipboard's _normalise helper, and ShortcutCapture's cancelled signal (with its onCancelled handler in ShortcutsPage.qml). Every call site and the two tests that assert on the literal source text (settings-ownership and settings-backup-live contracts) were updated in lockstep. Left untouched: config/dot/espanso/match/packages/misspell-en/ is a vendored third-party autocorrect dictionary -- its entries are typo corrections, not our prose, and rewriting them would fight the package's own purpose (and any future re-sync from upstream). The already-American `favorites` property (Home page pinned accessories) was never actually misspelled -- only nearby comments and error strings said "favourites" -- so no data migration was needed there. Claude-Session: https://claude.ai/code/session_01E6TJUAh41HaP25MVHWkhRZ
90 lines
3.0 KiB
QML
90 lines
3.0 KiB
QML
pragma Singleton
|
|
|
|
// The GPUs that can report utilisation.
|
|
//
|
|
// The vitals readout needs one specific sysfs file, and card numbering is
|
|
// neither stable across machines nor meaningful to a person -- this machine has
|
|
// two amdgpu cards, one discrete and one integrated, and picking a number
|
|
// blindly measures whichever the kernel enumerated first.
|
|
//
|
|
// Enumerated on demand rather than polled: hardware does not appear while you
|
|
// are looking at a settings page.
|
|
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import QtQuick
|
|
import qs.config
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
readonly property string helperPath: Quickshell.shellDir + "/scripts/panama-gpus"
|
|
|
|
// [{ card, path, name, busy }]
|
|
property var devices: []
|
|
property bool scanning: false
|
|
property string lastError: ""
|
|
|
|
readonly property string selectedPath: DesktopPreferences.get("gpuBusyPath")
|
|
|
|
readonly property var selected: root.devices.find(device => device.path === root.selectedPath) ?? null
|
|
|
|
// True when a GPU is stored that this machine does not have -- after moving
|
|
// the settings file between machines, say.
|
|
readonly property bool selectionMissing: root.devices.length > 0 && root.selected === null
|
|
|
|
Process {
|
|
id: scan
|
|
command: [root.helperPath]
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
try {
|
|
const parsed = JSON.parse(this.text);
|
|
root.devices = Array.isArray(parsed) ? parsed : [];
|
|
root.lastError = "";
|
|
} catch (error) {
|
|
root.devices = [];
|
|
root.lastError = "The graphics devices could not be read.";
|
|
}
|
|
root.scanning = false;
|
|
}
|
|
}
|
|
onExited: (exitCode, exitStatus) => {
|
|
root.scanning = false;
|
|
if (exitCode !== 0)
|
|
root.lastError = "The graphics devices could not be read.";
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: root.refresh()
|
|
|
|
function refresh(): void {
|
|
if (scan.running)
|
|
return;
|
|
root.scanning = true;
|
|
scan.running = true;
|
|
}
|
|
|
|
// Only a path this machine actually reported is accepted, so a hand-edited
|
|
// settings file cannot point the readout at an arbitrary file.
|
|
function select(path: string): bool {
|
|
if (!root.devices.some(device => device.path === path)) {
|
|
root.lastError = "That graphics device is not present.";
|
|
return false;
|
|
}
|
|
if (!DesktopPreferences.set("gpuBusyPath", path)) {
|
|
root.lastError = "That graphics device could not be saved.";
|
|
return false;
|
|
}
|
|
root.lastError = "";
|
|
return true;
|
|
}
|
|
|
|
// "AMD ... [Radeon RX 7700 XT / 7800 XT] (rev c8)" is what lspci gives; the
|
|
// bracketed marketing name is the part anyone recognizes.
|
|
function shortName(name: string): string {
|
|
const bracketed = String(name).match(/\[([^\]]+)\]\s*(?:\(rev[^)]*\))?\s*$/);
|
|
return bracketed ? bracketed[1] : String(name).replace(/\s*\(rev[^)]*\)\s*$/, "");
|
|
}
|
|
}
|