如何使用X11/Xlib C API获取活动窗口及相关参数疑问
获取Linux(Ubuntu)下的活动窗口:焦点窗口 vs EWMH属性
焦点窗口与活动窗口的区别
XGetInputFocus获取的焦点窗口是当前接收键盘输入的窗口,但它不一定等于视觉上的「活动窗口」——比如某些后台窗口可劫持焦点,或窗口切换瞬间会出现短暂不一致。- Ubuntu的GNOME/KDE等桌面环境遵循EWMH标准,根窗口上的
_NET_ACTIVE_WINDOW属性指向的才是用户视觉上的活动窗口(标题栏高亮的窗口),这是更可靠的获取方式。
使用XGetWindowProperty读取_NET_ACTIVE_WINDOW的参数说明
先上可运行的代码片段,再逐个解释关键参数:
#include <X11/Xlib.h> #include <X11/Xatom.h> #include <stdio.h> int main() { Display *display = XOpenDisplay(NULL); if (!display) { fprintf(stderr, "无法打开显示\n"); return 1; } Window root = DefaultRootWindow(display); Atom net_active_window = XInternAtom(display, "_NET_ACTIVE_WINDOW", False); Atom actual_type; int actual_format; unsigned long nitems, bytes_after; unsigned char *data = NULL; // 读取_NET_ACTIVE_WINDOW属性 int status = XGetWindowProperty( display, // 已打开的Display指针 root, // 属性所在的窗口(根窗口) net_active_window, // 要读取的属性原子 0L, // long_offset:从属性数据的第0个long位置开始读 1L, // long_length:最多读1个long单位(窗口ID占1个long) False, // delete:False表示只读取,不删除属性 XA_WINDOW, // req_type:指定我们期望的属性类型是窗口ID &actual_type, // 输出:实际读取到的属性类型 &actual_format, // 输出:实际数据的格式(32或64位) &nitems, // 输出:读取到的数据项数量 &bytes_after, // 输出:未读取完的剩余字节数 &data // 输出:存储属性数据的缓冲区(需用XFree释放) ); if (status == Success && data && nitems == 1 && actual_type == XA_WINDOW) { Window active_win = *(Window*)data; printf("当前活动窗口ID:%lu\n", (unsigned long)active_win); XFree(data); } else { fprintf(stderr, "读取活动窗口失败\n"); } XCloseDisplay(display); return 0; }
关键参数详解
long_offset:设为0L即可,因为_NET_ACTIVE_WINDOW仅存储单个窗口ID,从数据起始位置读取就够。long_length:设为1L,窗口ID在Xlib中对应一个long类型数值,读取1个单位就能完整获取目标值。delete:必须设为False,这个参数用于删除窗口属性,我们仅做读取操作,删除会破坏桌面环境对活动窗口的正常维护。req_type:指定为XA_WINDOW,这是Xlib预定义的窗口类型原子,确保返回的数据是合法的窗口ID格式;若实际属性类型与该值不匹配,说明读取异常。
编译时需链接X11库:gcc -o get_active_win get_active_win.c -lX11
内容的提问来源于stack exchange,提问作者T.L
相关产品推荐
相关产品推荐

