Linux desktop integration: Fill StartupWMClass in .desktop menu entries
hein at kde.org
Fri Apr 21 04:27:24 CDT 2017
I maintain the taskbar in Plasma 5 and would like to poke folks about a
desktop integration pain point we (and our friends at other DEs) face
with apps run via wine.
Here's the relevant ticket: https://bugs.winehq.org/show_bug.cgi?id=32699
Let me give some broader context on this. Modern DEs have a swath of UX
going on that relies on being able to identify the application owning a
particular window in the windowing system. "Identify the application" in
practice means "map the window to a .desktop file installed in the menu
file system". We want to do this because:
a) Many a taskbar/dock-like UI tries to form a smooth life cycle across
"launcher button", "startup notification" and "window button(s)". For
each of those we need to work out the app they are associated with to be
able to match them up. If it fails, ugly things like co-existing task
buttons or missing startup throbbers and similar happen.
b) UI these days tends to prefer to load assets such as app icons via
the values defined in .desktop files instead of using the window icon,
to ensure consistent results (apps may load icon assets differently from
the shell, leading to asset quality issues, inconsistent theming, the
icon changing between the lifecycle states mentioned in 'a', etc.) Plus
the Wayland windowing system we're all migrating towards currently
doesn'ㅅ have window icons.
c) DEs do things like track app starts/quits for things like "Most used
apps" launcher lists.
To match a window to a .desktop file we rely on window and process metadata.
On X11, there's the WM_CLASS window property:
Ideally, the second part of a X11 window's WM_CLASS matches the name of
a .desktop file installed on the system. Failing that, it matches the
value of StartupWMClass in that .desktop file (this is the key part I'll
get back to soon).
Here's some more documentation by our friends at Gnome on this standard
(Look for WM_CLASS / StartupWMClass.)
In practice, we pull many other tricks to cope with broken meta data. We
try to match things by names, we grab process command lines from /proc
and check them against Exec keys in .desktop files in complicated ways,
... it's a multi-page heuristic, and other DEs (Unity via bamf, Gnome
Shell via iirc ShellWindowTracker) have equivalent code. Something Gnome
does that we don't do (because I think it's brittle) is to store the
name of the .desktop file an app was launched with as a private window
hint on the next window that comes up (which then doesn't work when the
app was launched from CLI instead of shell UI).
None of these things currently allow us to handle wine very well. As of
now (perhaps thanks to the patch mentioned in the linked ticket), wine
sets WM_CLASS to the executable name of the app, e.g. "Notepad.exe". But
the .desktop files it generates don't match this by name, and they don't
contain a StartupWMClass key. The process command line is the
Windows-like path to the .exe, which we also can't easily match up to
the complicated Exec values in wine's .desktop files.
(Aside: On Wayland, there's a more modern version of this: Windows have
an appid property, which should be set to a .desktop file name. I don't
know what the status of Wayland support in wine is -- currently the wine
clients we encounter run over Xwayland, so we're back to WM_CLASS. We
hope wine will set this property correctly when the time comes, or we're
happy to work with you guys to find a way to support wine.)
Long story short ... could this be picked up? The goal must be to have
either .desktop file names or their StartupWMClass values match whatever
is set as WM_CLASS. Currently, the easiest fix would be to set
StartupWMClass to the executable name set as WM_CLASS. I assume the
.desktop file generator has access to this, as the .lnk file referred to
by Exec should presumably contain the name of the executable to be launched.
More information about the wine-devel