Keep AppLibrary scans out of login shells (#6815)

* Keep AppLibrary scans out of login shells

A login shell sources the user's profile, and tools like mise touch
~/.local/share on activation. Quickshell's desktop-entry watcher monitors
that tree, so every scan retriggered another scan: a self-sustaining loop
that pinned ~20% of a core at idle. The scans only use bash builtins,
find, and sort, so they don't need the login environment.

Fixes #6806

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Pin the AppLibrary scans to non-login shells in tests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-08-13 19:30:56 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 5b8fef406f
commit b08598086c
2 changed files with 13 additions and 2 deletions
+6 -2
View File
@@ -187,9 +187,13 @@ Item {
property string text: ""
}
// Both scans must run in non-login shells. A login shell sources the user's
// profile, and tools like mise touch ~/.local/share on activation — a
// directory the desktop-entry watcher monitors — so every scan would
// trigger the next one, pinning a core at idle.
Process {
id: hiddenEntryScan
command: ["bash", "-lc", root.hiddenEntryScanCommand()]
command: ["bash", "-c", root.hiddenEntryScanCommand()]
stdout: SplitParser { onRead: function(line) { hiddenEntryOutput.text += line + "\n" } }
onStarted: hiddenEntryOutput.text = ""
onExited: root.loadDesktopHiddenEntries(hiddenEntryOutput.text)
@@ -197,7 +201,7 @@ Item {
Process {
id: iconIndexScan
command: ["bash", "-lc", root.iconIndexScanCommand()]
command: ["bash", "-c", root.iconIndexScanCommand()]
stdout: SplitParser { onRead: function(line) { root.indexIconLine(line) } }
onStarted: root.pendingIconIndex = ({})
// Swapping the property re-evaluates every iconSource() binding, so
+7
View File
@@ -114,6 +114,13 @@ assert(
'app library fallback icon index includes device icons'
)
assert(
appLibraryQml.includes('command: ["bash", "-c", root.hiddenEntryScanCommand()]') &&
appLibraryQml.includes('command: ["bash", "-c", root.iconIndexScanCommand()]') &&
!appLibraryQml.includes('"-lc"'),
'app library scans avoid login shells whose profile activation retriggers the desktop-entry watcher'
)
assert(
/if \(active === "apps"\) \{[\s\S]*?rows\.sort\(function\(a, b\)/.test(menuQml),
'apps menu enforces alphabetical display order after provider refreshes'