在 X11 window 上移动 window 事件
Move window event on X11 window
我目前有 2 个 X11 windows 想要保持同步。一个覆盖透明图形,而另一个显示视频。我目前有一个叠加图形总是在视频之一的顶部,但我无法确保两个 windows 在移动时位于相同的位置。我在 X11 文档中寻找 window 移动事件,但我似乎找不到。
此外,在我的事件句柄循环中,我试图获取我的 windows 之一的位置并将另一个 window 移动到该位置。每当调用 XGetWindowAttributes 时都会失败,它总是 returns x=0 和 y=0,即使 window 已移动。
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;
}
您要查找的事件是 ConfigureNotify
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. The X server generates this event type whenever one of the following configure window requests made by a client application actually completes:
snip
A window is moved by calling 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. The width and height members are set to the inside size of the window, not including the border. The border_width member is set to the width of the window's border, in pixels.
事件掩码是 iirc StructureNotifyMask
。
尽管 window 经理可能不同意你四处走动......但如果仍然不起作用,请发表评论,我们会进行更深入的研究。
我目前有 2 个 X11 windows 想要保持同步。一个覆盖透明图形,而另一个显示视频。我目前有一个叠加图形总是在视频之一的顶部,但我无法确保两个 windows 在移动时位于相同的位置。我在 X11 文档中寻找 window 移动事件,但我似乎找不到。
此外,在我的事件句柄循环中,我试图获取我的 windows 之一的位置并将另一个 window 移动到该位置。每当调用 XGetWindowAttributes 时都会失败,它总是 returns x=0 和 y=0,即使 window 已移动。
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;
}
您要查找的事件是 ConfigureNotify
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. The X server generates this event type whenever one of the following configure window requests made by a client application actually completes:
snip
A window is moved by calling 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. The width and height members are set to the inside size of the window, not including the border. The border_width member is set to the width of the window's border, in pixels.
事件掩码是 iirc StructureNotifyMask
。
尽管 window 经理可能不同意你四处走动......但如果仍然不起作用,请发表评论,我们会进行更深入的研究。