Имена тестовых окон Xlib

0

Я пытаюсь получить контроль над Xterm с Xlib. Для этого я делаю Xterm со странным названием. После того, как я перечислил все окна и проверил их имена. Но что-то прослушивается, nammes моего 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);
    }
}
Теги:
title
xterm
xlib

2 ответа

2

Я не могу воспроизвести ошибку; ваш код находит мои окна xterm. Вы запрашиваете окно xterm, которое вы только что породили? Если это так, у вас может быть состояние гонки, в котором вы пытаетесь найти окно, прежде чем xterm получит шанс сделать это. В этом случае крахмальное решение было бы немного подождать и повторить попытку несколько раз.

Если это не так, я могу только предположить (больше) о причинах (мои предположения связаны с неправильным оконным менеджером или очень старым программным обеспечением), но, возможно, я могу предложить решение: если xterm не отображается в корневом окне _NET_CLIENT_LIST, пропустите прямо в дерево окна и посмотрите, найдем ли мы его там. Этот бит кода C (портирование на C++ не должно быть затруднительным, и в любом случае это достаточно, чтобы XQueryTree его) XQueryTree перемещает дерево окна с помощью 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-окно должно быть среди них. Если это не так, обратитесь к началу (бит о возможном состоянии гонки). И если это не так, то что-то очень странное.

  • 0
    После перезагрузки Xterm появится в списке. Когда программа закрыта, мне нужно освободить память используемого окна? Если мне нужно, как я могу это сделать? Благодарю.
  • 0
    После некоторого теста с вашим кодом, иногда он не находил консоль, потому что я думаю, что X-сервер создает окно, но не обновляет список окон. Нет?
Показать ещё 1 комментарий
0

После поиска, если я не добавляю cout, функция не работает, почему? Я добавил cout здесь:

if(XFetchName(display, current, &name) > 0) {
        int r = strcmp(needle, name);
        std::cout << current << " : " << name << std::endl;
        XFree(name);
        if(r == 0) {
            return current;
        }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню