LWJGL / lwjgl

[LEGACY] LWJGL 2.X - The Lightweight Java Game Library.
http://legacy.lwjgl.org/
548 stars 207 forks source link

Add a method to set the WM_CLASS hint on an X11 window on Linux #51

Closed s-zeid closed 11 years ago

s-zeid commented 11 years ago

Some Linux desktop environments (e.g. GNOME Shell) use the X11 window class (set using the WM_CLASS hint) to determine the application's name and provide certain functionality based on that. In the case of GNOME Shell specifically, allowing the user to dock an application to the Dash and showing the correct name in Alt-Tab. (See also this.)

I would suggest adding a setWmClass() method to org.lwjgl.opengl.Display, and possibly setting WM_CLASS to be the same as the window title by default. The setWmClass method would be a stub on non-Linux platforms.

md-5 commented 11 years ago

+1

md-5 commented 11 years ago

Is this an acceptable solution?

    public static void setAppName(final String appName)
    {
        final Toolkit toolkit = Toolkit.getDefaultToolkit();
        final Class<?> cls = toolkit.getClass();

        try
        {
            // When X11 toolkit is used then set the awtAppClassName field
            if (cls.getName().equals("sun.awt.X11.XToolkit"))
            {
                final Field field = cls.getDeclaredField("awtAppClassName");
                field.setAccessible(true);
                field.set(toolkit, appName);
            }
        }
        catch (final Exception e)
        {
            // If this fails for whatever reason then we silently ignore it 
            // because a running game is more important than a correct 
            // application name
        }
    }
md-5 commented 11 years ago

Above solution doesn't work :(

kappaOne commented 11 years ago

This has been added, not sure its a good idea to add a public API to LWJGL's Display class just for setting the WM_CLASS hint as its not useful to anyone running Windows or OS X and even on Linux its only used by a few Window Managers. Therefore I've set it for now to use the same value as Display Title 'Display.setTitle(String)', hope that should be enough. Thanks for the pull request though.

Anyway do give the next nightly builds from http://ci.newdawnsoftware.com/job/LWJGL-git-dist/ a go to confirm whether it works for you.

Thanks

md-5 commented 11 years ago

Nice, much appreciated

s-zeid commented 11 years ago

Well this is a start, but it won't really work for my particular use case, Minecraft: Minecraft runs with the window title set to "Minecraft [version number]", but my launcher .desktop file is set to just "Minecraft". The GNOME Shell desktop environment will match up windows to their .desktop files based on their window class, and you can set which window class to look for in the .desktop file, but having to update the .desktop file every single time Minecraft releases an update isn't really acceptable. I mean, I can make a client modification that sets the window title to something else, and I could even make a script to automate that process, but most people are not going to want (or even know) to do that, which is why I said that the setWmClass() method I suggested could be a stub on platforms that do not support such a thing. Also, the Minecraft Launcher lets you run multiple versions of the game, and so I would have to repeat this work for each version.

Now, of course, I don't work for Mojang, so they would have to actually add a call to setWmClass(), but I can open an issue for it on their bug tracker if it gets implemented here.

s-zeid commented 11 years ago

The nightly build does, however, succeed in setting the window class to the title.

md-5 commented 11 years ago

lol I actually opened this for Minecraft too. I don't believe the current fix is even correct, per my comments.

kappaOne commented 11 years ago

Thanks for the feedback ppl, can see why it might be problematic if the title changes every version.

I've had a think about the problem and implemented a solution that hopefully should fix the issue without needing to add platform specific API to LWJGL's crossplatform public API's.

By default if no WM_CLASS parameter is set then the title value 'Display.getTitle()' on Display window creation will be used.

You can now however set the WM_CLASS property manually by either:

1) Setting the System.setProperty() key, LWJGL_WM_CLASS in the java code e.g. System.setProperty("LWJGL_WM_CLASS", "Minecraft");

2) Specifying the LWJGL_WM_CLASS value as a Java VM parameter e.g. java -DLWJGL_WM_CLASS="Minecraft" ....

The above changes should be available in the next nightly build of LWJGL. Do let me know if it works or if there are any further issues.

Thanks

kappaOne

s-zeid commented 11 years ago

This sounds great; however, the name of the property key looked a bit weird being all caps. According to this wiki page, most of the existing LWJGL property keys use the format org.lwjgl.package.ClassName.somethingInCamelCase, so I kind of think the property name should be org.lwjgl.opengl.Display.wmClass. As I said, though, I do like the solution other than that.

kappaOne commented 11 years ago

Yeh compared to the listed hidden switches on that wiki page it does look different, however there are a lot more hidden switches inside LWJGL such as "LWJGL_DISABLE_XRANDR", "LWJGL_DISABLE_NETWM", etc.

With LWJGL_SET_WM_CLASS I was just following this latter style, seemed easier to remember and type on the command line than the longer package.class.method style names, however don't really mind which it uses, if ppl prefer the longer version its fine by me and can be changed.

s-zeid commented 11 years ago

Ah, that makes more sense, and yeah, it does seem easier to type. Now that you mention this, I don't really mind either way. Actually, I only saw 2 all-caps hidden switches—the ones you mentioned—when combing through the source just now, and they're Linux-specific, so it makes sense to keep that convention here.

Also, should I expect to see this in 2.9.1 or in another release?

Thank you for doing this.

kappaOne commented 11 years ago

Yup will be part of the next LWJGL release (very likely 2.9.1), which hopefully will follow shortly (think only an issue relating to the java sandbox/appletloader remains outstanding before that'll happen).

In any event, if you need it now, the above patch is available in the nightly builds of LWJGL at http://ci.newdawnsoftware.com/job/LWJGL-git-dist/