From 5fb66cce464cb392351b591157261145ec00a603 Mon Sep 17 00:00:00 2001 From: kappaOne Date: Sun, 27 Oct 2013 15:07:07 +0000 Subject: [PATCH] Make the WM_CLASS implementation more flexible by giving users an option to set it manually by VM parameter or system property --- src/java/org/lwjgl/opengl/Display.java | 9 ++++++ src/java/org/lwjgl/opengl/LinuxDisplay.java | 29 +++++++++++++++++++ .../linux/opengl/org_lwjgl_opengl_Display.c | 13 ++++++--- .../linux/opengles/org_lwjgl_opengl_Display.c | 13 ++++++--- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/java/org/lwjgl/opengl/Display.java b/src/java/org/lwjgl/opengl/Display.java index d64acc27..25f54915 100644 --- a/src/java/org/lwjgl/opengl/Display.java +++ b/src/java/org/lwjgl/opengl/Display.java @@ -1048,6 +1048,15 @@ public final class Display { } }); } + + /** Gets a string property as a privileged action. */ + static String getPrivilegedString(final String property_name) { + return AccessController.doPrivileged(new PrivilegedAction() { + public String run() { + return System.getProperty(property_name); + } + }); + } private static void initControls() { // Automatically create mouse, keyboard and controller diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index cf005676..eb91e3b1 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -159,6 +159,8 @@ final class LinuxDisplay implements DisplayImplementation { private LinuxKeyboard keyboard; private LinuxMouse mouse; + + private String wm_class; private final FocusListener focus_listener = new FocusListener() { public void focusGained(FocusEvent e) { @@ -460,15 +462,18 @@ final class LinuxDisplay implements DisplayImplementation { ByteBuffer handle = peer_info.lockAndGetHandle(); try { current_window_mode = getWindowMode(Display.isFullscreen()); + // Try to enable Lecagy FullScreen Support in Compiz, else // we may have trouble with stuff overlapping our fullscreen window. if ( current_window_mode != WINDOWED ) Compiz.setLegacyFullscreenSupport(true); + // Setting _MOTIF_WM_HINTS in fullscreen mode is problematic for certain window // managers. We do not set MWM_HINTS_DECORATIONS in fullscreen mode anymore, // unless org.lwjgl.opengl.Window.undecorated_fs has been specified. // See native/linux/org_lwjgl_opengl_Display.c, createWindow function. boolean undecorated = Display.getPrivilegedBoolean("org.lwjgl.opengl.Window.undecorated") || (current_window_mode != WINDOWED && Display.getPrivilegedBoolean("org.lwjgl.opengl.Window.undecorated_fs")); + this.parent = parent; parent_window = parent != null ? getHandle(parent) : getRootWindow(getDisplay(), getDefaultScreen()); resizable = Display.isResizable(); @@ -477,7 +482,14 @@ final class LinuxDisplay implements DisplayImplementation { window_y = y; window_width = mode.getWidth(); window_height = mode.getHeight(); + current_window = nCreateWindow(getDisplay(), getDefaultScreen(), handle, mode, current_window_mode, x, y, undecorated, parent_window, resizable); + + // Set the WM_CLASS hint which is needed by some WM's e.g. Gnome Shell + wm_class = Display.getPrivilegedString("LWJGL_WM_CLASS"); + if (wm_class == null) wm_class = Display.getTitle(); + setClassHint(Display.getTitle(), wm_class); + mapRaised(getDisplay(), current_window); xembedded = parent != null && isAncestorXEmbedded(parent_window); blank_cursor = createBlankCursor(); @@ -761,8 +773,25 @@ final class LinuxDisplay implements DisplayImplementation { } finally { unlockAWT(); } + + // also update the class hint value as some WM's use it for the window title + if (Display.isCreated()) setClassHint(title, wm_class); } private static native void nSetTitle(long display, long window, long title, int len); + + /** the WM_CLASS hint is needed by some WM's e.g. gnome shell */ + private void setClassHint(String wm_name, String wm_class) { + lockAWT(); + try { + final ByteBuffer nameText = MemoryUtil.encodeUTF8(wm_name); + final ByteBuffer classText = MemoryUtil.encodeUTF8(wm_class); + + nSetClassHint(getDisplay(), getWindow(), MemoryUtil.getAddress(nameText), MemoryUtil.getAddress(classText)); + } finally { + unlockAWT(); + } + } + private static native void nSetClassHint(long display, long window, long wm_name, long wm_class); public boolean isCloseRequested() { boolean result = close_requested; diff --git a/src/native/linux/opengl/org_lwjgl_opengl_Display.c b/src/native/linux/opengl/org_lwjgl_opengl_Display.c index e1fc0e45..8622faec 100644 --- a/src/native/linux/opengl/org_lwjgl_opengl_Display.c +++ b/src/native/linux/opengl/org_lwjgl_opengl_Display.c @@ -187,11 +187,11 @@ static void setWindowTitle(Display *disp, Window window, jlong title, jint len) len); } -static void setClassHint(Display *disp, Window window, jlong title) { +static void setClassHint(Display *disp, Window window, jlong wm_name, jlong wm_class) { XClassHint* hint = XAllocClassHint(); - hint->res_name = (const unsigned char *)(intptr_t)title; - hint->res_class = (const unsigned char *)(intptr_t)title; + hint->res_name = (const unsigned char *)(intptr_t)wm_name; + hint->res_class = (const unsigned char *)(intptr_t)wm_class; XSetClassHint(disp, window, hint); @@ -224,7 +224,12 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetTitle(JNIEnv * env Display *disp = (Display *)(intptr_t)display; Window window = (Window)window_ptr; setWindowTitle(disp, window, title, len); - setClassHint(disp, window, title); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetClassHint(JNIEnv * env, jclass clazz, jlong display, jlong window_ptr, jlong wm_name, jlong wm_class) { + Display *disp = (Display *)(intptr_t)display; + Window window = (Window)window_ptr; + setClassHint(disp, window, wm_name, wm_class); } static void freeIconPixmap(Display *disp) { diff --git a/src/native/linux/opengles/org_lwjgl_opengl_Display.c b/src/native/linux/opengles/org_lwjgl_opengl_Display.c index 339e3770..8bd9db97 100644 --- a/src/native/linux/opengles/org_lwjgl_opengl_Display.c +++ b/src/native/linux/opengles/org_lwjgl_opengl_Display.c @@ -184,11 +184,11 @@ static void setWindowTitle(Display *disp, Window window, jlong title, jint len) len); } -static void setClassHint(Display *disp, Window window, jlong title) { +static void setClassHint(Display *disp, Window window, jlong wm_name, jlong wm_class) { XClassHint* hint = XAllocClassHint(); - hint->res_name = (const unsigned char *)(intptr_t)title; - hint->res_class = (const unsigned char *)(intptr_t)title; + hint->res_name = (const unsigned char *)(intptr_t)wm_name; + hint->res_class = (const unsigned char *)(intptr_t)wm_class; XSetClassHint(disp, window, hint); @@ -218,7 +218,12 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetTitle(JNIEnv * env Display *disp = (Display *)(intptr_t)display; Window window = (Window)window_ptr; setWindowTitle(disp, window, title, len); - setClassHint(disp, window, title); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetClassHint(JNIEnv * env, jclass clazz, jlong display, jlong window_ptr, jlong wm_name, jlong wm_class) { + Display *disp = (Display *)(intptr_t)display; + Window window = (Window)window_ptr; + setClassHint(disp, window, wm_name, wm_class); } static void freeIconPixmap(Display *disp) {