You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.c pkg-config --cflags --libs glib-2.0 x11``

内容的提问来源于stack exchange,提问作者Helg1980

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 02:40:32