Add a command line switch to set the name part of WM_CLASS independently
This commit is contained in:
parent
02884c5045
commit
32a6dd2aa1
@ -36,6 +36,9 @@ version 0.5.1 [2017-12-01]
|
||||
|
||||
- Add an option to control the audio bell volume on X11 systems
|
||||
|
||||
- Add a command line switch to set the name part of the WM_CLASS window
|
||||
property independently.
|
||||
|
||||
|
||||
version 0.5.0 [2017-11-19]
|
||||
---------------------------
|
||||
|
||||
7
glfw/glfw3.h
vendored
7
glfw/glfw3.h
vendored
@ -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`.
|
||||
|
||||
29
glfw/x11_window.c
vendored
29
glfw/x11_window.c
vendored
@ -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)
|
||||
{
|
||||
|
||||
@ -19,8 +19,9 @@ from .keys import get_key_map, get_shortcut
|
||||
from .session import create_session
|
||||
from .tabs import SpecialWindow, TabManager
|
||||
from .utils import (
|
||||
end_startup_notification, get_primary_selection, init_startup_notification,
|
||||
open_url, safe_print, set_primary_selection, single_instance
|
||||
encode_wm_class, end_startup_notification, get_primary_selection,
|
||||
init_startup_notification, open_url, safe_print, set_primary_selection,
|
||||
single_instance
|
||||
)
|
||||
|
||||
|
||||
@ -78,10 +79,10 @@ class Boss:
|
||||
startup_session = create_session(opts, args)
|
||||
self.add_os_window(startup_session, os_window_id=os_window_id)
|
||||
|
||||
def add_os_window(self, startup_session, os_window_id=None, wclass=None, size=None, visible=True):
|
||||
def add_os_window(self, startup_session, os_window_id=None, wclass=None, wname=None, size=None, visible=True):
|
||||
if os_window_id is None:
|
||||
w, h = initial_window_size(self.opts) if size is None else size
|
||||
os_window_id = create_os_window(w, h, wclass or self.args.cls, visible)
|
||||
os_window_id = create_os_window(w, h, encode_wm_class(wname or self.args.name, wclass or self.args.cls), visible)
|
||||
tm = TabManager(os_window_id, self.opts, self.args, startup_session)
|
||||
self.os_window_map[os_window_id] = tm
|
||||
return os_window_id
|
||||
@ -103,7 +104,7 @@ class Boss:
|
||||
args = option_parser().parse_args(msg['args'][1:])
|
||||
opts = create_opts(args)
|
||||
session = create_session(opts, args)
|
||||
os_window_id = self.add_os_window(session, wclass=args.cls, size=initial_window_size(opts))
|
||||
os_window_id = self.add_os_window(session, wclass=args.cls, wname=args.name, size=initial_window_size(opts))
|
||||
if startup_id:
|
||||
ctx = init_startup_notification(os_window_id, startup_id)
|
||||
end_startup_notification(ctx)
|
||||
|
||||
@ -20,7 +20,13 @@ def option_parser():
|
||||
'--class',
|
||||
default=appname,
|
||||
dest='cls',
|
||||
help=_('Set the WM_CLASS property')
|
||||
help=_('Set the class part of the WM_CLASS property')
|
||||
)
|
||||
a(
|
||||
'--name',
|
||||
default=None,
|
||||
dest='name',
|
||||
help=_('Set the name part of the WM_CLASS property (defaults to using the value from {})').format('--class')
|
||||
)
|
||||
a(
|
||||
'--config',
|
||||
|
||||
10
kitty/glfw.c
10
kitty/glfw.c
@ -402,15 +402,6 @@ glfw_window_hint(PyObject UNUSED *self, PyObject *args) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject*
|
||||
glfw_init_hint_string(PyObject UNUSED *self, PyObject *args) {
|
||||
int hint_id;
|
||||
char *hint;
|
||||
if (!PyArg_ParseTuple(args, "is", &hint_id, &hint)) return NULL;
|
||||
glfwInitHintString(hint_id, hint);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
// }}}
|
||||
|
||||
@ -694,7 +685,6 @@ static PyMethodDef module_methods[] = {
|
||||
{"glfw_post_empty_event", (PyCFunction)glfw_post_empty_event, METH_NOARGS, ""},
|
||||
{"glfw_get_physical_dpi", (PyCFunction)glfw_get_physical_dpi, METH_NOARGS, ""},
|
||||
{"glfw_get_key_name", (PyCFunction)glfw_get_key_name, METH_VARARGS, ""},
|
||||
{"glfw_init_hint_string", (PyCFunction)glfw_init_hint_string, METH_VARARGS, ""},
|
||||
{"glfw_primary_monitor_size", (PyCFunction)primary_monitor_size, METH_NOARGS, ""},
|
||||
{"glfw_primary_monitor_content_scale", (PyCFunction)primary_monitor_content_scale, METH_NOARGS, ""},
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
|
||||
@ -14,13 +14,13 @@ from .cli import create_opts, option_parser
|
||||
from .config import initial_window_size, load_cached_values, save_cached_values
|
||||
from .constants import isosx, iswayland, logo_data_file
|
||||
from .fast_data_types import (
|
||||
change_wcwidth, create_os_window, glfw_init, glfw_init_hint_string,
|
||||
glfw_terminate, install_sigchld_handler, set_default_window_icon,
|
||||
set_logical_dpi, set_options, GLFW_X11_WM_CLASS_NAME, GLFW_X11_WM_CLASS_CLASS
|
||||
change_wcwidth, create_os_window, glfw_init, glfw_terminate,
|
||||
install_sigchld_handler, set_default_window_icon, set_logical_dpi,
|
||||
set_options
|
||||
)
|
||||
from .fonts.box_drawing import set_scale
|
||||
from .utils import (
|
||||
detach, end_startup_notification, get_logical_dpi,
|
||||
detach, encode_wm_class, end_startup_notification, get_logical_dpi,
|
||||
init_startup_notification, single_instance
|
||||
)
|
||||
from .window import load_shader_programs
|
||||
@ -45,7 +45,7 @@ def run_app(opts, args):
|
||||
set_options(opts, iswayland, args.debug_gl)
|
||||
load_cached_values()
|
||||
w, h = initial_window_size(opts)
|
||||
window_id = create_os_window(w, h, args.cls, True, load_all_shaders)
|
||||
window_id = create_os_window(w, h, encode_wm_class(args.name, args.cls), True, load_all_shaders)
|
||||
startup_ctx = init_startup_notification(window_id)
|
||||
if not iswayland and not isosx: # no window icons on wayland
|
||||
with open(logo_data_file, 'rb') as f:
|
||||
@ -137,10 +137,7 @@ def main():
|
||||
return
|
||||
opts = create_opts(args)
|
||||
change_wcwidth(not opts.use_system_wcwidth)
|
||||
glfw_module = init_graphics()
|
||||
if glfw_module == 'x11':
|
||||
glfw_init_hint_string(GLFW_X11_WM_CLASS_CLASS, args.cls)
|
||||
glfw_init_hint_string(GLFW_X11_WM_CLASS_NAME, args.cls)
|
||||
init_graphics()
|
||||
try:
|
||||
with setup_profiling(args):
|
||||
# Avoid needing to launch threads to reap zombies
|
||||
|
||||
@ -291,3 +291,9 @@ def single_instance(group_id=None):
|
||||
s.set_inheritable(False)
|
||||
atexit.register(remove_socket_file, s)
|
||||
return True
|
||||
|
||||
|
||||
def encode_wm_class(name, cls, title=appname):
|
||||
if isosx:
|
||||
return title
|
||||
return '\x01' + (name or cls) + '\x1e' + cls + '\x1e' + title
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user