在Xlib/Xt中处理“新顶层窗口”事件

4
所以我处于这样一种情况,需要知道何时创建顶级窗口。我正在Xlib/Xt级别上工作,并且在不支持EWMH规范的窗口管理器上工作。我的想法是钩入根窗口的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, window, 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, window, &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, 0);
    XtRegisterDrawable (display, root_window, dummy);
    XSelectInput (display, root_window, SubstructureNotifyMask);
    XtAddRawEventHandler (dummy, SubstructureNotifyMask, False, handle_event, 0);

// ...
}

一个不太可能的想法,但有没有人有任何我可以尝试的想法?我真的想不出还能做什么了。

1
你正在使用哪个窗口管理器?为什么不实现EWMH? - Zifre
1个回答

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接