Spawn shell subprocesses with bash -c instead of bash -lc

Each `bash -lc` starts a login shell that re-sources the profile
(mise activation, /etc/profile.d) on every invocation — ~16 forks per
call versus ~2 for `bash -c` — which taxes every menu/panel/launcher
action the shell shells out for. The session already exports PATH and
env to the shell, so omarchy commands resolve fine under `bash -c`.

Switch the internal/omarchy-owned spawns (theme+background switches,
brightness, monitor scaling, DNS, lock/fingerprint, keyboard-layout
probe, voxtype status, and the `:`/printf state-file writes) to
`bash -c`. Leave `bash -lc` on the sites that run user-configurable
commands (custom bar-widget exec, menu provider/guard scripts,
launcher scan commands, configurable idle/screensaver command), where
a user's command may rely on their login environment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-07-19 22:46:27 -07:00
co-authored by Claude Fable 5
parent 4d630c9f30
commit a64d895a02
10 changed files with 18 additions and 18 deletions
+2 -2
View File
@@ -109,13 +109,13 @@ Item {
Process { Process {
id: bgSwitchProc id: bgSwitchProc
command: ["bash", "-lc", "background=$(omarchy-theme-bg-switcher); [[ -n $background ]] && omarchy-theme-bg-set \"$background\""] command: ["bash", "-c", "background=$(omarchy-theme-bg-switcher); [[ -n $background ]] && omarchy-theme-bg-set \"$background\""]
onExited: root.refreshBackground() onExited: root.refreshBackground()
} }
Process { Process {
id: themeSwitchProc id: themeSwitchProc
command: ["bash", "-lc", "theme=$(omarchy-theme-switcher); [[ -n $theme ]] && omarchy-theme-set \"$theme\" >/dev/null 2>&1 &"] command: ["bash", "-c", "theme=$(omarchy-theme-switcher); [[ -n $theme ]] && omarchy-theme-set \"$theme\" >/dev/null 2>&1 &"]
onExited: root.refreshBackground() onExited: root.refreshBackground()
} }
+1 -1
View File
@@ -807,7 +807,7 @@ Item {
Process { Process {
id: barHiddenProbe id: barHiddenProbe
running: true running: true
command: ["bash", "-lc", "[[ -f $HOME/.local/state/omarchy/toggles/bar-off ]] && echo yes || echo no"] command: ["bash", "-c", "[[ -f $HOME/.local/state/omarchy/toggles/bar-off ]] && echo yes || echo no"]
stdout: SplitParser { onRead: function(line) { root.barHidden = String(line).trim() === "yes" } } stdout: SplitParser { onRead: function(line) { root.barHidden = String(line).trim() === "yes" } }
} }
FileView { FileView {
+1 -1
View File
@@ -24,7 +24,7 @@ BarIndicator {
} }
Process { Process {
command: ["bash", "-lc", "omarchy-voxtype-status"] command: ["bash", "-c", "omarchy-voxtype-status"]
running: true running: true
stdout: SplitParser { stdout: SplitParser {
onRead: function(data) { root.update(data) } onRead: function(data) { root.update(data) }
+1 -1
View File
@@ -34,7 +34,7 @@ BarWidget {
Process { Process {
id: queryProc id: queryProc
command: ["bash", "-lc", "hyprctl -j devices 2>/dev/null | sed -n '/keyboards/,$p' | head -200"] command: ["bash", "-c", "hyprctl -j devices 2>/dev/null | sed -n '/keyboards/,$p' | head -200"]
stdout: StdioCollector { stdout: StdioCollector {
waitForEnd: true waitForEnd: true
onStreamFinished: { onStreamFinished: {
+2 -2
View File
@@ -139,7 +139,7 @@ Item {
if (releaseProc.running || doneFilesToRelease.length === 0) return if (releaseProc.running || doneFilesToRelease.length === 0) return
var path = doneFilesToRelease.shift() var path = doneFilesToRelease.shift()
releaseProc.command = ["bash", "-lc", ": > " + Util.shellQuote(path)] releaseProc.command = ["bash", "-c", ": > " + Util.shellQuote(path)]
releaseProc.running = true releaseProc.running = true
} }
@@ -163,7 +163,7 @@ Item {
selectionFile = "" selectionFile = ""
doneFile = "" doneFile = ""
applyProc.command = ["bash", "-lc", "printf '%s\\n' " + Util.shellQuote(path) + " > " + Util.shellQuote(activeSelectionFile) + "; : > " + Util.shellQuote(activeDoneFile)] applyProc.command = ["bash", "-c", "printf '%s\\n' " + Util.shellQuote(path) + " > " + Util.shellQuote(activeSelectionFile) + "; : > " + Util.shellQuote(activeDoneFile)]
applyProc.running = true applyProc.running = true
} }
+3 -3
View File
@@ -352,7 +352,7 @@ Item {
Process { Process {
id: fingerprintCheckProc id: fingerprintCheckProc
command: ["bash", "-lc", "if [[ -f /etc/pam.d/omarchy-lock-fingerprint ]] && command -v fprintd-list >/dev/null 2>&1 && fprintd-list \"$USER\" 2>/dev/null | grep -qi finger; then echo yes; else echo no; fi"] command: ["bash", "-c", "if [[ -f /etc/pam.d/omarchy-lock-fingerprint ]] && command -v fprintd-list >/dev/null 2>&1 && fprintd-list \"$USER\" 2>/dev/null | grep -qi finger; then echo yes; else echo no; fi"]
stdout: StdioCollector { id: fingerprintCheckStdout; waitForEnd: true } stdout: StdioCollector { id: fingerprintCheckStdout; waitForEnd: true }
onExited: { onExited: {
root.fingerprintConfigured = String(fingerprintCheckStdout.text || "").trim() === "yes" root.fingerprintConfigured = String(fingerprintCheckStdout.text || "").trim() === "yes"
@@ -363,12 +363,12 @@ Item {
Process { Process {
id: wakeProcess id: wakeProcess
command: ["bash", "-lc", "omarchy-system-wake"] command: ["bash", "-c", "omarchy-system-wake"]
} }
Process { Process {
id: blankProcess id: blankProcess
command: ["bash", "-lc", "omarchy-brightness-keyboard off; omarchy-brightness-display off"] command: ["bash", "-c", "omarchy-brightness-keyboard off; omarchy-brightness-display off"]
} }
Timer { Timer {
+2 -2
View File
@@ -115,9 +115,9 @@ Item {
root.doneFile = "" root.doneFile = ""
if (selection === null || selection === undefined) { if (selection === null || selection === undefined) {
resultProc.command = ["bash", "-lc", ": > " + Util.shellQuote(activeDoneFile)] resultProc.command = ["bash", "-c", ": > " + Util.shellQuote(activeDoneFile)]
} else { } else {
resultProc.command = ["bash", "-lc", "printf '%s\\n' " + Util.shellQuote(selection) + " > " + Util.shellQuote(activeSelectionFile) + "; : > " + Util.shellQuote(activeDoneFile)] resultProc.command = ["bash", "-c", "printf '%s\\n' " + Util.shellQuote(selection) + " > " + Util.shellQuote(activeSelectionFile) + "; : > " + Util.shellQuote(activeDoneFile)]
} }
resultProc.running = true resultProc.running = true
} }
+2 -2
View File
@@ -213,7 +213,7 @@ Panel {
} }
root.brightnessSetQueued = false root.brightnessSetQueued = false
setBrightnessProc.command = ["bash", "-lc", "omarchy-brightness-display --no-osd " + percent + "%"] setBrightnessProc.command = ["bash", "-c", "omarchy-brightness-display --no-osd " + percent + "%"]
setBrightnessProc.running = true setBrightnessProc.running = true
} }
@@ -248,7 +248,7 @@ Panel {
} }
function setScale(scale) { function setScale(scale) {
actionProc.command = ["bash", "-lc", "omarchy-hyprland-monitor-scaling " + scale] actionProc.command = ["bash", "-c", "omarchy-hyprland-monitor-scaling " + scale]
if (!actionProc.running) actionProc.running = true if (!actionProc.running) actionProc.running = true
} }
+3 -3
View File
@@ -262,7 +262,7 @@ Panel {
function copyToClipboard(value) { function copyToClipboard(value) {
if (!value || !root.bar) return if (!value || !root.bar) return
Quickshell.execDetached(["bash", "-lc", "printf %s " + Util.shellQuote(value) + " | wl-copy"]) Quickshell.execDetached(["bash", "-c", "printf %s " + Util.shellQuote(value) + " | wl-copy"])
} }
readonly property string icon: Model.connectionIcon(kind, signalStrength) readonly property string icon: Model.connectionIcon(kind, signalStrength)
@@ -271,7 +271,7 @@ Panel {
if (scanWifi === undefined) scanWifi = false if (scanWifi === undefined) scanWifi = false
if (!detailsProc.running) detailsProc.running = true if (!detailsProc.running) detailsProc.running = true
if (!dnsProc.running) { if (!dnsProc.running) {
dnsProc.command = ["bash", "-lc", root.dnsCommand("")] dnsProc.command = ["bash", "-c", root.dnsCommand("")]
dnsProc.running = true dnsProc.running = true
} }
if (wifiDevice) { if (wifiDevice) {
@@ -467,7 +467,7 @@ Panel {
} }
root.pendingDnsProvider = provider root.pendingDnsProvider = provider
actionProc.command = ["bash", "-lc", root.dnsCommand(provider)] actionProc.command = ["bash", "-c", root.dnsCommand(provider)]
actionProc.running = true actionProc.running = true
root.close() root.close()
} }
+1 -1
View File
@@ -300,7 +300,7 @@ Item {
Process { Process {
id: stayAwakeStateProbe id: stayAwakeStateProbe
command: ["bash", "-lc", "mkdir -p \"$HOME/.local/state/omarchy/indicators\"; if [[ -f $HOME/.local/state/omarchy/indicators/stay-awake ]]; then echo yes; else echo no; fi"] command: ["bash", "-c", "mkdir -p \"$HOME/.local/state/omarchy/indicators\"; if [[ -f $HOME/.local/state/omarchy/indicators/stay-awake ]]; then echo yes; else echo no; fi"]
stdout: SplitParser { stdout: SplitParser {
onRead: function(line) { root.applyStayAwake(String(line).trim() === "yes", false, "state-file") } onRead: function(line) { root.applyStayAwake(String(line).trim() === "yes", false, "state-file") }
} }