While debugging a port of the classic xwininfo command from the libX11 to libxcb
API's, I noted that the class info shown for some java windows contained bogus
extra characters on the end.
For instance, while the Xlib version of xwinfo showed:
0x5400010 "FocusProxy": ("Focus-Proxy-Window" "FocusProxy") 1x1+-1+-1 +1313+1
the xcb version showed:
0x5400010 "FocusProxy": ("Focus-Proxy-Window" "FocusProxyFra1") 1x1+-1+-1 +1313+1
Digging into this, I discovered that Xlib was hiding a bug in Java. Xlib always
adds a trailing '\0' byte to property strings, while xcb does not. This exposes
that Java is not including the trailing '\0' when setting the WM_CLASS string - from
XBaseWindow.java:
void setWMClass(String[] cl) {
if (cl.length != 2) {
throw new IllegalArgumentException("WM_CLASS_NAME consists of exactly two strings");
}
XToolkit.awtLock();
try {
XAtom xa = XAtom.get(XAtom.XA_WM_CLASS);
xa.setProperty8(getWindow(), cl[0] + '\0' + cl[1]);
} finally {
XToolkit.awtUnlock();
}
}
But the ICCCM specifies that unlike most window properties, which are not null
terminated, the WM_CLASS is a special case that must be null terminated:
Note that WM_CLASS strings are null-terminated and, thus, differ from the
general conventions that STRING properties are null-separated.
This inconsistency is necessary for backwards compatibility.
(BTW, the error message for the IllegalArgumentException seems to have an extra
"_NAME" on the end of the property name.)