c++ - Xlib 测试窗口名称

标签 c++ linux title xlib xterm

我正在尝试使用 Xlib 控制 Xterm。 为此,我正在制作一个标题奇怪的 Xterm。在我列出所有窗口并检查它们的名称之后。但是有些东西被窃听了,当它们被列出时,我的 Xterm 的名字没有出现。这是列出所有窗口的代码:

void CMD::getWindowTerminal()
{
    Atom a = XInternAtom(m_display, "_NET_CLIENT_LIST", true);
    Atom actualType;
    int format;
    unsigned long numItems, bytesAfter;
    unsigned char *data = 0;
    int status = XGetWindowProperty(m_display, m_root_win, a, 0L, (~0L), false,
                                AnyPropertyType, &actualType, &format, &numItems,
                                &bytesAfter, &data);

    if (status >= Success && numItems)
    {
        long *array = (long*) data;
        for (unsigned long k = 0; k < numItems; k++)
        {
            // get window Id:
            Window w = (Window) array[k];

            char* name = '\0';
            status = XFetchName(m_display, w, &name);
            if (status >= Success)
            {
                std::cout << w << " " << name << std::endl;
                if (name == NULL)
                {
                    m_window_terminal = w;
                    std::cout << "TERMINAL FOUND" << std::endl;
                }
            }
            XFree(name);
        }
        XFree(data);
    }
}

最佳答案

我无法重现错误;你的代码找到了我的 xterm 窗口。您是在查询刚刚生成的 xterm 的窗口吗?如果是这样,您可能会遇到竞争条件,因为您试图在 xterm 有机会找到窗口之前找到它。在这种情况下,一个糟糕的解决方案是稍等片刻,然后重试几次。

如果不是这种情况,我只能推测(更多)原因(我的推测涉及行为不当的窗口管理器或非常旧的软件),但也许我可以建议一个解决方案:如果 xterm 没有出现在根窗口的 _NET_CLIENT_LIST,让我们直接深入到窗口树中,看看是否可以在那里找到它。这段C代码(移植到C++应该不难,反正试试就够了)用XQueryTree递归遍历了窗口树,所以查询了所有个窗口:

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>

Window window_from_name_search(Display *display, Window current, char const *needle) {
  Window retval, root, parent, *children;
  unsigned children_count;
  char *name = NULL;

  /* Check if this window has the name we seek */
  if(XFetchName(display, current, &name) > 0) {
    int r = strcmp(needle, name);
    XFree(name);
    if(r == 0) {
      return current;
    }
  }

  retval = 0;

  /* If it does not: check all subwindows recursively. */
  if(0 != XQueryTree(display, current, &root, &parent, &children, &children_count)) {
    unsigned i;
    for(i = 0; i < children_count; ++i) {
      Window win = window_from_name_search(display, children[i], needle);

      if(win != 0) {
        retval = win;
        break;
      }
    }

    XFree(children);
  }

  return retval;
}

// frontend function: open display connection, start searching from the root window.
Window window_from_name(char const *name) {
  Display *display = XOpenDisplay(NULL);
  Window w = window_from_name_search(display, XDefaultRootWindow(display), name);
  XCloseDisplay(display);
  return w;
}

因为它处理所有窗口,所以您的 xterm 窗口必须在其中。如果不是,请返回开头(关于可能的竞争条件的部分)。如果不是这样,那就很奇怪了。

关于c++ - Xlib 测试窗口名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27910906/

相关文章:

c++ - 在 C++ 中使用内联函数的未指定输出

linux - Linux除法和乘法的语法错误

python - 存储图像的标题文本 Selenium Webdriver Python

resources - 带有标题 munge 的 puppet 资源命令

c++ - Windows XP 到 Ubuntu Linux 点对点通信使用 Python 或 C/C++

c++ - 如何找出二进制文件中写入了多少个字符串?

linux - rsync-创建每日备份并在 30 天后删除?

linux - IPC 与 imsg? OpenBSD 和 Linux 兼容性?

php 动态 html 标题

c++ - Boost spirit x3 解析为结构,如果它为空则跳过成员