我最近发现,当LANG设置为C.utf8
时,Swing JFrame中没有设置X11原子WM_NAME,而是设置了LANG的其他值。这发生在Linux Redhat 8.2和OpenJDK 11.0.9上。
LANG= c.t utf8时xprop | grep -i name
的结果
_NET_WM_ICON_NAME(UTF8_STRING) = "title 123"
_NET_WM_NAME(UTF8_STRING) = "title 123"
LANG=en_GB时xprop | grep -i name
的结果。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
带有标题的简单JFrame
public class Example {
public static void main(String[] args) {
new javax.swing.JFrame("title 123").setVisible(true);
}
}
我一直追踪到sun.awt.X11.XBaseWindow.updateWMName(),它无条件地更新VM_NAME和_NET_WM_NAME
XAtom nameAtom = XAtom.get(XAtom.XA_WM_NAME);
nameAtom.setProperty(getWindow(), name);
XAtom netNameAtom = XAtom.get("_NET_WM_NAME");
netNameAtom.setPropertyUTF8(getWindow(), name);
所以我猜在X11库中较低的某个地方,原子要么没有被设置,要么被拒绝,可能与字符编码有关。
我确实理解WM_NAME是遗留的和可选的,而_NET_WM_NAME是现代的替代品。这对我来说很重要的原因是,我维护一些遗留的定制窗口管理器风格的代码,这些代码只查找WM_NAME。我将很快对其进行增强,以查找_NET_WM_NAME。我只是想充分了解这一点,因为我自己的学术兴趣
进一步跟踪sun.awt.X11.XAtom.setProperty(long, String)
对本地方法sun.awt.X11.XlibWrapper.SetProperty(long, long, long, String)
的调用
这是通过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);
}
}
这意味着如果Xutf8TextListToTextProperty不成功,则不会报告错误。
Xutf8TextListToTextProperty是由Xutils.h提供的,它来自https://gitlab.freedesktop.org/xorg/lib/libx11
libX11似乎有自己的i18n实现,直到libX11 1.7.1才"理解";LANG = C。虽然它确实有c.t utf -8的别名,但通过commit https://github.com/mirror/libX11/commit/cc9f8878f2cbe17c7b4035b4ff4352b52ece38e0纠正了这一点,它在/usr/share/x11/locale/locale.alias
中添加了别名C.utf8: en_US.UTF-8
提交消息简洁地回答了这个问题
正常形式为'C.UTF-8',但'C.utf8'在野外也见过。
如果我手动更改/usr/share/X11/locale/locale.别名并使用LANG=C运行我的示例。如果WM_NAME和其他原子被正确设置,