LINUX.ORG.RU

список окон xlib

 ,


0

2

Братцы, нужно получить список окон.

Делаю так:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <X11/Xutil.h>

static Display *dpy;
static Window root;
char **name;
int param;
int main(int argc, char ** argv)
{
  dpy = XOpenDisplay (NULL);
  assert (dpy);
  root = DefaultRootWindow (dpy);
  assert (root);

  Window rw, pw, *cw;
  unsigned int nchildren, i;


  assert (XQueryTree (dpy, root, &rw, &pw, &cw, &nchildren));
  for (i = 0; i < nchildren; i++)
  {
        XFetchName(dpy,cw[i],name);
	printf("%s\n",name);
  }


 XCloseDisplay (dpy);

}

Получаю вот это: segmentation fault (core dumped).

Подскажите чего не так?


Ответ на: комментарий от mixa

Примерно следующим образом:

void CSoftwareInfoLinux::enumerateWindows(Display *display, Window rootWindow)
{
    Window parent;
    Window *children;
    Window *child;
    quint32 nNumChildren;

    XTextProperty wmName;
    XTextProperty wmCommand;

    int status = XGetWMName(display, rootWindow, &wmName);
    if (status && wmName.value && wmName.nitems)
    {
        int i;
        char **list;
        status = XmbTextPropertyToTextList(display, &wmName, &list, &i);
        if (status >= Success && i && *list)
        {
            qDebug() << "Found window with name:" << (char*) *list;
        }

        status = XGetCommand(display, rootWindow, &list, &i);
        if (status >= Success && i && *list)
        {
            qDebug() << "... and Command:" << i << (char*) *list;
        }

        Window tf;
        status = XGetTransientForHint(display, rootWindow, &tf);
        if (status >= Success && tf)
        {
            qDebug() << "TF set!";
        }

        XWMHints *pHints = XGetWMHints(display, rootWindow);
        if (pHints)
        {
            qDebug() << "Flags:" << pHints->flags
                    << "Window group:" << pHints->window_group;
        }
    }

    status = XQueryTree(display, rootWindow, &rootWindow, &parent, &children, &nNumChildren);
    if (status == 0)
    {
        // Could not query window tree further, aborting
        return;
    }

    if (nNumChildren == 0)
    {
        // No more children found. Aborting
        return;
    }

    for (int i = 0; i < nNumChildren; i++)
    {
        enumerateWindows(display, children[i]);
    }

    XFree((char*) children);
}

Deathstalker ★★★★★ ()

если пишешь кейлоггер то уже есть готовые =)

reprimand ★★★★★ ()
Последнее исправление: reprimand (всего исправлений: 1)
XFetchName(dpy,cw[i],name);
printf("%s\n",name);

The XFetchName() function returns the name of the specified window. If it succeeds, it returns a nonzero status; otherwise, no name has been set for the window, and it returns zero. If the WM_NAME property has not been set for this window, XFetchName() sets window_name_return to NULL. If the data returned by the server is in the Latin Portable Character Encoding, then the returned string is in the Host Portable Character Encoding. Otherwise, the result is implementation dependent. When finished with it, a client must free the window name string using XFree().

Zubok ★★★★★ ()
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <X11/Xutil.h>

static Display *dpy;
static Window root;
char *name;
int param;

int main(int argc, char **argv)
{
    dpy = XOpenDisplay(NULL);
    assert(dpy);
    root = DefaultRootWindow(dpy);
    assert(root);

    Window rw, pw, *cw;
    unsigned int nchildren, i;

    assert(XQueryTree(dpy, root, &rw, &pw, &cw, &nchildren));
    for (i = 0; i < nchildren; i++) {
        if (XFetchName(dpy, cw[i], &name)) {
            printf("%s\n", name);
            XFree(name);
        }
    }
    XCloseDisplay(dpy);
}

Не у всех Х-окон есть имя(заголовок). В таких случаях XFetchName кладет NULL в name, и возвращает 0. Падает printf(«%s\n», NULL).

И на name надо говорить XFree. (man XFetchName)

anonymous ()
Ответ на: комментарий от anonymous

Спасибо, последний вариант работает!

Обнаружил интересную вещь. У мне открыт ELK терминал. И вверху у этого окна собственно и написано «ELK терминал», я всегда думал что это и есть заголовок, но программа выводит, что заголовок у нее «elk-wm». А чем тогда является надпись на окне «ELK терминал» и как мне ее получить?

