簡體   English   中英

處理Xlib / Xt中的“新頂級窗口”事件

[英]Handle “new top level window” events in 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, 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);

// ...
}

遠射,但是有人有我可以嘗試的想法嗎? 我想不出我在這里能做的很多事情。

我認為您熟悉ICCCM及其冗長的討論

您是否檢查了WM_TRANSIENT_FOR屬性?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM