We now own the pinned shell, so the runtime patches that the pacman-hook + patch-script machinery re-applied after every caelestia-shell upgrade are baked directly into source. Folds in all five caelestia-shell-targeting patches from the builder's `os updates/`: - Lock PAM (F1, blocker): ship faillock-free assets/pam.d/caelestia and point modules/lock/Pam.qml's passwd PamContext at it (config "passwd" -> "caelestia"). A desktop screen-lock must never lock the user out of their own session. - Updates page: add modules/nexus/pages/UpdatesPage.qml + register it in the first System slot of PageCompRegistry.qml. - Additions page: add modules/nexus/pages/AdditionsPage.qml + register it in the Plugins slot; relabel Plugins -> Additions in PageRegistry.qml. - Sudo toggle: add modules/nexus/common/SudoToggleRow.qml + insert it into ServicesPage.qml after the Smart colour scheme toggle. - Wi-Fi wrong-password recovery: NetworkConnection.qml saved-profile branch now passes a real callback that forgets the bad profile and reopens the dialog. The builder will drop the corresponding patch-*.sh calls + pacman hooks and bump NOSIGNAL_SHELL_COMMIT to this commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
69 lines
2.3 KiB
QML
69 lines
2.3 KiB
QML
// SudoToggleRow.qml (NoSignal) — Settings -> Services toggle for time-boxed
|
|
// passwordless sudo. Reflects live state by polling `nosignal-sudo-toggle
|
|
// status` (no root needed); enabling opens a floating terminal for the ONE
|
|
// password prompt, disabling runs passwordless inside the active window.
|
|
//
|
|
// Untracked file under modules/nexus/common — auto-discovered as the type
|
|
// `SudoToggleRow` via `import qs.modules.nexus.common`. Survives caelestia
|
|
// upgrades; only the one-line insert in ServicesPage.qml is re-applied by hook.
|
|
import QtQuick
|
|
import Quickshell.Io
|
|
import qs.modules.nexus.common
|
|
|
|
ToggleRow {
|
|
id: root
|
|
|
|
property bool active: false
|
|
property int remaining: 0
|
|
|
|
text: qsTr("Passwordless sudo (15 min)")
|
|
subtext: active
|
|
? qsTr("On — %1 min left. Auto-reverts; a reboot also clears it.").arg(remaining)
|
|
: qsTr("Run sudo without a password for 15 minutes, then it reverts")
|
|
|
|
onToggled: {
|
|
if (checked)
|
|
enableProc.running = true; // needs a password -> floating terminal
|
|
else
|
|
disableProc.running = true; // no password inside the active window
|
|
reconcile.restart();
|
|
}
|
|
|
|
// --- live state -----------------------------------------------------------
|
|
Process {
|
|
id: statusProc
|
|
command: ["nosignal-sudo-toggle", "status"]
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
const p = text.trim().split(/\s+/);
|
|
root.active = p[0] === "active";
|
|
root.remaining = parseInt(p[1] || "0") || 0;
|
|
root.checked = root.active; // drive switch from real state
|
|
}
|
|
}
|
|
}
|
|
|
|
// --- actions --------------------------------------------------------------
|
|
Process {
|
|
id: enableProc
|
|
command: ["kitty", "--class", "TUI.float", "-e", "sudo", "nosignal-sudo-toggle", "enable"]
|
|
}
|
|
Process {
|
|
id: disableProc
|
|
command: ["sudo", "-n", "nosignal-sudo-toggle", "disable"]
|
|
}
|
|
|
|
// --- polling --------------------------------------------------------------
|
|
Timer {
|
|
interval: 5000
|
|
repeat: true
|
|
running: true
|
|
triggeredOnStart: true
|
|
onTriggered: statusProc.running = true
|
|
}
|
|
Timer {
|
|
id: reconcile
|
|
interval: 2000
|
|
onTriggered: statusProc.running = true
|
|
}
|
|
}
|