济南网站自然优化创可贴在线设计网站
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:49
当前位置: 首页 > news >正文
济南网站自然优化,创可贴在线设计网站,西安seo招聘,自己注册一个网站要多少钱在 Linux X11 下枚举窗口并获取窗口信息
在 Linux 系统中#xff0c;X11 是一个非常流行的窗口系统#xff0c;它提供了丰富的 API 用于管理和操作窗口。在这篇博客中#xff0c;我们将详细介绍如何使用 X11 枚举当前系统中的窗口#xff0c;并获取它们的标题、截图、进程…在 Linux X11 下枚举窗口并获取窗口信息
在 Linux 系统中X11 是一个非常流行的窗口系统它提供了丰富的 API 用于管理和操作窗口。在这篇博客中我们将详细介绍如何使用 X11 枚举当前系统中的窗口并获取它们的标题、截图、进程路径、进程图标等信息。
环境准备
首先我们需要安装一些必要的库和工具
sudo apt-get install libx11-dev libxcomposite-dev libxext-dev枚举窗口
我们将使用 X11 提供的 XQueryTree 函数来枚举当前系统中的所有窗口。以下是一个简单的示例代码
#include X11/Xlib.h
#include X11/Xatom.h
#include vector
#include string
#include iostreamstruct WindowInfo {::Window window;std::string title;std::string process_path;std::vectoruint8_t icon_data;int icon_width;int icon_height;
};std::vectorWindowInfo enum_windows(Display *display) {std::vectorWindowInfo windows;::Window root DefaultRootWindow(display);::Window parent;::Window *children;unsigned int num_children;if (XQueryTree(display, root, root, parent, children, num_children)) {for (unsigned int i 0; i num_children; i) {WindowInfo info;info.window children[i];// 获取窗口标题XTextProperty window_name;if (XGetWMName(display, children[i], window_name) window_name.value) {info.title (char *)window_name.value;XFree(window_name.value);}// 获取进程路径Atom pid_atom XInternAtom(display, _NET_WM_PID, True);if (pid_atom ! None) {Atom actual_type;int actual_format;unsigned long nitems, bytes_after;unsigned char *prop nullptr;if (XGetWindowProperty(display, children[i], pid_atom, 0, 1, False, XA_CARDINAL,actual_type, actual_format, nitems, bytes_after, prop) Success nitems 0) {pid_t pid *(pid_t *)prop;XFree(prop);char path[1024];snprintf(path, sizeof(path), /proc/%d/exe, pid);char exe_path[1024];ssize_t len readlink(path, exe_path, sizeof(exe_path) - 1);if (len ! -1) {exe_path[len] \0;info.process_path exe_path;}}}// 获取窗口图标Atom icon_atom XInternAtom(display, _NET_WM_ICON, True);if (icon_atom ! None) {Atom actual_type;int actual_format;unsigned long nitems, bytes_after;unsigned char *prop nullptr;if (XGetWindowProperty(display, children[i], icon_atom, 0, (~0L), False, AnyPropertyType,actual_type, actual_format, nitems, bytes_after, prop) Success nitems 0) {unsigned long *data (unsigned long *)prop;info.icon_width data[0];info.icon_height data[1];info.icon_data.assign((uint8_t *)(data 2), (uint8_t *)(data 2 info.icon_width * info.icon_height));XFree(prop);}}windows.push_back(info);}XFree(children);}return windows;
}int main() {Display *display XOpenDisplay(NULL);if (!display) {std::cerr Failed to open display std::endl;return -1;}std::vectorWindowInfo windows enum_windows(display);for (const auto window : windows) {std::cout Window ID: window.window std::endl;std::cout Title: window.title std::endl;std::cout Process Path: window.process_path std::endl;std::cout Icon Size: window.icon_width x window.icon_height std::endl;std::cout std::endl;}XCloseDisplay(display);return 0;
}获取窗口截图
为了获取窗口的截图我们可以使用 XGetImage 函数。以下是一个示例代码
#include X11/Xlib.h
#include X11/Xutil.h
#include vector
#include iostream
#include fstreamvoid save_ximage_to_ppm(const char *filename, XImage *image) {std::ofstream ofs(filename, std::ios::binary);ofs P6\n image-width image-height \n255\n;for (int y 0; y image-height; y) {for (int x 0; x image-width; x) {unsigned long pixel XGetPixel(image, x, y);unsigned char r (pixel image-red_mask) 16;unsigned char g (pixel image-green_mask) 8;unsigned char b (pixel image-blue_mask);ofs.put®.put(g).put(b);}}
}void capture_window(Display *display, ::Window window, const char *filename) {XWindowAttributes attributes;XGetWindowAttributes(display, window, attributes);XImage *image XGetImage(display, window, 0, 0, attributes.width, attributes.height, AllPlanes, ZPixmap);if (image) {save_ximage_to_ppm(filename, image);XDestroyImage(image);}
}int main() {Display *display XOpenDisplay(NULL);if (!display) {std::cerr Failed to open display std::endl;return -1;}::Window root DefaultRootWindow(display);capture_window(display, root, screenshot.ppm);XCloseDisplay(display);return 0;
}结合所有功能
我们可以将上述功能结合起来创建一个完整的程序来枚举窗口并获取它们的标题、截图、进程路径、进程图标等信息。
#include X11/Xlib.h
#include X11/Xatom.h
#include X11/Xutil.h
#include vector
#include string
#include iostream
#include fstreamstruct WindowInfo {::Window window;std::string title;std::string process_path;std::vectoruint8_t icon_data;int icon_width;int icon_height;
};void save_ximage_to_ppm(const char *filename, XImage *image) {std::ofstream ofs(filename, std::ios::binary);ofs P6\n image-width image-height \n255\n;for (int y 0; y image-height; y) {for (int x 0; x image-width; x) {unsigned long pixel XGetPixel(image, x, y);unsigned char r (pixel image-red_mask) 16;unsigned char g (pixel image-green_mask) 8;unsigned char b (pixel image-blue_mask);ofs.put®.put(g).put(b);}}
}void capture_window(Display *display, ::Window window, const char *filename) {XWindowAttributes attributes;XGetWindowAttributes(display, window, attributes);XImage *image XGetImage(display, window, 0, 0, attributes.width, attributes.height, AllPlanes, ZPixmap);if (image) {save_ximage_to_ppm(filename, image);XDestroyImage(image);}
}std::vectorWindowInfo enum_windows(Display *display) {std::vectorWindowInfo windows;::Window root DefaultRootWindow(display);::Window parent;::Window *children;unsigned int num_children;if (XQueryTree(display, root, root, parent, children, num_children)) {for (unsigned int i 0; i num_children; i) {WindowInfo info;info.window children[i];// 获取窗口标题XTextProperty window_name;if (XGetWMName(display, children[i], window_name) window_name.value) {info.title (char *)window_name.value;XFree(window_name.value);}// 获取进程路径Atom pid_atom XInternAtom(display, _NET_WM_PID, True);if (pid_atom ! None) {Atom actual_type;int actual_format;unsigned long nitems, bytes_after;unsigned char *prop nullptr;if (XGetWindowProperty(display, children[i], pid_atom, 0, 1, False, XA_CARDINAL,actual_type, actual_format, nitems, bytes_after, prop) Success nitems 0) {pid_t pid *(pid_t *)prop;XFree(prop);char path[1024];snprintf(path, sizeof(path), /proc/%d/exe, pid);char exe_path[1024];ssize_t len readlink(path, exe_path, sizeof(exe_path) - 1);if (len ! -1) {exe_path[len] \0;info.process_path exe_path;}}}// 获取窗口图标Atom icon_atom XInternAtom(display, _NET_WM_ICON, True);if (icon_atom ! None) {Atom actual_type;int actual_format;unsigned long nitems, bytes_after;unsigned char *prop nullptr;if (XGetWindowProperty(display, children[i], icon_atom, 0, (~0L), False, AnyPropertyType,actual_type, actual_format, nitems, bytes_after, prop) Success nitems 0) {unsigned long *data (unsigned long *)prop;info.icon_width data[0];info.icon_height data[1];info.icon_data.assign((uint8_t *)(data 2), (uint8_t *)(data 2 info.icon_width * info.icon_height));XFree(prop);}}windows.push_back(info);}XFree(children);}return windows;
}int main() {Display *display XOpenDisplay(NULL);if (!display) {std::cerr Failed to open display std::endl;return -1;}std::vectorWindowInfo windows enum_windows(display);for (const auto window : windows) {std::cout Window ID: window.window std::endl;std::cout Title: window.title std::endl;std::cout Process Path: window.process_path std::endl;std::cout Icon Size: window.icon_width x window.icon_height std::endl;// 保存窗口截图std::string screenshotfilename screenshot std::to_string(window.window) .ppm;capture_window(display, window.window, screenshot_filename.c_str());std::cout Screenshot saved to: screenshot_filename std::endl;std::cout std::endl;}XCloseDisplay(display);return 0;
}需要注意获取ICON数据时候的特殊处理
在 get_window_icon 函数中对于不同架构32位和64位的实现有所不同这是因为在不同架构下数据的存储方式和处理方式有所不同。以下是对该函数中不同架构实现的原因和方法的详细解释。
原因 数据存储方式不同 在32位架构下unsigned long 类型的大小是32位4字节。在64位架构下unsigned long 类型的大小是64位8字节但实际数据只使用了低32位高32位是填充的。 数据处理方式不同 在32位架构下可以直接复制整个内存块因为数据是连续存储的。在64位架构下需要逐个元素处理因为每个元素是64位的但实际数据只使用了低32位。
方法
32位架构实现
在32位架构下直接复制整个内存块因为数据是连续存储的且每个元素的大小是32位。
#if defined(TRAA_ARCH_32_BITS)icon_data.assign(prop 2 * sizeof(unsigned long), prop nitems * sizeof(unsigned long));
#endif这里使用 std::vector::assign 方法将图标数据从 prop 中复制到 icon_data 向量中。prop 2 * sizeof(unsigned long) 跳过了前两个元素宽度和高度prop nitems * sizeof(unsigned long) 表示复制整个内存块。
64位架构实现
在64位架构下需要逐个元素处理因为每个元素是64位的但实际数据只使用了低32位。
#elif defined(TRAA_ARCH_64_BITS)// TODO: this can be optimized by using some SIMD instructions.icon_data.resize(width * height * desktop_frame::bytes_per_pixel);for (int y 0; y height; y) {for (int x 0; x width; x) {unsigned long pixel data[2 y * width x];icon_data(y * width x) * desktop_frame::bytes_per_pixel 3 0xff; // Bicon_data(y * width x) * desktop_frame::bytes_per_pixel 2 0xff; // Gicon_data(y * width x) * desktop_frame::bytes_per_pixel 1 0xff; // Ricon_data[(y * width x) * desktop_frame::bytes_per_pixel 0] pixel 0xff; // A}}
#endif这里逐个像素处理将每个像素的ARGB值提取出来并存储到 icon_data 向量中。具体步骤如下 调整 icon_data 的大小 icon_data.resize(width * height * desktop_frame::bytes_per_pixel);调整 icon_data 的大小以容纳所有像素数据。 逐个像素处理 for (int y 0; y height; y) {for (int x 0; x width; x) {unsigned long pixel data[2 y * width x];icon_data(y * width x) * desktop_frame::bytes_per_pixel 3 0xff; // Bicon_data(y * width x) * desktop_frame::bytes_per_pixel 2 0xff; // Gicon_data(y * width x) * desktop_frame::bytes_per_pixel 1 0xff; // Ricon_data[(y * width x) * desktop_frame::bytes_per_pixel 0] pixel 0xff; // A}
}逐个像素处理将每个像素的ARGB值提取出来并存储到 icon_data 向量中。
总结
在 get_window_icon 函数中对于不同架构的不同实现是为了适应32位和64位架构下数据存储和处理方式的不同。在32位架构下可以直接复制整个内存块而在64位架构下需要逐个元素处理以确保数据的正确性。
PS
Copilot生成的博客还算有点乱和抓不住重点细节…感兴趣的去看源码吧还是细节都在代码里了.
源码传送
traa
- 上一篇: 济南网站制作技术交流免费引流微信推广
- 下一篇: 济南网站自然优化王也道长微信头像
相关文章
-
济南网站制作技术交流免费引流微信推广
济南网站制作技术交流免费引流微信推广
- 技术栈
- 2026年03月21日
-
济南网站制作公司哪家好seo静态页源码
济南网站制作公司哪家好seo静态页源码
- 技术栈
- 2026年03月21日
-
济南网站制作服务成都建设公司网站
济南网站制作服务成都建设公司网站
- 技术栈
- 2026年03月21日
-
济南网站自然优化王也道长微信头像
济南网站自然优化王也道长微信头像
- 技术栈
- 2026年03月21日
-
济南响应式网站建设国内比较好的vi设计公司
济南响应式网站建设国内比较好的vi设计公司
- 技术栈
- 2026年03月21日
-
济南小型网站建设适合穷人的18个创业项目投资小
济南小型网站建设适合穷人的18个创业项目投资小
- 技术栈
- 2026年03月21日
