It seems to me that one of the reasonable paths towards utopia that has merit is humanity leaning strongly towards open-source "free" information technology. That also goes for just information, but that's another story.
After seeing how Veritasium layed out the XZ attack, I got to thinking. I remember the week when CVE-2024-3094 got out, this top of the scale 10/10 CRITICAL. I was shocked how there was no shock in the news.
If this happens in open source, we should expect it happens in closed source, and a lot more of it, viruses and dark stuff loves the .. dark, closed, places.
There are so many steps between committing code and actually getting through testing, rcs, alphas, betas, etc, this is the perfect example of why open source works, because everyone who cares, does care, and some tests will pick up unexpected changes.
Imagine if there was even more incentive for these open-source people to make good code, they (we) care. A lot.
On the other hand, in the closed industry, this may (and) happen all the time, continuously, we just don't know, because we can't know. 🤷 Until of course, 5 or 10 years, after something crazy happens.
I have a small bash script that opens one of my dev environments; Dolphin on my project assets, Unity Hub, VS Code, and a Konsole in the project directory. It works, but two things always annoyed me:
The script lingers in System Monitor as a phantom process doing nothing, with no visible window.
Dolphin opens as "dolphin" (lowercase, no icon) instead of "Dolphin" with its proper icon, like it would from the KDE start menu. I wondered why.
Time for some Claude Code. Fixing this turned out to be a deep dive into how KDE Plasma actually launches applications.
Simple enough. kstart is a KDE utility for launching windowed apps. But it's a holdover from Plasma 5 that doesn't integrate with the way Plasma 6 tracks applications.
This fixed the Dolphin icon issue (the app now sets its own _KDE_NET_WM_DESKTOP_FILE window property), but the apps vanished entirely from System Monitor's Applications tab. The script itself still lingered.
The problem: KDE System Monitor's "Applications" view doesn't use window properties. It uses systemd cgroups.
How KDE tracks applications
When you launch an app from KDE's start menu or KRunner, the launcher doesn't just fork a process. It creates a systemd scope; a named cgroup container; following a specific naming convention:
KDE System Monitor (specifically libksysguard) parses these scope names with a regex to extract the desktop file ID, then looks up the .desktop file to get the app name and icon. No scope, no entry in the Applications tab.
This seemed right, but systemd-run --scope acts as the scope lifecycle manager; it blocks, keeping the scope alive as long as the app runs. Only Dolphin would open; the script would hang on line 1 waiting for Dolphin to exit. Running the script a second time would open the remaining three apps (because Dolphin, a single-instance app, would return immediately).
Worse: when I killed the lingering script from System Monitor, it took Unity Hub down with it; because killing the systemd-run process tears down the scope.
After attempt 2: apps show correctly, but the script still lingers and is entangled with the app processes.
The solution: D-Bus scope creation
Looking at how KDE's own launcher works (in KIO::ScopedProcessRunner), the actual mechanism is:
Start the process normally (fork)
Call systemd's StartTransientUnit over D-Bus to create a scope
Pass the PID to move it into the new scope
The scope is created by systemd and persists independently; no lifecycle manager needed. We can do the same from bash with busctl:
Calls StartTransientUnit via D-Bus, creating a scope named app-<desktop-id>-<pid>.scope and moving the process into it
Disowns the process from the shell
Each app now lives in its own cgroup scope. The script's cgroup becomes empty when it exits, so it vanishes from System Monitor. All apps show up with proper names and icons.
After the fix: all apps appear correctly in KDE System Monitor, and the script is gone.
A nice side effect: re-running the script doesn't re-open single-instance apps (like Dolphin), while Konsole opens a new window each time; which is exactly the behaviour I wanted.
Verifying against KDE source
To make sure this approach is stable and won't need migrating, I checked the actual KDE source code.
KIO's ScopedProcessRunner (scopedprocessrunner.cpp) does the same thing: fork the process, then call StartTransientUnit with the PIDs property. KDE uses a UUID for the scope suffix instead of PID, and sets three additional properties:
Property
Value
Purpose
PIDs
Process ID
Move process into scope
Slice
app.slice
Proper cgroup hierarchy
Description
App name
Human-readable in systemctl
SourcePath
Path to .desktop file
Fallback for desktop file lookup
libksysguard's cgroup.cpp parses the scope name with this regex:
It extracts the desktop file ID from between app- and -<suffix>.scope, then calls KService::serviceByMenuId() to find the .desktop file. This is why the naming convention matters; use the desktop file's stem (e.g., org.kde.dolphin) as the ID.
Interesting note: on systemd ≥ 250, KDE internally prefers launching apps as transient services (where systemd itself forks the process). But scopes remain the correct mechanism for external launchers that start the process themselves; exactly our case. This is standardized in the systemd XDG desktop specification and isn't going anywhere.
Why is this so hard?
KDE has a clean C++ API for this; KIO::ApplicationLauncherJob is essentially a one-liner that handles scope creation, desktop file lookup, and process management. But no CLI tool exposes it properly:
kioclient exec launches .desktop files but doesn't accept app arguments (no --workdir, no directory to open)
kstart is a Plasma 5 holdover that doesn't create scopes
systemd-run --scope blocks as a lifecycle manager
gtk-launch doesn't create KDE-style scopes
There's a missing CLI tool in the KDE ecosystem; something like klaunch org.kde.dolphin /some/path that does what the start menu does. Until that exists, the busctl + StartTransientUnit approach is the way to go.