简体   繁体   English

在X11窗口上移动窗口事件

[英]Move window event on X11 window

I currently have 2 X11 windows that I want to keep in sync. 我目前有2个X11窗口,我想保持同步。 One overlays a transparent graphic while the other one shows video. 一个覆盖透明图形,另一个显示视频。 I currently have the one that overlays graphic to be always on top of the one of the video, but I am having trouble making sure both windows are at the same places when moved. 目前,我有一个可以将图形叠加在视频之一上,但我无法确保两个窗口在移动时都位于同一位置。 I am looking for a window move event in the X11 documentation, but I can't seem to find one. 我正在X11文档中寻找一个窗口移动事件,但似乎找不到。

In addition, in my event handle loop, I have tried to get the location of one of my windows and to move the other window to that location. 另外,在事件句柄循环中,我尝试获取一个窗口的位置并将另一个窗口移至该位置。 This has failed whenever XGetWindowAttributes is called it always returns x=0 and y=0 even though the window is moved. 每当调用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);

Here is my handle events call 这是我的句柄事件调用

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;
}

The event you're looking for is ConfigureNotify 您正在寻找的事件是ConfigureNotify

http://tronche.com/gui/x/xlib/events/window-state-change/configure.html http://tronche.com/gui/x/xlib/events/window-state-change/configure.html

The X server can report ConfigureNotify events to clients wanting information about actual changes to a window's state, such as size, position, border, and stacking order. X服务器可以将ConfigureNotify事件报告给需要有关窗口状态的实际更改(例如大小,位置,边框和堆叠顺序)的信息的客户端。 The X server generates this event type whenever one of the following configure window requests made by a client application actually completes: 每当客户机应用程序实际完成以下配置窗口请求之一时,X服务器就会生成此事件类型:

snip 剪断

A window is moved by calling XMoveWindow(). 通过调用XMoveWindow()移动窗口。

The x and y members are set to the coordinates relative to the parent window's origin and indicate the position of the upper-left outside corner of the window. x和y成员设置为相对于父窗口原点的坐标,并指示窗口左上角的位置。 The width and height members are set to the inside size of the window, not including the border. width和height成员设置为窗口的内部尺寸,不包括边框。 The border_width member is set to the width of the window's border, in pixels. border_width成员设置为窗口边框的宽度,以像素为单位。

The event mask is iirc StructureNotifyMask . 事件掩码是iirc StructureNotifyMask

The window manager might disagree with your moving around though... but if it still doesn't work, leave a comment and we'll look deeper. 窗口管理器可能会不同意您的走动...但是,如果仍然无法正常工作,请发表评论,我们会做得更深。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM