Linux下如何通过C/C++/Xlib检测窗口拖至屏幕边缘的位置事件
检测Linux下窗口拖拽至屏幕边缘的事件(Xlib实现)
你的代码无法收到ConfigureNotify消息,核心原因是:ConfigureNotify事件默认发送给被调整/移动的窗口本身,而非根窗口。你之前监听根窗口的StructureNotifyMask,只能捕获根窗口自身的配置变化,无法感知其他客户端窗口的位置变更。
要实现需求,需要监听根窗口的SubstructureNotifyMask掩码——这个掩码会让根窗口接收所有子窗口(即系统中所有客户端窗口)的结构变更事件,包括窗口移动、调整大小的ConfigureNotify。
修改后的代码示例
#include <glib.h> #include <X11/Xlib.h> #include <X11/Xutil.h> int main(int argc, char **argv) { Display *dsp; Window wnd_root; Screen *screen; int screen_width, screen_height; dsp = XOpenDisplay(NULL); if (!dsp) { g_print("无法打开显示\n"); return 1; } wnd_root = XRootWindow(dsp, 0); screen = XDefaultScreenOfDisplay(dsp); screen_width = XWidthOfScreen(screen); screen_height = XHeightOfScreen(screen); // 监听根窗口的子窗口结构变更事件 XSelectInput(dsp, wnd_root, SubstructureNotifyMask); while (true) { XEvent evn; XNextEvent(dsp, &evn); switch (evn.type) { case ConfigureNotify: { XConfigureEvent *cfg_ev = &evn.xconfigure; // 检查窗口是否处于屏幕边缘(可根据需求调整判断条件) bool at_edge = false; if (cfg_ev->x == 0 || cfg_ev->y == 0) { at_edge = true; } if (cfg_ev->x + cfg_ev->width == screen_width || cfg_ev->y + cfg_ev->height == screen_height) { at_edge = true; } if (at_edge) { g_print("窗口 0x%lx 被拖拽至屏幕边缘!位置:(%d,%d) 大小:%dx%d\n", cfg_ev->window, cfg_ev->x, cfg_ev->y, cfg_ev->width, cfg_ev->height); } else { g_print("Configure Notify - 窗口 0x%lx 位置:(%d,%d) 大小:%dx%d\n", cfg_ev->window, cfg_ev->x, cfg_ev->y, cfg_ev->width, cfg_ev->height); } break; } default: break; } } XCloseDisplay(dsp); return 0; }
关键说明
SubstructureNotifyMask:让根窗口接收所有子窗口的结构变更事件,包括ConfigureNotify。- 边缘判断逻辑:示例中判断窗口是否贴靠左、上、右、下任意一边缘,你可以根据需求调整阈值(比如允许少量偏移)。
- 编译时需要链接X11和glib库:
gcc -o window_edge_detect window_edge_detect.cpkg-config --cflags --libs glib-2.0 x11``
内容的提问来源于stack exchange,提问作者Helg1980
相关产品推荐
相关产品推荐

