C++ X11窗口上的移动窗口事件

C++ X11窗口上的移动窗口事件,c++,x11,C++,X11,我目前有2个X11窗口,我想保持同步。其中一个覆盖透明图形,而另一个显示视频。我目前有一个覆盖图形的窗口,它总是位于视频的顶部,但我很难确保移动时两个窗口位于相同的位置。我正在X11文档中查找窗口移动事件,但似乎找不到 此外,在我的事件句柄循环中,我尝试获取一个窗口的位置,并将另一个窗口移动到该位置。无论何时调用XGetWindowAttributes,此操作都失败。即使窗口被移动,它也始终返回x=0和y=0 Window win; int nxvisuals = 0; XVisualInf

我目前有2个X11窗口,我想保持同步。其中一个覆盖透明图形,而另一个显示视频。我目前有一个覆盖图形的窗口,它总是位于视频的顶部,但我很难确保移动时两个窗口位于相同的位置。我正在X11文档中查找窗口移动事件,但似乎找不到

此外,在我的事件句柄循环中,我尝试获取一个窗口的位置,并将另一个窗口移动到该位置。无论何时调用XGetWindowAttributes,此操作都失败。即使窗口被移动,它也始终返回x=0和y=0

Window   win;
int nxvisuals = 0;
XVisualInfo visual_template;
XVisualInfo *visual_list;
XVisualInfo vinfo;
Visual *visual;
int depth;
Atom wm_state;
(void)wm_state;

x_display = XOpenDisplay ( NULL );   // open the standard display (the primary screen)

visual_template.screen = DefaultScreen(x_display);
visual_list = XGetVisualInfo(x_display, VisualScreenMask, &visual_template, &nxvisuals);

XMatchVisualInfo(x_display, XDefaultScreen(x_display), 32, TrueColor, &vinfo)

Window parent = XDefaultRootWindow(x_display);
XSync(x_display, True);
visual = vinfo.visual;
depth = vinfo.depth;

XSetWindowAttributes  swa;
swa.event_mask = ExposureMask | PointerMotionMask | KeyPressMask;
swa.colormap = XCreateColormap(x_display, XDefaultRootWindow(x_display), visual, AllocNone);
swa.background_pixel = 0;
swa.border_pixel = 0;

win = XCreateWindow (   // create a window with the provided parameters
          x_display, parent,
          0, 0, 1024, 576, 0,
          depth, InputOutput,
          visual, CWEventMask | CWBackPixel | CWColormap | CWBorderPixel,
          &swa );

XSync(x_display, True);

XSetWindowAttributes  xattr;

xattr.override_redirect = False;
XChangeWindowAttributes ( x_display, win, CWOverrideRedirect, &xattr );

XWMHints hints;
hints.input = True;
hints.flags = InputHint;
XSetWMHints(x_display, win, &hints);

XSizeHints *size_hints = XAllocSizeHints();
size_hints->flags = PMinSize | PMaxSize | PSize;
size_hints->min_width = 1024;
size_hints->max_width = 1024;
size_hints->min_height = 576;
size_hints->max_height = 576;
XSetNormalHints(x_display, win, size_hints);
XSetWMSizeHints(x_display,win , size_hints, PSize | PMinSize | PMaxSize);

XMapWindow ( x_display , win );                   // make the window visible on the screen
XStoreName ( x_display , win , "OpenGL" ); // give the window a name

/* Second window starts here */
int cnxvisuals = 0;
XVisualInfo cvisual_template;
XVisualInfo *cvisual_list;
XVisualInfo cvinfo;
Visual *cvisual;
int cdepth;

cvisual_template.screen = DefaultScreen(x_display);
cvisual_list = XGetVisualInfo(x_display, VisualScreenMask, &cvisual_template, &cnxvisuals);

XMatchVisualInfo(x_display, XDefaultScreen(x_display), 24, TrueColor, &cvinfo)

Window child = XDefaultRootWindow(x_display);
XSync(x_display, True);
cvisual = cvinfo.visual;
cdepth = cvinfo.depth;

XSetWindowAttributes  cswa;
cswa.event_mask = PointerMotionMask | KeyPressMask;
cswa.colormap = XCreateColormap(x_display, XDefaultRootWindow(x_display), cvisual, AllocNone);
cswa.background_pixel = 0;
cswa.border_pixel = 0;

child = XCreateWindow (   // create a window with the provided parameters
          x_display, parent,
          0, 0, 1024, 576, 0,
          cdepth, InputOutput,
          cvisual, CWEventMask | CWBackPixel | CWColormap | CWBorderPixel,
          &cswa );

