From e195854e00a726bf5b381e801752b8af47725050 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 20 Nov 2017 20:20:48 +0530 Subject: [PATCH] Support for setting WM_CLASS on a per-window basis --- include/GLFW/glfw3.h | 7 ++++++- src/x11_window.c | 29 ++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index a3f986407..67c2d495b 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -2343,7 +2343,12 @@ GLFWAPI void glfwWindowHint(int hint, int value); * @remark @x11 The name and class of the `WM_CLASS` window property will by * default be set to the window title passed to this function. Set the @ref * GLFW_X11_WM_CLASS_NAME and @ref GLFW_X11_WM_CLASS_CLASS init hints before - * initialization to override this. + * initialization to override this. You can also set the title int he following + * special format, which allows setting the two parts of the WM_CLASS property + * and the window title independently: + * <01> WM_CLASS name <30> WM_CLASS class <30> title + * Here <01> refers to the byte value 01 (ASCII start-of-header) and <30> refers + * to the byte value 30 (ASCII record separator). * * @remark @wayland The window frame is currently unimplemented, as if * [GLFW_DECORATED](@ref GLFW_DECORATED_hint) was always set to `GLFW_FALSE`. diff --git a/src/x11_window.c b/src/x11_window.c index 32fff63b6..0cc49d744 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -703,9 +703,11 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, updateNormalHints(window, wndconfig->width, wndconfig->height); - // Set ICCCM WM_CLASS property + // Set ICCCM WM_CLASS property and window title { XClassHint* hint = XAllocClassHint(); + char *wm_cclass = NULL, *wm_cname = NULL; + const char *real_title = wndconfig->title; if (strlen(_glfw.hints.init.x11.className) && strlen(_glfw.hints.init.x11.classClass)) @@ -713,10 +715,26 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, hint->res_name = (char*) _glfw.hints.init.x11.className; hint->res_class = (char*) _glfw.hints.init.x11.classClass; } - else if (strlen(wndconfig->title)) + else if (strlen(real_title)) { - hint->res_name = (char*) wndconfig->title; - hint->res_class = (char*) wndconfig->title; + if (*real_title == 1) { + char *p = strchr(real_title, 30); + if (p && p > real_title + 1) { + wm_cname = calloc(p - real_title + 1, 1); + if (wm_cname) memcpy(wm_cname, real_title + 1, p - real_title - 1); + hint->res_name = wm_cname; + char *q = strchr(p + 1, 30); + if (q && q > p + 1) { + wm_cclass = calloc(q - p + 1, 1); + if (wm_cclass) memcpy(wm_cclass, p + 1, q - p - 1); + hint->res_class = wm_cclass; + real_title = q + 1; + } + } + } else { + hint->res_name = (char*) real_title; + hint->res_class = (char*) real_title; + } } else { @@ -726,6 +744,8 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, XSetClassHint(_glfw.x11.display, window->x11.handle, hint); XFree(hint); + free(wm_cclass); free(wm_cname); + _glfwPlatformSetWindowTitle(window, real_title); } // Announce support for Xdnd (drag and drop) @@ -736,7 +756,6 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, PropModeReplace, (unsigned char*) &version, 1); } - _glfwPlatformSetWindowTitle(window, wndconfig->title); if (_glfw.x11.im) {