diff --git a/core/internal/server/sysupdate/backend_pacman.go b/core/internal/server/sysupdate/backend_pacman.go index e07f404af..09070e522 100644 --- a/core/internal/server/sysupdate/backend_pacman.go +++ b/core/internal/server/sysupdate/backend_pacman.go @@ -112,7 +112,7 @@ func (b archHelperBackend) Upgrade(ctx context.Context, opts UpgradeOptions, onL } cmd := strings.Join(archHelperUpgradeArgv(b.id, opts.IncludeAUR, opts.Ignored), " ") title := fmt.Sprintf("DMS — System Update (%s)", b.id) - return Run(ctx, wrapInTerminal(term, title, cmd), RunOptions{OnLine: onLine}) + return Run(ctx, wrapInTerminal(term, title, cmd, opts.TerminalArgs), RunOptions{OnLine: onLine}) } func archHelperUpgradeArgv(id string, includeAUR bool, ignored []string) []string { diff --git a/core/internal/server/sysupdate/executor.go b/core/internal/server/sysupdate/executor.go index 8d6891900..1dc256d1a 100644 --- a/core/internal/server/sysupdate/executor.go +++ b/core/internal/server/sysupdate/executor.go @@ -119,7 +119,7 @@ func findTerminal(override string) string { return "" } -func wrapInTerminal(term, title, shellCmd string) []string { +func wrapInTerminal(term, title, shellCmd string, extraArgs []string) []string { const appID = "com.danklinux.dms" banner := fmt.Sprintf( `printf '\033[1;36m=== %s ===\033[0m\n'; printf '\033[2m$ %s\033[0m\n'; printf '\033[33mYou may be prompted for your sudo password to apply system updates.\033[0m\n\n'`, @@ -129,24 +129,25 @@ func wrapInTerminal(term, title, shellCmd string) []string { export := `export SUDO_PROMPT="[DMS] sudo password for %u: "; ` full := export + banner + "; " + shellCmd + "; " + closer + var argv []string + execFlag := "-e" switch term { - case "kitty": - return []string{term, "--class", appID, "-T", title, "-e", "sh", "-c", full} - case "alacritty": - return []string{term, "--class", appID, "-T", title, "-e", "sh", "-c", full} + case "kitty", "alacritty", "wezterm": + argv = []string{term, "--class", appID, "-T", title} case "foot": - return []string{term, "--app-id=" + appID, "--title=" + title, "-e", "sh", "-c", full} + argv = []string{term, "--app-id=" + appID, "--title=" + title} case "ghostty": - return []string{term, "--class=" + appID, "--title=" + title, "-e", "sh", "-c", full} - case "wezterm": - return []string{term, "--class", appID, "-T", title, "-e", "sh", "-c", full} + argv = []string{term, "--class=" + appID, "--title=" + title} case "xterm": - return []string{term, "-class", appID, "-T", title, "-e", "sh", "-c", full} + argv = []string{term, "-class", appID, "-T", title} case "konsole": - return []string{term, "-p", "tabtitle=" + title, "-e", "sh", "-c", full} + argv = []string{term, "-p", "tabtitle=" + title} case "gnome-terminal": - return []string{term, "--title=" + title, "--", "sh", "-c", full} + argv = []string{term, "--title=" + title} + execFlag = "--" default: - return []string{term, "-e", "sh", "-c", full} + argv = []string{term} } + argv = append(argv, extraArgs...) + return append(argv, execFlag, "sh", "-c", full) } diff --git a/core/internal/server/sysupdate/handlers.go b/core/internal/server/sysupdate/handlers.go index a0f7e1a79..42dd0db05 100644 --- a/core/internal/server/sysupdate/handlers.go +++ b/core/internal/server/sysupdate/handlers.go @@ -46,6 +46,7 @@ func handleUpgrade(conn net.Conn, req models.Request, m *Manager) { DryRun: params.BoolOpt(req.Params, "dry", false), CustomCommand: params.StringOpt(req.Params, "customCommand", ""), Terminal: params.StringOpt(req.Params, "terminal", ""), + TerminalArgs: stringSliceOpt(req.Params, "terminalArgs"), Ignored: stringSliceOpt(req.Params, "ignored"), } if err := m.Upgrade(opts); err != nil { diff --git a/core/internal/server/sysupdate/manager.go b/core/internal/server/sysupdate/manager.go index c54263d30..f4fcedfad 100644 --- a/core/internal/server/sysupdate/manager.go +++ b/core/internal/server/sysupdate/manager.go @@ -336,7 +336,7 @@ func (m *Manager) runUpgrade(ctx context.Context, opts UpgradeOptions) { }() if opts.CustomCommand != "" { - m.runCustomUpgrade(ctx, opts.CustomCommand, opts.Terminal) + m.runCustomUpgrade(ctx, opts) return } @@ -389,8 +389,8 @@ func (m *Manager) runUpgrade(ctx context.Context, opts UpgradeOptions) { m.finishSuccessfulUpgrade(true) } -func (m *Manager) runCustomUpgrade(ctx context.Context, command, terminalOverride string) { - term := findTerminal(terminalOverride) +func (m *Manager) runCustomUpgrade(ctx context.Context, opts UpgradeOptions) { + term := findTerminal(opts.Terminal) if term == "" { m.setError(ErrCodeBackendFailed, "no terminal found (pick one in DMS settings, set $TERMINAL, or install kitty/ghostty/foot/alacritty)") return @@ -407,7 +407,7 @@ func (m *Manager) runCustomUpgrade(ctx context.Context, command, terminalOverrid m.markDirty() onLine := func(line string) { m.appendLog(line) } - argv := wrapInTerminal(term, "DMS — System Update (custom)", command) + argv := wrapInTerminal(term, "DMS — System Update (custom)", opts.CustomCommand, opts.TerminalArgs) if err := Run(ctx, argv, RunOptions{OnLine: onLine}); err != nil { code := ErrCodeBackendFailed switch { @@ -425,6 +425,7 @@ func (m *Manager) runCustomUpgrade(ctx context.Context, command, terminalOverrid } m.finishSuccessfulUpgrade(false) + m.runRefresh(context.Background(), false) } func (m *Manager) finishSuccessfulUpgrade(clearPackages bool) { diff --git a/core/internal/server/sysupdate/types.go b/core/internal/server/sysupdate/types.go index 63ea14f92..8664ef3f5 100644 --- a/core/internal/server/sysupdate/types.go +++ b/core/internal/server/sysupdate/types.go @@ -80,6 +80,7 @@ type UpgradeOptions struct { AttachStdio bool CustomCommand string Terminal string + TerminalArgs []string Targets []Package Ignored []string } diff --git a/quickshell/Modules/DankBar/Popouts/SystemUpdatePopout.qml b/quickshell/Modules/DankBar/Popouts/SystemUpdatePopout.qml index 721bbd43d..673f41d42 100644 --- a/quickshell/Modules/DankBar/Popouts/SystemUpdatePopout.qml +++ b/quickshell/Modules/DankBar/Popouts/SystemUpdatePopout.qml @@ -74,7 +74,7 @@ DankPopout { color: "transparent" focus: true - readonly property bool hasTerminalBackend: (SystemUpdateService.backends || []).some(b => b.runsInTerminal === true) + readonly property bool upgradeRunsInTerminal: SystemUpdateService.useCustomCommand || (SystemUpdateService.backends || []).some(b => b.runsInTerminal === true) property int nowUnix: Math.floor(Date.now() / 1000) @@ -272,7 +272,7 @@ DankPopout { includeAUR: SettingsData.updaterAllowAUR, terminal: SessionData.terminalOverride }; - if (updaterPanel.hasTerminalBackend) { + if (updaterPanel.upgradeRunsInTerminal) { systemUpdatePopout._reopenAfterUpgrade = true; SystemUpdateService.runUpdates(opts); systemUpdatePopout.close(); @@ -478,7 +478,7 @@ DankPopout { anchors.fill: parent anchors.margins: Theme.spacingM spacing: Theme.spacingS - visible: SystemUpdateService.isUpgrading && updaterPanel.hasTerminalBackend + visible: SystemUpdateService.isUpgrading && updaterPanel.upgradeRunsInTerminal DankIcon { anchors.horizontalCenter: parent.horizontalCenter @@ -509,7 +509,7 @@ DankPopout { DankFlickable { anchors.fill: parent anchors.margins: Theme.spacingM - visible: SystemUpdateService.isUpgrading && !updaterPanel.hasTerminalBackend + visible: SystemUpdateService.isUpgrading && !updaterPanel.upgradeRunsInTerminal contentWidth: width contentHeight: logText.implicitHeight clip: true diff --git a/quickshell/Services/SystemUpdateService.qml b/quickshell/Services/SystemUpdateService.qml index 90e7b52c0..b7dc5ba2f 100644 --- a/quickshell/Services/SystemUpdateService.qml +++ b/quickshell/Services/SystemUpdateService.qml @@ -3,7 +3,6 @@ pragma ComponentBehavior: Bound import QtQuick import Quickshell -import Quickshell.Io import qs.Common import qs.Services @@ -34,6 +33,7 @@ Singleton { readonly property int updateCount: availableUpdates.length readonly property bool helperAvailable: sysupdateAvailable && backends.length > 0 + readonly property bool useCustomCommand: SettingsData.updaterUseCustomCommand && (SettingsData.updaterCustomCommand || "").trim().length > 0 Connections { target: DMSService @@ -183,11 +183,14 @@ Singleton { function runUpdates(opts) { const params = opts || {}; - if (SettingsData.updaterUseCustomCommand && SettingsData.updaterCustomCommand.length > 0) { - _runCustomTerminalCommand(); - return; - } params.ignored = SettingsData.updaterIgnoredPackages || []; + if (useCustomCommand) { + params.customCommand = SettingsData.updaterCustomCommand.trim(); + const termArgs = (SettingsData.updaterTerminalAdditionalParams || "").trim(); + if (termArgs.length > 0) { + params.terminalArgs = termArgs.split(/\s+/); + } + } DMSService.sysupdateUpgrade(params, null); } @@ -199,30 +202,6 @@ Singleton { DMSService.sysupdateSetInterval(seconds, null); } - function _runCustomTerminalCommand() { - const terminal = SessionData.resolveTerminal(); - if (!terminal || terminal.length === 0) { - ToastService.showError(I18n.tr("No terminal configured"), I18n.tr("Pick a terminal in Settings → Launcher (or set $TERMINAL).")); - return; - } - const updateCommand = `${SettingsData.updaterCustomCommand} && echo -n "Updates complete! " ; echo "Press Enter to close..." && read`; - const termClass = SettingsData.updaterTerminalAdditionalParams || ""; - var argv = [terminal]; - if (termClass.length > 0) { - argv = argv.concat(termClass.split(" ")); - } - argv.push("-e"); - argv.push("sh"); - argv.push("-c"); - argv.push(updateCommand); - customRunner.command = argv; - customRunner.running = true; - } - - Process { - id: customRunner - } - property bool _startupCheckDone: false function _maybeStartupCheck() { @@ -262,5 +241,4 @@ Singleton { } DMSService.sysupdateRelease(null); } - }