XSync(x_display, True);

XSetWindowAttributes  xcattr;

xcattr.override_redirect = False;
XChangeWindowAttributes ( x_display, child, CWOverrideRedirect, &xcattr );

XWMHints chints;
chints.input = True;
chints.flags = InputHint;
XSetWMHints(x_display, child, &chints);

XSetNormalHints(x_display, child, size_hints);
XSetWMSizeHints(x_display,child , size_hints, PSize | PMinSize | PMaxSize);

XMapWindow ( x_display , child );                   // make the window visible on the screen
XStoreName ( x_display , child , "video" ); // give the window a name

XSelectInput(x_display, child, ExposureMask | FocusChangeMask);

int id = pthread_create(&x11loop, NULL,x11_handle_events,this);
这是我的电话

void* x11_handle_events(void *void_ptr)
{
    Renderer* renderer = static_cast<Renderer*>(void_ptr);
    renderer->stop = false;
    XEvent event;
    XWindowAttributes opengl_attrs;
    while(!renderer->stop)
    {
        XNextEvent(renderer->x_display, &event);
        switch(event.type)
        {
            case Expose:
            if (event.xexpose.window == renderer->child)
            {
                XRaiseWindow(renderer->x_display, renderer->win);
            }
            break;

            case FocusIn:
           if (event.xfocus.window == renderer->child)
            {
                XRaiseWindow(renderer->x_display, renderer->win);
            }
            break;

        }

        // Make sure both windows are in the same location
        XGetWindowAttributes(renderer->x_display, renderer->child, &opengl_attrs);
        XMoveWindow(renderer->x_display, renderer->win, opengl_attrs.x, opengl_attrs.y);
    }


    pthread_exit(0);
    return NULL;
}
void*x11\u handle\u事件(void*void\u ptr)
{
渲染器*渲染器=静态投影(无效投影);
渲染器->停止=错误;
XEvent事件;
XWindowAttributes opengl_attrs;
而(!渲染器->停止)
{
XNextEvent(渲染器->x_显示和事件);
开关(事件类型)
{
案件曝光:
if(event.xexpose.window==renderer->child)
{
XRaiseWindow(渲染器->x_显示,渲染器->win);
}
打破
病例重点:
if(event.xfocus.window==渲染器->子对象)
{
XRaiseWindow(渲染器->x_显示,渲染器->win);
}
打破
}
//确保两个窗口位于同一位置
XGetWindowAttributes(渲染器->x_显示、渲染器->子对象和opengl_属性);
XMoveWindow(渲染器->x\u显示,渲染器->win,opengl\u attrs.x,opengl\u attrs.y);
}
pthread_退出(0);
返回NULL;
}

您要查找的事件是ConfigureNotify

X服务器可以将ConfigureNotify事件报告给需要有关窗口状态的实际更改(如大小、位置、边框和堆叠顺序)信息的客户端。每当客户端应用程序发出的以下配置窗口请求之一实际完成时,X服务器就会生成此事件类型:

剪断

通过调用XMoveWindow()移动窗口

x和y成员被设置为相对于父窗口原点的坐标,并指示窗口左上角外侧的位置。宽度和高度构件设置为窗的内部尺寸,不包括边框。边框宽度成员设置为窗口边框的宽度(以像素为单位)

事件掩码是iirc
StructureNotifyMask


不过,窗口管理器可能不同意您四处走动。。。但如果仍然不起作用,请留下评论,我们将深入了解。

谢谢,两个窗口现在一起移动。我注意到的一件事是,窗口不喜欢在标题栏上相互重叠。该窗口将紧跟在标题栏下方的另一个窗口之后。有没有办法防止这种情况发生?原因是,标题栏是窗口管理器添加的另一个窗口,然后你的应用程序窗口将被重新租给它。所以,也许您可以询问应用程序窗口的父窗口的位置。(这也是您第一次尝试时可能得到0,0的原因。)可以获得父窗口。。。但是你也可以通过减去标题栏的高度来修改它,或者更好的是,让你的叠加窗口没有标题装饰,这样它现在就在正确的位置上了。这是通过EWMH原子完成的…SetWMHints也可以这样做。我现在不记得了,必须运行,尝试搜索没有标题栏的xlib make window,如果找到它,请链接到这里。谢谢,我通过减去标题栏的高度手动将其插入。我将研究EWHM原子。