LINUX.ORG.RU

Получение имени окна по ID

 , ,


0

1

Здравствуйте. Получаю список окон при помощи свойства корневого окна _NET_CLIENT_LIST:

Window *winlist(Display* display, unsigned long* len) {
    Atom prop = XInternAtom(display,"_NET_CLIENT_LIST",False), type;
    int form;
    unsigned long remain;
    unsigned char* list;

    XGetWindowProperty(display,XDefaultRootWindow(display),prop,0,1024, False, 33,
                    &type,&form,len,&remain,&list);

    return (Window*)list;
}

void getWinList(Display* display, QList<unsigned long>* winIDs) {
    unsigned long len;
    Window* list = winlist(display, &len);

    for (unsigned int i = 0; i < len; ++i) {
        winIDs->append(*(list + i));
    }
}

ID есть и если перевести полученные числа из десятичной СС в шестнадцатеричную СС, то адреса совпадают с теми, что показывает wmctrl -l и xprop -root _NET_CLIENT_LIST. Пытаюсь получить имена:

QString getNameByID(Display* display, unsigned long* id) {
    Atom prop = XInternAtom(display, "_NET_WM_NAME", False), type;
    int form;
    unsigned long remain;
    unsigned char* list;
    unsigned long len = 0;

    XGetWindowProperty(display, (Window)id, prop, 0, 1024, False, 4,
                       &type, &form, &len, &remain, &list);

    for (unsigned int i = 0; i < len; ++i) {
        qDebug() << *(list + i);
    }

    return "";
}

В ответ на qDebug не получаю ничего. Подскажите, пожалуйста, в чем дело.


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

Да, 33 - XA_WINDOW. Взял отсюда. По поводу debug. Во всем остальном коде, в т.ч. здесь же qDebug() << «123» прекрасно работает. Проблема, насколько я понимаю, либо в том, что XGetWindowProperty в getNameByID() ничего в list не записал, либо в том, что я неправильно к нему обращаюсь.

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

а 4 это что мы должны все угадывать? пиши вместо 33 XA_WINDOW это же константа из хидера
ты не проверяешь тип результата type, с выше приведенными магическими числами непонятно что ты запрашиваешь.
XGetWindowProperty аллоцирует память которую ты не освобождаешь, memory leak 110%.
ты точно используешь Qt? QList<Window*> в результате getWinList видеть предпочтительнее, при этом все аллокации оставляя внутри функции.
NET_WM_NAME это по идее строка char* + len = QString, в своем цикле ты хочешь увидеть буквы?
NET_WM_NAME это UTF8_STRING и запрашивать нужн этот атом
разберитесь с параметрами XGetWindowProperty какой и для чего, да их много но там если разобраться все становится понятно

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

4 - это XA_ATOM. Подключил <X11/Xatom.h>, теперь видит константы.

По числам. XGetWindowProperty(display, (Window)id, prop, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, &list) 0 - long_offset, 1024 - long_length

По Window. Посмотрел в X.h. Window - это XID, а XID - это обычный unsigned long. Т.е. по идее, с ним должно быть все ок.

По QList. Попробовал. Получил совершенно другие числа и также никакого ответа от XGetWindowProperty.

По memory leak. Добавил XFree(list) в связи с тем, что теперь есть QList.

Единственное, что меня здесь насторожило, это XA_ATOM, который я попробовал заменить на XA_WM_NAME (мне же _NET_WM_NAME нужно). Положительного результата не дало. По прежнему все переменные (type, form, len) = 0.

QList<Window*> winlist(Display* display, unsigned long* len) {
    Atom prop = XInternAtom(display, "_NET_CLIENT_LIST", False), type;
    int form;
    unsigned long remain;
    unsigned char* list;
    QList<Window*> windows;

    XGetWindowProperty(display, XDefaultRootWindow(display), prop, 0, 1024,
                       False, XA_WINDOW, &type,&form,len,&remain,&list);

    for (unsigned short i = 0; i < *len; ++i) {
        windows << (Window*)(list + i);
    }

    XFree(list);

    return windows;
}

QString WindowList::getNameByID(Display* display, Window* win) {
    Atom prop = XInternAtom(display, "_NET_WM_NAME", False), type;
    int form;
    unsigned long remain;
    unsigned char* list;
    unsigned long len = 0;

    XGetWindowProperty(display, *win, prop, 0, 1024, False, XA_WM_NAME,
                       &type, &form, &len, &remain, &list);

    qDebug() << "len:" << len;
    qDebug() << "form:" << form;
    for (unsigned int i = 0; i < len; ++i) {
        qDebug() << *(list + i);
    }

    return "";
}

void WindowList::getWinList(Display* display, QList<unsigned long>* winIDs) {
    unsigned long len;
    QList<Window*> windows = winlist(display, &len);
    qDebug() << "Length: " << len;

    foreach(Window* win, windows) {
        qDebug() << win;
        getNameByID(display, win);
    }
}
thm
() автор топика
Последнее исправление: thm (всего исправлений: 1)
Ответ на: комментарий от thm

NET_WM_NAME это тип UTF8_STRING и запрашивать нужн этот атом -> XInternAtom(«UTF8_STRING») а не XA_WM_NAME, либо ANY_TYPE я не знаю как в xlib это называется

XA_WM_NAME это атом XInternAtom(«_NET_WM_NAME»)

XGetWindowProperty(display, *win, XA_WM_NAME, 0, 1024, False, ATOM_UTF8_STRING,
                       &type, &form, &len, &remain, &list);
anonymous2 ★★★★★
()
Последнее исправление: anonymous2 (всего исправлений: 5)

Вопрос решил подключением либы KWindowSystem и использованием функции KWindowSystem::windows()

thm
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.