XReparentWindow偶尔起作用 [英] XReparentWindow works sporadically

查看:268
本文介绍了XReparentWindow偶尔起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在试验XReparentWindow,最终目的是将多个进程的窗口聚合到一个座舱"模拟进程中. XReparentWindow的实验偶尔会起作用.有时窗口成功重新设置了父级,有时没有成功.如果未成功重新设置父级,则(非)抓取的窗口闪烁一秒钟,然后照常进行,抓取器将显示未定义的窗口内容.每隔两次就成功了一次(总是尝试两次以试图强行解决问题).

I'm experimenting with XReparentWindow with the end goal to aggregate windows of multiple processes into one "cockpit" simulating process. Experiments with XReparentWindow works sporadically; sometimes the window is reparented successfully, sometimes not. When unsuccessfully reparented the (not) grabbed window flickers for a second and then proceedes as usual, and the grabber show undefined window content. It is successfull every other time (tempted to brute-force the problem away by always trying two times).

XReparentWindow显示所抓取的窗口已正确重新设置后立即检查XQueryTree的输出,但是似乎将其帧原点保留在显示的抓取位置,而不是移至抓取器窗口.

Edit 1: Checking output of XQueryTree right after XReparentWindow shows the grabbed window is properly reparented, but would appear to keep its frame origin where grabbed from on display rather than being moved to the grabber window.

抓取的窗口来自实时OpenGL渲染应用程序,该应用程序是从源代码编译的.该应用程序不会以任何方式预期抢夺(也许应该吗?).我还尝试过使用glxgears和GNOME终端,结果相同.

The grabbed window is from a real-time OpenGL rendering application, compiled from source. The application does not anticipate the grabbing in any way (maybe it should?). I have also tried grabbing glxgears and a GNOME Terminal, same result.

实验代码,以窗口作为程序参数(例如,使用xwininfo | grep "Window id"):

The experimental code, taking window to grab as program argument (e.g. using xwininfo | grep "Window id"):

#include <X11/Xlib.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h> // usleep

int main(int argc, char** argv) {
  assert(argc==2);
  Window window, extwin;
  sscanf(argv[1], "%p", &extwin);
  Display* display = XOpenDisplay(0);
  window = XCreateWindow(display, RootWindow(display, 0), 0, 0, 500, 500, 0, DefaultDepth(display, 0), InputOutput, DefaultVisual(display, 0), 0, 0);
  XMapWindow(display, window);
  XReparentWindow(display, extwin, window, 0, 0);
  while(1) {
    XFlush(display);
    usleep(3e5);
  }
  return 0;
}

(代码是从受限环境中手动导出的.对于导出过程中出现的任何错字,我们深表歉意.)

(Code is manually exported from a restricted environment. Sorry for any typos made during export.)

期待有关下一步尝试的建议.

Looking forward for suggestions of what to try out next.

使用xev捕获抓取窗口的事件流后,我发现有些奇怪.重新设置到采集卡窗口后,它会在不到一秒钟的时间内重新将自己重新绑定到根窗口(受限制的环境,键入在其他窗口上看到的具有预期意义的内容):

Edit 2: Having captured the event stream of the grabbed window using xev I notice something odd; after being reparented to the grabber window, it reparents itself back to root window after less than a second (restricted environment, typing what's seen on other window with anticipated significance):

UnmapNotify event ...
ReparentNotify event ... parent 0x4000001 (grabber window)
MapNotify event ...
ConfigureNotify event ... synthetic YES (what is this?)
UnmapNotify event ...
ReparentNotify event ... parent 0xed (reparenting back to parent window, but why?)
MapNotify event ...
VisibilityNotify event ...
Expose event ...
PropertyNotify event ... _NET_WM_DESKTOP state PropertyDelete
PropertyNotify event ... _NET_WM_STATE state PropertyDelete
PropertyNotify event ... WM_STATE state PropertyNewValue

我退出程序,然后再次尝试,然后继续输出:

I quit the program and try again a second time, at which the output that continues is:

UnmapNotify event ...
ReparentNotify event ... parent 0x4000001 (grabber window)
MapNotify event ...
VisibilityNotify event ...
Expose event ...

这是怎么回事?

推荐答案

强力解决方案,反复抓住窗口:

Brute force solution, grabbing the window repeatedly:

#include <X11/Xlib.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h> // usleep

int main(int argc, char** argv) {
  assert(argc==2);
  Window window, extwin;
  sscanf(argv[1], "%p", &extwin);
  Display* display = XOpenDisplay(0);
  window = XCreateWindow(display, RootWindow(display, 0), 0, 0, 500, 500, 0, DefaultDepth(display, 0), InputOutput, DefaultVisual(display, 0), 0, 0);
  XMapWindow(display, window);
  while(1) {
    Window root, parent, *ch;
    unsigned int nch;
    XQueryTree(display, extwin, &root, &parent, &ch, &nch);
    if(parent!=window) {
      XReparentWindow(display, extwin, window, 0, 0);
    }
    if(nch>0) { XFree(ch); }
    XFlush(display);
    usleep(3e5);
  }
  return 0;
}

假定仅在两次调用reparent之后可以禁用该子句的情况下才会发生这种情况.在我的机器上工作.希望能对真正发生的事情进行充分的解释.

Assuming this only happens once the clause can be disabled after two calls to reparent. Works on my machine. Would appreciate full explaination of what is really going on.

这篇关于XReparentWindow偶尔起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