I’m so glad I found out how to fix this, because it’s an issue that just kept popping up every now and then.
The issue is this: for some applications, especially (but not necessarily) after upgrades, Unity somehow decides to spawn a new icon every time the app is launched. Thus, you end up with two identical (or in the case of upgrades, very similar) versions of the icon in the Unity launchbar, with the additional annoyance of having one work as a window switcher, and the other working as a new launcher.
Here’s how to fix that.
1. Locate your application’s .desktop file
In Ubuntu this is either inside ~/.local/share/applications or inside /usr/share/applications.
One problem you may have is that you have more than one .desktop file for the same application. If that is the case, remove one (probably the older one).
The .desktop files don’t necessarily match the application name that’s shown when you hover on the launcher (wonderful design idea, duh), so you might need to use grep to find the file.
For example, to find my PyCharm launcher, I had to execute
ls ~/.local/share/applications | grep -i charm
which returned jetbrains-pycharm.desktop, the file that I was looking for.
Removing duplicate .desktop files might be enough to solve the issue, so try launching your app to see if that fixed it. Otherwise, read on.
2. Find your application’s WM_CLASS
This was the core of the issue in my case. To match a window to an application, Unity looks for the window’s WM_CLASS.
To find what your application’s WM_CLASS is, launch your app and run this in a terminal (using a small window for the terminal, leaving your app visible in the background, you’ll see why in a moment):
your mouse cursor will turn into a crosshair, and you must click anywhere on your application’s window. You will find something like this in your terminal:
WM_CLASS(STRING) = "sun-awt-X11-XFramePeer", "jetbrains-pycharm-ce"
(this is the output for PyCharm Community Edition). Your WM_CLASS is the most specific string in the list (use your intuition, in this case jetbrains-pycharm-ce is obviously about PyCharm, whereas the other seems to be related to all Java apps in general).
3. Set your application’s WM_CLASS in the .desktop file
Open your .desktop file from Step 1 with a text editor, and either add (if it’s not there already) this line to the bottom, or replace its previous value with the WM_CLASS string from Step 2:
replacing jetbrains-pycharm-ce with your WM_CLASS, of course.
That’s it! Close all your application windows, and relaunch your app. This time, after you launch the app, you should only have one icon