Wednesday, June 19, 2013

Creating Shortcuts With Different Icons for Multiple rdesktop Connections

We use rdesktop to run those few programs that we can't run on Linux on a Windows Remote Desktop Server. I like to make launchers for these, so they seem more like real applications for users. Unfortunately, when you have several rdesktop (or Wine, Java, etc.) applications, and assign an icon to them, it will choose only one icon to display in the launcher in Unity/Ubuntu. This is how you fix that.

First, we need to create an icon. It just needs to be a 48x48 pixel .png file. Do that however you feel comfortable, and save it to /usr/share/icons. Make sure it has the correct permissions:

sudo chmod 644 /usr/share/icons/internetexplorer.png

Now, lets create a launcher for each separate application. Create the launcher in /usr/bin. Mine looks something like this:

All that jazz for the $MONITORSIZE just uses xrandr to automatically figure out the dimensions of the monitor, so rdesktop will start in Windowed full screen. It works with multiple monitors too! If you were doing this for a Wine, Java, etc. program, you wouldn't need any of that. Also, replace the rdesktop line with whatever you would actually need. The juicy part of what we need is right below that, the xdotool stuff. Speaking of which, you should probably install that, it isn't installed by default:

sudo apt-get install xdotool

Unity figures out which icon to display based on a few things. Normally, it will just call an application, and it will know to keep the icon for that application. Since we are using a launcher, it will just display a question mark, instead of whatever icon we choose. This is because it doesn't know about the program we called, just the one that IT called. Now, to get around this, you can specify that the program called will not be the program to keep the icon for. You can also tell it the window class name so all windows with that class name will share an icon. Unfortunately, the class names are generic, and we really want to specify the icon based on the window name, or title (which we are specifying with the -t option when calling rdesktop from our script). That's what we are doing with xdotool. We first search for the window we want, based on title, then we set it's class to something unique and remove the window from the window manager, wait and add it back to the window manager. The reason for removing and then re-adding it is so that Unity will see the new window with our custom window class, and give it the correct icon. You may have to adjust the sleep there. It is needed otherwise the window gets redrawn too quickly, and loses the window decorations (i.e. resize, maximize, title, etc.).

Okay, you still following me? Now, all we have to do is create our .desktop file. This is very easy. You can do this with a simple GUI by using this command:

sudo gnome-desktop-item-edit /usr/share/applications --create-new

But that presupposes you havegnome-desktop-item-edit installed, and it is really easy to do it manually. Create a .desktop file in /usr/share/applications like this:

[Desktop Entry]Name=Internet ExplorerComment=Remote desktop version of Internet Explorer for sites that do not support other browsers/OSes.Exec=/usr/bin/internetexplorerIcon=/usr/share/icons/internetexplorer.pngTerminal=falseType=ApplicationCategories=Internet;

That all is fairly well documented, and if you only have one application that needs the custom icon, you can just add StartupNotify=True to the end of that.

Again, let's make sure we got the right permissions:

sudo chmod 644 /usr/share/applications/internetexplorer.desktop

That's it. If you were following along, you should now be able to repeat the process for your next program, and enjoy being able to open both of them with different icons.