[Linux] Adding Taskbar Icons

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

[Linux] Adding Taskbar Icons

Post by chronologicaldot »

I managed to figure out how to get the icon to appear on my task bar instead of the ugly question mark icon. To do so, however, requires platform dependent code, but it doesn't interfere with anything else.

Here's how to do it.

In IrrlichtDevice.h, following setWindowCaption(), I added:

Code: Select all

 
        //! Sets the application class
        virtual void setApplicationClass(const char* className) {}
 
In CIrrDeviceLinux.h, following setWindowCaption(), you thus add:

Code: Select all

 
        //! Sets the application class
        virtual void setApplicationClass(const char* className) _IRR_OVERRIDE_;
 
And in CIrrDeviceLinux.cpp, following the CIrrDeviceLinux::setWindowCaption() method body, you add:

Code: Select all

 
//! Sets the application class
void CIrrDeviceLinux::setApplicationClass(const char* className)
{
#ifdef _IRR_COMPILE_WITH_X11_
    if (CreationParams.DriverType == video::EDT_NULL)
        return;
 
    XClassHint* hint = XAllocClassHint();
    hint->res_name = const_cast<char*>(className);
    hint->res_class = const_cast<char*>(className);
    XSetClassHint(XDisplay, XWindow, hint);
    XFree(hint);
#endif
}
 
Setting the Icon (User Guide)
I'm on Ubuntu, so you're experience may vary. In any case, you will need to know:
1.) The location of your application binaries (usually /usr/bin)
2.) The location of your application icons (there are various places)
3.) The location of your application launchers (usually /usr/share/applications)

You need to create:
1) A .desktop file.
2) An icon (even .png or .jpg will work since we're not on Windows, haha)

Creating a .desktop
A .desktop file is just a text file that looks something like this:

Code: Select all

 
[Desktop Entry]
Version=1.0
Name[en_US]=MyProgram
Comment=Description that shows up in my start menu
GenericName=MyProgram - Some text that shows up in other places
Exec=/usr/bin/MyProgram
Icon=MyProgram.png
MimeType=application/x-example
Terminal=false
Type=Application
StartupNotify=true
Categories=Utilities;3DGraphics;Education
StartupWMClass=MyProgramClass
 
At the top, you may need to add "#! gnome-launcher" or something like that, depending on the application launcher of your window manager, but I didn't need to.

When you create the .desktop file, you can do so by replacing the extension ".txt" with ".desktop", however, some file managers are stupid and decide to doubly append ".desktop" onto the name. Just rename the file without the ".desktop", and the file manager will append it's own. *sigh* Some things... Anyways...

Let's go over the important parts of the .desktop file:

Name - (followed by the language locale) This is for what your program is going to be named in your desktop startmenu, among other things.
Exec - The ABSOLUTE PATH of the executable. Relative paths are not accepted no matter where the .desktop file is located.
Icon - The name (NOT A PATH) of the icon for this application. The icon will be automatically searched for within system directories.
MimeType - This is the "type" value of the registered mimetype, and it allows your files to be associated with your application. More info can be found here: https://developer.gnome.org/integration ... me.html.en
It is recommended that you use "glob pattern" when created a mimetype because it's faster.
Terminal - If your application is itself a terminal OR your application execution is loaded with a terminal (such as: Exec=gnone-terminal myapp), then this will need to be set to true. Standalone Irrlicht apps don't need this.
Categories - This is where your application will be placed by default in your taskbar startmenu.
StartupWMClass THIS IS THE MOST IMPORTANT ONE FOR ADDING THE ICON. The name put here must be the same as the one you pass to IrrlichtDevice::setApplicationClass().

Installing
For this, you'll obviously need root privileges, so it's helpful to open your file manager with root access (if it gives you the convenient option of doing so, all the better!).

1.) Copy your .desktop file to your application launchers folder.
2.) Copy your binary to your application binaries folder.
3.) Copy your application icon into one of two places:
a) If you just have a single icon, try looking for the folder "pixmaps", which for me is under "/usr/share/pixmaps". This folder is for icons of basically any shape and size.
b) If you have various quality sizes, you will need to add the sizes you have to the appropriate folders under the icons folder, something like "/usr/share/icons". Such folders include:

