Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ “处理”;“新顶层窗口”;Xlib/Xt中的事件_C++_Xlib_Xt - Fatal编程技术网

C++ “处理”;“新顶层窗口”;Xlib/Xt中的事件

C++ “处理”;“新顶层窗口”;Xlib/Xt中的事件,c++,xlib,xt,C++,Xlib,Xt,因此,我需要知道何时创建顶级窗口。我在Xlib/Xt级别上工作,在一个不支持EWMH规范的窗口管理器上工作。我的想法是钩住根窗口的子结构Notify事件。但事情并非如此简单 问题在于并非每个CreateNotify事件都对应于[b]顶级[/b]窗口的创建。所以我想我需要做的是测试我从事件中得到的窗口,以确认它是一个顶级窗口。我已经很接近了,但仍然有一些假窗口通过我的网。例如,在GTK应用程序中,如果您有一个下拉框并单击它,就会创建一个新窗口,我不知道如何捕获和忽略它。这样的窗口很难与典型的顶级应

因此,我需要知道何时创建顶级窗口。我在Xlib/Xt级别上工作,在一个不支持EWMH规范的窗口管理器上工作。我的想法是钩住根窗口的子结构Notify事件。但事情并非如此简单

问题在于并非每个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);

// ...
}
//我省略了(大量)清理代码以及设置display和toplevel变量的位置。
显示*显示;
小部件顶层;
bool有\u名称(窗口)
{
XTextProperty数据=XTextProperty();
返回(!XGetWMName(显示、窗口和数据));
}
bool有客户机领导(窗口)
{
无符号长nitems=0;
无符号字符*数据=0;
原子型;
int实际_格式;
无符号长字节;
//WM_CLIENT_LEADER是WM_CLIENT_LEADER属性的内部原子
int status=XGetWindowProperty(显示、窗口、WM_客户机_领导人、0L、(~0L)、False、,
AnyPropertyType、&actual_类型、&actual_格式、&nitems、&bytes、&data);
if(status!=Success | | acutal_type==None)返回false;
窗口*引线=重新解释投影(数据);
返回(*引线!=0);
}
bool有_类(窗口窗口)
{
XClassHint data=XClassHint();
返回(!GetClassHint(显示、窗口和数据));
}
void handle_事件(小部件小部件、XtPointer、XEvent*事件、布尔值*)
{
如果(事件->类型!=CreateNotify)返回;
窗口w=事件->xcreatewindow.Window;
//确认窗口有一个名称
如果(!has_name(w))返回;
//确认窗口是一个客户端窗口
窗口客户端=XmuClientWindow(显示,w);
如果(!client | | client!=w)返回;
//确认窗口有一个不是0x0的客户端引线
如果(!有客户领导(客户))返回;
//确认窗口有一个类
如果(!有_类(客户端))返回;
//窗户已经通过了我们所有的检查!
//继续用窗户做些事情。。。
}
int main(int argc,char*argv[])
{
// ...
//为根窗口上的子结构Notify设置事件处理程序
窗口根\u窗口=XDefaultRootWindow(显示);
Widget dummy=XtCreateWidget(“dummy”,coreWidgetClass,顶级,0,0);
XtRegisterDrawable(显示,根窗口,虚拟);
XSelectInput(显示、根窗口、子结构NotifyMask);
XtAddRawEventHandler(伪,子结构NotifyMask,False,句柄\事件,0);
// ...
}

很难,但有人有什么想法我可以试试吗?我想不出我还能在这里做什么了。

我想你对它和它很熟悉


您是否检查了
WM\u TRANSIENT\u的
属性?

您正在使用什么窗口管理器?为什么不实施EWMH?