c – 在Xlib / Xt中处理“新顶级窗口”事件

因此,我需要知道何时创建顶级窗口.我正在Xlib / Xt级别以及不支持EWMH规范的Window Manager上工作.我的想法是挂钩根窗口的SubstructureNotify事件.但事情并不像那样简单.

问题是并非每个CreateNotify事件都对应于[b]顶级[/ b]窗口的创建.所以我认为我需要做的是测试我从事件中得到的窗口,以确认它是一个顶级窗口.我已经接近了,但是一些虚假的窗户仍然通过我的网络.例如,在GTK应用程序中,如果您有一个下拉框并单击它,则会创建一个新窗口,我无法弄清楚如何捕获和忽略.这样的窗口与典型的顶级应用程序窗口难以区分.

这是我到目前为止所拥有的:

// I am omiting (tons of) cleanup code and where I set the display and toplevel variables.

display* display;
Widget toplevel;

bool has_name(Window window)
{
    XTextProperty data = XTextProperty ();
    return (!XGetWMName (display,window,&data));
}

bool has_client_leader(Window window)
{
    unsigned long nitems = 0;
    unsigned char* data = 0;
    Atom actual_type;
    int actual_format;
    unsigned long bytes;
    // WM_CLIENT_leader is an interned Atom for the WM_CLIENT_leader property
    int status = XGetwindowProperty (display,WM_CLIENT_leader,0L,(~0L),False,AnyPropertyType,&actual_type,&actual_format,&nitems,&bytes,&data);
    if (status != Success || acutal_type == None) return false;
    Window* leader = reinterpret_cast<Window*> (data);
    return (*leader != 0);
}

bool has_class(Window window)
{
    XClassHint data = XClassHint ();
    return (!GetClassHint (display,&data));
}

void handle_event(Widget widget,XtPointer,XEvent* event,Boolean*)
{
    if (event->type != CreateNotify) return;

    Window w = event->xcreatewindow.window;

    // confirm window has a name
    if (!has_name (w)) return;

    // confirm window is a client window
    Window client = XmuClientwindow (display,w);
    if (!client || client != w) return;

    // confirm window has a client leader that is not 0x0
    if (!has_client_leader (client)) return;

    // confirm window has a class
    if (!has_class (client)) return;

    // The window has passed all our checks!
    // Go on to do stuff with the window ...
}

int main(int argc,char* argv[])
{
    // ...

    // Setting up the event handler for SubstructureNotify on root window
    Window root_window = XDefaultRootwindow (display);
    Widget dummy = XtCreateWidget ("dummy",coreWidgetClass,toplevel,0);
    XtRegisterDrawable (display,root_window,dummy);
    XSelectInput (display,SubstructureNotifyMask);
    XtAddRawEventHandler (dummy,SubstructureNotifyMask,handle_event,0);

// ...
}

很长一段时间,但有没有人有任何想法我可以尝试?我想不出我能在这里真正做到的其他事情.

解决方法

我假设你熟悉 ICCCM及其 long-winded discussion.

你检查过WM_TRANSIENT_FOR属性了吗?

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...