Спасибо!

mixa ()
Ответ на: комментарий от anonymous

вообще задача такая:

есть программа (сетевая). когда нам по ней приходит сообщение, появляется окошко «вам пришло сообщение».

Нужно сделать так, чтоб когда это окошко появляется, это дело фиксировалось и проигрывался какой-либо аудиофайл для привлечения внимания.

mixa ()
Ответ на: комментарий от mixa

devilspie спасет отца демократии.

UPD. Или не спасет. Что-то я был уверен, что там есть запуск программ и скриптов, если сработало правило. Но что-то не вижу.

Zubok ★★★★★ ()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

UPD. Или не спасет. Что-то я был уверен, что там есть запуск программ и скриптов, если сработало правило. Но что-то не вижу.

А, нет. кажется, спасет. Надо проверить, то ли это.

UPD: Работает! У себя проверил. По правилу запускает нужную команду.

Вот в man:

       spawn_async
              Execute a command in the background (returns  boolean).  Command
              is  given as a single string, or as a series of strings (similar
              to execl).

       spawn_sync
              Execute a command in the foreground (returns command  output  as
              string, or FALSE on error). Command is given as a single string,
              or as a series of strings (similar to execl).
Zubok ★★★★★ ()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Спасибо за совет, но охото уже добить то что есть.

Как все таки быть вот с этим:

Обнаружил интересную вещь. У мне открыт ELK терминал. И вверху у этого окна собственно и написано «ELK терминал», я всегда думал что это и есть заголовок, но программа выводит, что заголовок у нее «elk-wm». А чем тогда является надпись на окне «ELK терминал» и как мне ее получить?

mixa ()
Ответ на: комментарий от mixa

Если честно, то не имею возможности разбираться, что у тебя там не так. Это глупо заниматься программазмом, когда для твоей задачи есть готовые средства. Задача решается за минуту. К тому же, твоя программа не будет работать в фоне, она не умеет перехватывать события открытия и создания окон. Как ты там собираешься делать - одному Патрегу известно. Каждую секунду программу вызывать? :)

А чем тогда является надпись на окне «ELK терминал» и как мне ее получить?

Ну вот откуда нам знать? Набираешь в терминале xprop? жмешь в окошко с этим ELK, вывод вываливаешь сюда (или, если вывод длинный очень, то на pastebin.com).

Zubok ★★★★★ ()
Последнее исправление: Zubok (всего исправлений: 4)
Ответ на: комментарий от mixa

Значит, elk-wm имя какого-то другого окна в иерархии. Да и из названия видно, что ты получил имя какого-то окна оконного своего менеджера ELK (или что там). Это не имя терминала и это не окно терминала. Вот и все. Значит, до окна «ELK Терминал» надо лезть еще ниже по иерархии. Значит, на первом уровне иерархии после RootWindow терминала твоего нет. В общем, фигней ты занимаешься.

Zubok ★★★★★ ()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от mixa

Обходит все окна. Печатает имя, если есть.

#include <stdio.h>
#include <X11/Xlib.h>

Display *dpy;

void pwn(Window win)
{
    unsigned int nchildren, i;
    Window rw, pw, *cw;
    char *name;

    if (XFetchName(dpy, win, &name)) {
        printf("%s\n", name);
        XFree(name);
    }
    if (XQueryTree(dpy, win, &rw, &pw, &cw, &nchildren)) {
        for (i = 0; i < nchildren; ++i)
            pwn(cw[i]);
        XFree(cw);
    }
}

int main()
{
    Window root;

    if ((dpy = XOpenDisplay(NULL))) {
        if ((root = DefaultRootWindow(dpy)))
            pwn(root);
        XCloseDisplay(dpy);
    }
    return 0;
}
Случайно «программа (сетевая)» не firefox ?

anonymous ()
Ответ на: комментарий от anonymous

Спасибо за помощь!

Нет, программа другая - «юпитер».

mixa ()
Ответ на: комментарий от anonymous

Очень дорогой обход. Надо прекращать поиск вглубь, когда найдено первое окно, у которого WM_STATE есть, а дальше уже не погружаться. Иерархия в теории может быть очень большой, а искать по ней всей смысла никакого нет, так как там будут окна виджетов. Тем не менее, если смотреть проблему, о которой говорит ТС, то, повторю, он занимается фигней. И способ, которым он хочет искать окно, полная фигня.

Zubok ★★★★★ ()
Последнее исправление: Zubok (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.