【问题标题】:Grabbing the X server with XGrabServer使用 XGrabServer 抓取 X 服务器
【发布时间】:2009-07-10 06:26:21
【问题描述】:

在嵌入式 Linux 系统中,我试图显示关闭通知,该通知应在关闭时覆盖任何其他窗口。现在创建窗口不是问题,但可靠地显示窗口是。 X 服务器或 WM 不知何故太忙而无法每次都绘制通知。考虑到我们的 CPU 能力有限,这不足为奇。

所以,我想我可以通过使用 gdk_x11_grab_server()(在默认显示上调用 XGrabServer)抓取 X 服务器来简化 WM/X。但是我什么时候应该调用抓取函数?如果我在构建我的窗口之前调用它,在我的窗口的暴露事件中显示我的窗口或事件之前,没有任何内容被绘制到屏幕上(即使在空载测试中)!

documentation 说:

XGrabServer 功能禁用 处理请求和关闭 在除一个以外的所有其他连接上 这个请求到达了。

我想这意味着应该只处理来自我的应用程序的请求,但似乎情况并非如此,因为如果我的应用程序抓取了 X,则不会绘制任何内容。

那么,应该如何以及何时使用抓取 X 服务器来获得想要的结果,还是它完全是一个错误的工具,我误解了它的使用(或试图使用它太高级了)让它真正起作用)。

【问题讨论】:

    标签: linux embedded


    【解决方案1】:

    我猜什么都没有被绘制,因为你打开的是一个普通的顶级窗口,在这种情况下,窗口管理器需要在它可见之前对其进行操作;但是您已经通过调用 XGrabServer() 锁定了窗口管理器。

    你可以尝试在窗口上设置 OverrideRedirect,它告诉 X 服务器窗口管理器根本不应该参与这个窗口。这还具有从窗口中删除任何装饰(标题栏、关闭按钮等)的效果,这很可能是您想要的关闭通知。

    【讨论】:

      【解决方案2】:

      您可能需要通过XSync/XFlush 关注电话。

      【讨论】:

        【解决方案3】:

        您不应该继续调用XUngrabServer 以便X 服务器恢复处理请求吗?由于您调用了XGrabServer,所有其他连接都已关闭,但您显然需要恢复请求处理,因为您想在连接上发出请求。

        【讨论】:

          【解决方案4】:

          XGrabServer 究竟做了什么似乎有些令人困惑,而不仅仅是在这个问题上。手册页对此非常含糊。我们可以很容易地验证服务器确实仍在处理来自我们连接的请求:

          // cc grab-test.c `pkg-config --cflags --libs x11`
          #include <assert.h>
          #include <stdio.h>
          #include <unistd.h>
          
          #include <X11/Xlib.h>
          
          int main(void)
          {
              // Initialize
              Display* dpy = XOpenDisplay(NULL);
              assert(dpy != NULL);
              int s = DefaultScreen(dpy);
              // Grab the Server
              XGrabServer(dpy); // XFlush(dpy);
              // Create some stuffs
              Window win = XCreateSimpleWindow(dpy, RootWindow(dpy, s), 10, 10, 640, 480, 1, BlackPixel(dpy, s), WhitePixel(dpy, s));
              XSelectInput(dpy, win, ExposureMask);
              XMapWindow(dpy, win);
              XStoreName(dpy, win, "An X11 window");
              // Notice we can query the attributes BEFORE ungrabbing the server
              XWindowAttributes wa;
              XGetWindowAttributes(dpy, win, &wa);
              int width = wa.width;
              int height = wa.height;
              printf("Current window size: %dx%d\n", width, height);
              sleep(2); // Give some time to see the window
              XDestroyWindow(dpy, win); XFlush(dpy);
              sleep(2); // Give some time to NOT see the window
              // Ungrab the server
              XUngrabServer(dpy); // XFlush(dpy);
              // Shutdown
              XCloseDisplay(dpy);
              return 0;
          }
          

          可能有一个窗口管理器或复合管理器阻止窗口显示,如果我在 Xephyr 中运行上述程序(没有窗口管理器或复合管理器),我可以看到一个白色窗口 2 秒,然后是黑色屏幕停留 2 秒,然后重新绘制所有其他窗口。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-02-07
            • 2021-09-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-01-04
            • 1970-01-01
            • 2016-05-06
            相关资源
            最近更新 更多