Set Multiple values for StartupWMClass (to group under same launcher in Unity)
This a specific example of a generic problem I haven't been able to find a solution for yet.
I have a program (Android Virtual Device Manager) that launches 'sub-programs' (namely emulators or virtual devices) from within itself (also can be launched from else where). I want any instances of EITHER of these programs to be grouped under the same Unity icon.
I have created a .desktop
file to try and accomplish this but don't exactly know how to go about it. The desktop file is as follows:
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Name=Android Virtual Device
Icon=/home/ben/.icons/android.svg
Exec=/home/ben/usr/bin/android avd
StartupWMClass=Android Virtual Device Manager
From what I understand, StartupWMClass
is what I need to set to achieve this correctly. I have obtained the two class names ('Android Virtual Device Manager' and 'emulator64-arm') using xprop WM_CLASS
on the repsective windows. Both work individually (the launcher icon is correctly attached to the program no matter what way it is launched), but I cannot get it to work for both.
I am assuming that I somehow need to set two values for StartupWMClass
but have not been able to do it correctly (or know if it is a valid operation). I have tried, colon separated like environment variables, comma separated, quotes, etc and I cannot find any hints in the official documentation.
Any suggestions?
EDIT:
Another, more pedantic, but probably more identifiable example is with Matlab
. I am running 2013a and the splash screen that initially shows and the program have completely different WM_CLASS
values. This means, when I click my launcher with StartupWMClass=com-mathworks-util-PostVMInit
in it, the splash screen comes up with a different (default Unknown) Unity
icon, while the rest comes up grouped under my launcher.
By using xprop WMCLASS
and clicking on first the splash screen, then repeating with an active Matlab
session I get the following terminal output:
ben@ben-OptiPlex-9010:~$ xprop WM_CLASS
WM_CLASS(STRING) = "MATLAB", "MATLAB"
ben@ben-OptiPlex-9010:~$ xprop WM_CLASS
WM_CLASS(STRING) = "sun-awt-X11-XFramePeer", "com-mathworks-util-PostVMInit"
If I could specify something along the lines of:
StartupWMClass=com-mathworks-util-PostVMInit&&MATLAB
That would work perfectly (as both work separately) but I have no idea of the syntax, if it even exists. I just know nothing I have tried has worked thus far.
Any help or a definitive answer either way would be great as I believe this is a pretty fundamental element of a well functioning desktop.
Solution 1:
Same problem for me with Starcraft II launched throw playonlinux. There is first a application launcher:
(WM_CLASS(STRING) = "Blizzard Launcher.exe", "Wine")
and then the game itself:(WM_CLASS(STRING) = "SC2.exe", "Wine")
I guess that wine is setting the class with the binary executable.
I had a look in bamf code (bamf_matcher.c, insert_desktop_file_class_into_table() method):
- There is a map that make the association between a desktop file and one and only one class,
- The key StartupWMClass is read with g_key_file_get_string() which is not designed to return a list of strings,
- g_key_file_get_string_list() could do that but bamf developpers did not design the framework to be able to associate multiple classes to one single desktop file.
In my case I cheat by creating 2 desktop files with same keys but StartupWMClass. This is not perfect because I still have 2 Uniy icons when in the launcher but the important thing is I know why :-).
Solution 2:
I know this question is really old, but after going through the same problem, i think i've finally created a workaround for this, and decided to share with anyone having this issue:
As we can't set multiple WMClasses for a single .desktop file, why don't set all the windows to a single WMClass?
We can do something like this (Obviously, replace Window 1
, Window 2
and potatoes
with your windows names and desired WMClass):
xprop -name "Window 1" -f WM_CLASS 8s -set WM_CLASS "potatoes"
xprop -name "Window 2" -f WM_CLASS 8s -set WM_CLASS "potatoes"
And on the .desktop file we can do this: StartupWMClass=potatoes
Tadam! All windows are grouped now.
But hey, are we doing this manually every time the program opens up? Of course not.
We can just go and make a bash script that automagically does that every half second:
while true
do
xprop -name "Window 1" -f WM_CLASS 8s -set WM_CLASS "potatoes"
xprop -name "Window 2" -f WM_CLASS 8s -set WM_CLASS "potatoes"
sleep 0.5
done
And finally, set the .sh we created to run every time the OS starts up:
Hope my answer is helpful to anyone browsing this question.