I recently discovered that the X11 atom WM_NAME is not set in Swing JFrame when LANG is set to C.utf8
but is set for other values of LANG. This occurs on Linux Redhat 8.2 with OpenJDK 11.0.9.
Result with xprop | grep -i name
when LANG=C.utf8
_NET_WM_ICON_NAME(UTF8_STRING) = "title 123"
_NET_WM_NAME(UTF8_STRING) = "title 123"
Result with xprop | grep -i name
when LANG=en_GB.UTF-8
_NET_WM_ICON_NAME(UTF8_STRING) = "title 123"
WM_ICON_NAME(STRING) = "title 123"
_NET_WM_NAME(UTF8_STRING) = "title 123"
WM_NAME(STRING) = "title 123
Simple JFrame with title used
public class Example {
public static void main(String[] args) {
new javax.swing.JFrame("title 123").setVisible(true);
}
}
I've traced this through to sun.awt.X11.XBaseWindow.updateWMName() which updates both VM_NAME and _NET_WM_NAME unconditionally
XAtom nameAtom = XAtom.get(XAtom.XA_WM_NAME);
nameAtom.setProperty(getWindow(), name);
XAtom netNameAtom = XAtom.get("_NET_WM_NAME");
netNameAtom.setPropertyUTF8(getWindow(), name);
So I'm guessing that somewhere lower in X11 libraries the atom is either not being set or being rejected, possibly to do with character encoding.
I do understand that WM_NAME is legacy and optional and _NET_WM_NAME is the modern replacement. The reason this matters to me is that I maintain some legacy bespoke window manager style code that only looks for WM_NAME. I will be shortly enhancing this to look for _NET_WM_NAME too. I just want to understand this fully for my own academic geeky interest
CodePudding user response:
Tracing further sun.awt.X11.XAtom.setProperty(long, String)
calls out to native method sun.awt.X11.XlibWrapper.SetProperty(long, long, long, String)
This is implemented by https://github.com/openjdk/jdk/blob/master/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c
#ifdef X_HAVE_UTF8_STRING
status = Xutf8TextListToTextProperty((Display *)jlong_to_ptr(display), &cname, 1,
XStdICCTextStyle, &tp);
#else
status = XmbTextListToTextProperty((Display *)jlong_to_ptr(display), &cname, 1,
XStdICCTextStyle, &tp);
#endif
if (status == Success || status > 0) {
XChangeProperty((Display *)jlong_to_ptr(display), window, atom, tp.encoding, tp.format, PropModeReplace, tp.value, tp.nitems);
if (tp.value != NULL) {
XFree(tp.value);
}
}
This implies that if Xutf8TextListToTextProperty is unsuccessful then no error is reported.
Xutf8TextListToTextProperty is provided by Xutils.h which comes from https://gitlab.freedesktop.org/xorg/lib/libx11
It appears that libX11 has its own i18n implementation and until libX11 1.7.1 it did not "understand" LANG=C.utf8, although it did have an alias for C.UTF-8, this was corrected by commit https://github.com/mirror/libX11/commit/cc9f8878f2cbe17c7b4035b4ff4352b52ece38e0 which added an alias to /usr/share/X11/locale/locale.alias
C.utf8: en_US.UTF-8
The commit message answers the question concisely
The normal form is 'C.UTF-8', but 'C.utf8' has been seen in the wild.
If I manually change /usr/share/X11/locale/locale.alias and run my example with LANG=C.utf8 then WM_NAME and other atoms are set correctly.