为什么在某些语言环境下WM_NAME原子未被设置

4

我最近发现,在设置LANG为 C.utf8 时,Swing JFrame中的X11原子WM_NAME没有设置,但在其他值的LANG时设置了。这发生在Linux Redhat 8.2上,使用OpenJDK 11.0.9。

在LANG=C.utf8时的 xprop | grep -i name 结果:

_NET_WM_ICON_NAME(UTF8_STRING) = "title 123"
_NET_WM_NAME(UTF8_STRING) = "title 123"

当LANG=en_GB.UTF-8时,使用xprop | grep -i name所得到的结果:

_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。我只是想充分理解这个问题,以满足我的学术兴趣。

1个回答

1

追踪更多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有自己的国际化实现,直到libX11 1.7.1之前,它并不“理解”LANG=C.utf8,尽管它有C.UTF-8的别名,但这已经通过提交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.alias并使用LANG=C.utf8运行我的示例,则WM_NAME和其他原子将被正确设置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接