/usr/share/icons/HighContrast/48x48/apps
/usr/share/icons/HighContrast/22x22/apps
/usr/share/icons/HighContrast/256x256/apps
/usr/share/icons/HighContrast/32x32/apps
/usr/share/icons/HighContrast/scalable/apps-extra
/usr/share/icons/HighContrast/24x24/apps
/usr/share/icons/HighContrast/16x16/apps
/usr/share/icons/hicolor/scalable/apps
/usr/share/icons/hicolor/128x128/apps
/usr/share/icons/hicolor/16x16/apps

But your system may vary.

I used pixmaps, so I can't guarantee the latter, but I do have applications with icons in a similar folder structure, so obviously, it worked for somebody.

I hope this helps somebody.

EDIT: Added memory freeing of the XClassHint.
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

Re: [Linux] Adding Taskbar Icons

Post by chronologicaldot »

I guess I was hinting at the fact that it'd be nice if setApplicationClass() were added to IrrlichtDevice, otherwise this post would be better suited under FAQs/Tutorials.
Anyone know how to set the icon for Windows?
CuteAlien
Admin
Posts: 9733
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: [Linux] Adding Taskbar Icons

Post by CuteAlien »

Didn't test yet, but it might be possible to have this in your application without changing Irrlicht. You can acces display and window from SExposedVideoData (IVideoDriver::getExposedVideoData).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

Re: [Linux] Adding Taskbar Icons

Post by chronologicaldot »

You're right. I figured it out. Posting this here for reference. I created a header and a cpp file to handle the job (since Xlib contains its own definition of Bool which tends to conflict with other libraries).
Header:

Code: Select all

 
#include <irrString.h>
#include <IVideoDriver.h>
 
void irrSetApplicationClass( irr::video::IVideoDriver*, irr::core::stringc appName, irr::core::stringc appClass );
 
Cpp:

Code: Select all

 
#include "irrSetAppClass.h"
#include <SExposedVideoData.h> // For application class setting (for icon loading)
 
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif
 
void irrSetApplicationClass(
    irr::video::IVideoDriver* videoDriver,
    irr::core::stringc appName,
    irr::core::stringc appClass
) {
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_) && defined(_IRR_COMPILE_WITH_OPENGL_)
    if ( videoDriver->getDriverType() == irr::video::EDT_NULL )
        return;
 
    const irr::video::SExposedVideoData&  x11VideoData = videoDriver->getExposedVideoData();
    XClassHint* hint = XAllocClassHint();
    hint->res_name = const_cast<char*>(appName.c_str());
    hint->res_class = const_cast<char*>(appClass.c_str());
    XSetClassHint(
        (Display*)x11VideoData.OpenGLLinux.X11Display,
        (Window)x11VideoData.OpenGLLinux.X11Window,
        hint);
    XFree(hint);
#endif
}
 
Also, I noticed setWindowCaption() also sets the application icon, but it doesn't allow you to set it separately from the app name / window caption. It just assumes the two are the same, which is fine if you're creating a game but not so convenient for applications.
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

Re: [Linux] Adding Taskbar Icons

Post by chronologicaldot »

Turns out, my above code is giving me a problem of "BadWindow" for X11. It doesn't crash the application, but it doesn't work as expected either. The only difference between the two approaches I've taken is the accessing of the X11Display and X11Window: the first way, directly in the video driver, worked, but the second way, indirectly through SExposedVideoData, did not. I'm using OpenGL, so that's not the problem. *shrug*
Has this worked for anyone else?
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

Re: [Linux] Adding Taskbar Icons

Post by chronologicaldot »

Correction, the first way was in the device, as I said above.

The XWindow in CIrrLinuxDevice doesn't get changed it seems, but the one in ContextManager for CGLXContextManager gets changed to GlxWin on line 290 of the cpp file. I tried various workarounds to save the XWindow of the device in the context manager but to no avail. Still getting BadWindow.
netpipe
Posts: 670
Joined: Fri Jun 06, 2008 12:50 pm
Location: Edmonton, Alberta, Canada
Contact:

Re: [Linux] Adding Taskbar Icons

Post by netpipe »

would be neat to have a nice demo app framework for windows and linux tray applet too
Live long and phosphor!
-- https://github.com/netpipe/Luna Game Engine Status 95%
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

Re: [Linux] Adding Taskbar Icons

Post by chronologicaldot »

Just an update: The void irrSetApplicationClass() function using SExposedVideoData now works!!
Thanks CuteAlien for informing me the bug got fixed in revision 6370.
Post Reply