2009-04-10 74 views
4

所以我處於需要知道何時創建頂級窗口的情況。我正在Xlib/Xt級別和不支持EWMH規範的窗口管理器上工作。我的想法是鉤入根窗口的SubstructureNotify事件。但事情並非如此簡單。在Xlib/Xt中處理「新頂級窗口」事件

問題是,並非每個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 2009-04-10 01:01:46

回答