如何使用JNA(Java)为活动窗口获取X11 WM_类?

如何使用JNA(Java)为活动窗口获取X11 WM_类?,java,x11,jna,Java,X11,Jna,我使用以下代码获取Linux中的当前(焦点)窗口: X11 x11 = X11.INSTANCE; X11.Display display = x11.XOpenDisplay(null); X11.Window window = x11.XDefaultRootWindow(display); 现在我想得到这个窗口的WM_CLASS属性 下面一段介绍了如何做到这一点: 要读取窗口的WM_类属性,请使用XGetClassHint() XClassHint包含: 类型定义结构{ char*res

我使用以下代码获取Linux中的当前(焦点)窗口:

X11 x11 = X11.INSTANCE;
X11.Display display = x11.XOpenDisplay(null);
X11.Window window = x11.XDefaultRootWindow(display);
现在我想得到这个窗口的
WM_CLASS
属性

下面一段介绍了如何做到这一点:

要读取窗口的WM_类属性,请使用XGetClassHint()

XClassHint包含:

类型定义结构{

char*res_名称

char*res_类

}XClassHint

然而,当我们查看时,我们可以看到没有这样的属性
res\u class
(即
WM\u class


那么,如何获取当前窗口的
WM_CLASS
属性呢?

您可以从
jnacontrib
包中使用
X.window
类的
getWindowClass()
:它从提供的窗口读取
WC_CLASS
,并用点(
)替换空终止符(
\0
)。Javadoc:

以UTF8字符串形式返回属性值,其中每个“\0”字符都替换为“.”

x11x11=X11.INSTANCE;
X11.Display=X11.XOpenDisplay(null);
X11.Window Window=X11.XDefaultRootWindow(显示);
字符串wmClass=new X.Window(new X.Display(Display),Window.getWindowClass();

获取此值的另一种方法是手动读取(从contrib软件包中复制了一些零件):

静态类XClassHint{
公共最终字符串名称;
公共最终字符串重类;
公共XClassHint(最终字符串名称、最终字符串cls){
this.resName=名称;
this.resClass=cls;
}
@凌驾
公共字符串toString(){
返回字符串.format(“%s:%s”、this.resName、this.resClass);
}
}
私有静态XClassHint wmClass(X11 X11,X11.Display Display,X11.Window窗口)引发UnsupportedEncodingException{
最终X11.Atom xa_prop_type=X11.xa_字符串;
最终的X11.Atom xa_prop_name=X11.xa_WM_类;
最终整数最大值属性值长度=4096;
X11.AtomByReference xa_ret_type_ref=新的X11.AtomByReference();
IntByReference ret_format_ref=新IntByReference();
NativeLongByReference ret_nitems_ref=新的NativeLongByReference();
NativeLongByReference ret_bytes_after_ref=新的NativeLongByReference();
PointerByReference ret_prop_ref=新的PointerByReference();
NativeLong long_offset=新的NativeLong(0);
NativeLong长度=新NativeLong(最大属性值长度/4);
if(x11.XGetWindowProperty)(显示、窗口、xa_属性名称、长偏移量、长长度、假、,
xa_prop_type,xa_ret_type_ref,ret_format_ref,
ret\u nitems\u ref,ret\u bytes\u after\u ref,ret\u prop\u ref)!=X11.成功){
字符串prop_name=x11.XGetAtomName(显示,xa_prop_name);
抛出新的RuntimeException(“无法获取”+prop_name+“属性”);
}
X11.Atom xa_ret_type=xa_ret_type_ref.getValue();
指针ret_prop=ret_prop_ref.getValue();
if(xa_ret_type==null){
//指定窗口的指定属性不存在
返回null;
}
如果(xa_prop_type==null||
!xa_ret_type.toNative().equals(xa_prop_type.toNative()){
x11.XFree(ret_prop);
字符串prop_name=x11.XGetAtomName(显示,xa_prop_name);
抛出新的RuntimeException(“无效类型的“+prop_name+”属性”);
}
int ret_format=ret_format_ref.getValue();
long ret_nitems=ret_nitems_ref.getValue().longValue();
//null终止结果以使字符串处理更容易
整数字节;
if(ret_格式==32)
nbytes=本机长\u大小;
else if(ret_格式==16)
n字节=本机.LONG\u大小/2;
else if(ret_格式==8)
n字节=1;
else if(ret_格式==0)
n字节=0;
其他的
抛出新的RuntimeException(“返回格式无效”);
int length=Math.min((int)ret\u nitems*n字节,MAX\u PROPERTY\u VALUE\u LEN);
字节[]ret=ret_prop.getByteArray(0,长度);
x11.XFree(ret_prop);
if(ret==null){
返回null;
}
//搜索“\0”
int i;
对于(i=0;i