2009-04-10 35 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

回答