XReparentWindow零星工作(XReparentWindow works sporadic

2019-10-29 07:13发布

我尝试用XReparentWindow与最终目标,以多个进程的总窗口为一个“驾驶舱”模拟过程。 与XReparentWindow实验零星工作; 有时窗口被成功地重设父,有时没有 。 当未成功重设父的(不)抓住窗口闪烁用于第二和随后proceedes像往常一样,和抓取器显示窗口未定义内容。 它是全成每个其他时间(由诱惑总是试图两次以暴力破解的问题远)。

编辑1:检查输出XQueryTree之后XReparentWindow显示抓住窗口正确重设父,但似乎保持其框架的起源,其中来自于显示器,而不是被移动到采集窗口抓起。

该抓住窗口从实时OpenGL渲染应用,从源代码编译。 该应用程序不预期以任何方式抢夺(也许它应该?)。 我也曾尝试抓取glxgears和GNOME终端,同样的结果。

实验代码,以窗口为抢程序参数(例如,使用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;
}

(代码被手动从一个受限制的环境中导出。对不起出口期间进行的任何拼写错误。)

期待着明年什么尝试了建议。

编辑2:具有拍摄使用抓起窗口的事件流xev ,我注意到一些奇怪的; 被重设父的采集窗口之后,它本身reparents回根窗口后不到一秒钟(受限制的环境中,输入什么上看到与预期的意义的其他窗口):

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

我退出程序,然后重试第二次,在此是继续对输出是:

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

到底是怎么回事?

Answer 1:

我从来没有与OpenGL应用程序尝试和没有这里的环境。 也许尝试先用一个简单的X应用程序(如XCLOCK),如果你得到了相同的行为观察。 如果是的话,那是你的代码,如果没有,可能是OpenGL的互动。

从你的snippset,虽然两点意见:

while循环,你应该消耗的X事件

XEvent e;    
while(1) {
     XNextEvent(d, &e);
}

然后XAddToSaveSet功能不能正常工作。 您将需要使用利用Xfixes为了正确地还原该窗口在发生碰撞的情况。

#include <X11/extensions/Xfixes.h>

...

// The Xorg API is buggy in certain areas.
// Need to use the XFixes extensions to address them
// Initializes these extensions
int event_base_return = 0;
int error_base_return = 0;
Bool result = XFixesQueryExtension(display, &event_base_return);
printf("XFixesQueryExtension result: %d. eventbase: %d - errorbase: %d\n", result, event_base_return, error_base_return);

// We actually only need version 1.0. But if 4.0 is not there then something is really wrong
int major = 4;
int minor = 0;
result = XFixesQueryVersion(display, &major, &minor);
printf("XFixesQueryVersion result: %d - version: %d.%d\n", result, major, minor);

...
XReparentWindow(display, childWindowId, parentWindowId, 0, 0);
XFixesChangeSaveSet(display, childWindowId, SetModeInsert, SaveSetRoot, SaveSetUnmap);
...


Answer 2:

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

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

假设这一次该条款可以经过两次电话被禁用,以重新设置父级发生。 作品在我的机器上。 希望了解什么是真正发生了充分的解释。



文章来源: XReparentWindow works sporadically
标签: x11 gnome xlib