如何使用JNA(Java)为活动窗口获取X11 WM_类?
我使用以下代码获取Linux中的当前(焦点)窗口:如何使用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
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
您是否尝试过字符串wc=new X.Window(new X.Display(Display),Window).getWindowClass()代码>来自jnacontrib
?它从当前窗口读取WM_CLASS
属性。结果字符串应该包含两个字符串,X.Display
类将\0
字符替换为点(
)是的,它确实尝试了。它很好用。但是,我想知道如何不用该代码手动完成。AFAIK使用了一些已经由JNA实现的函数,比如您提到的字符串转换。谢谢。但是,有没有办法不使用这个类?@当然,您可以创建一个类来反映WM\u class
struct并手动读取属性(请参阅更新)