https://bugs.kde.org/show_bug.cgi?id=525807
Bug ID: 525807
Summary: Session restore never relaunches tray-icon-only
(StatusNotifierItem) applications
Classification: Plasma
Product: plasmashell
Version First 6.6.6
Reported In:
Platform: Other
OS: Linux
Status: REPORTED
Severity: normal
Priority: NOR
Component: Session Management
Assignee: [email protected]
Reporter: [email protected]
CC: [email protected]
Target Milestone: 1.0
# Session restore never relaunches tray-icon-only (StatusNotifierItem)
applications
## Product / Component
plasmashell — Session Restore (the `session-restore` save/restore tool in
`plasma-workspace`, authored in MR !3523 "Reopen running apps on startup").
## Summary
"Restore previous session" ("fake session restore", landed in Plasma 6.1)
never relaunches applications whose *only* UI is a system tray icon
(`org.kde.StatusNotifierItem` / `org.freedesktop.StatusNotifierItem`) with
no top-level window. This is not a timing race (unlike the superficially
similar bug 425315/385828, where apps *do* relaunch but their tray icon
fails to render due to a `StatusNotifierWatcher` startup race) — the
application process itself is never launched at all, because it was never
recorded as "running" in the first place.
## Root cause (verified against the actual source)
`session-restore/save.cpp` (from MR !3523) enumerates "running
applications" by iterating `TaskManager::WindowTasksModel`'s rows and
recording each row's `AppId`:
```cpp
// save.cpp, paraphrased from the actual MR:
// performs a Wayland roundtrip, then iterates tasksModel.rowCount(),
// reading AbstractTasksModel::AppId for each row, and persists that
// list to the session-restore state config.
```
`WindowTasksModel` is fundamentally a *window* enumeration model — it is
populated from Wayland toplevel surfaces (via KWin's window-management
protocols). An application that never creates a toplevel window during
normal operation — because its entire UI is a `StatusNotifierItem` tray
icon, shown/hidden windows on demand only (e.g. a settings dialog opened
by clicking the tray icon) — produces **zero rows** in this model. There
is no code path in `save.cpp` by which such an application could ever be
recorded, regardless of anything the application itself does.
`session-restore/restore.cpp` then reads back the saved `AppId` list,
resolves each one via `KService::serviceByMenuId(appId)`, and relaunches
it via `KIO::ApplicationLauncherJob` — but since tray-only apps were never
in the saved list to begin with, they are never reached by this code
either.
## Concrete real-world examples
Two independent, unrelated real-world applications reproduce this
consistently:
1. **[Safe Eyes](https://github.com/slgobinath/safeeyes)** (`safeeyes`,
v3.5.1) — a break-reminder utility. Its tray icon
(`safeeyes/plugins/trayicon/plugin.py`) is implemented as a
`StatusNotifierItemService` — a plain `DBusService` subclass that
registers itself with the `StatusNotifierWatcher` via
`watcher.RegisterStatusNotifierItem(...)`. There is no `Gtk.Window`
instantiated anywhere for the idle/tray state; a window only appears
transiently for the fullscreen break screen (triggered periodically)
or if the user manually opens Settings/About from the tray menu. At
session-save time (logout), if no break screen or settings dialog
happens to be open, SafeEyes has zero windows and is invisible to
`WindowTasksModel`.
2. **[Seafile client](https://github.com/haiwen/seafile-client)**
(`seafile-applet`) — a file-sync tray application. Its own config
(`~/.config/Seafile/Seafile Client.conf`) explicitly sets
`hideMainWindowWhenStarted=true`, meaning even its one actual window is
deliberately kept unmapped/hidden during normal operation, for exactly
the same "just a tray icon" use case.
## Steps to reproduce
1. In System Settings → Startup and Shutdown → Desktop Session, set "On
Login" → "Restore previous session".
2. Launch a tray-icon-only application (e.g. `safeeyes`, or
`seafile-applet` with "hide main window" enabled) alongside some
ordinary windowed applications (e.g. a browser, a terminal).
3. Log out, then log back in.
## Expected result
All applications that were running at logout, including the tray-only
ones, are relaunched.
## Actual result
Ordinary windowed applications (browser, terminal, etc.) are correctly
relaunched. The tray-icon-only applications are silently never relaunched
— no error, no log message, nothing for the user to act on. The only
symptom is "it's just not there after I log back in," which is very hard
for an end user (or the tray application's own developer, who has no
reason to suspect Plasma's window-based session enumeration) to diagnose
without reading `session-restore`'s source directly.
## Why this is worth fixing at the Plasma level rather than in each app
Tray-only background utilities are a common and legitimate application
category (sync clients, break reminders, indicator applets, etc.). There
is no session-management protocol such an application could implement to
opt in to today's window-based enumeration — the gap is structural to
`save.cpp` only looking at `WindowTasksModel`, not at registered
`StatusNotifierItem`s. A fix at the Plasma level (e.g. `save.cpp` also
querying `org.kde.StatusNotifierWatcher`'s
`RegisteredStatusNotifierItems` property, recording the owning process's
command/desktop file the same way autostart-phase code already resolves
PIDs to `.desktop` files) would transparently benefit every existing
tray-only application without requiring any of them to change a single
line of code.
## Suggested fix sketch
In `save.cpp`, in addition to enumerating `WindowTasksModel`, also query
`org.kde.StatusNotifierWatcher.RegisteredStatusNotifierItems` (a standard
property already used by every tray implementation), map each item's
D-Bus service name back to its owning PID
(`org.freedesktop.DBus.GetConnectionUnixProcessID`),
resolve that PID to a `.desktop` file the same way the rest of the
save/restore code already resolves `AppId`s, and add it to the saved list
if it is not already present via a window. `restore.cpp` needs no changes
at all — it already just relaunches whatever `AppId`s were saved.
## Environment
- KDE Plasma: 6.6.6 (Wayland session)
- Distro: Gentoo, OpenRC
- Confirmed via live testing: after enabling "Restore previous session"
and doing a real logout/login cycle, ordinary windowed apps (Chrome,
System Settings, Konsole) were correctly restored; `safeeyes` and
`seafile-applet` (both tray-only at the time of logout) were not,
consistent with the source-level analysis above.
--
You are receiving this mail because:
You are watching all bug changes.