LINUX.ORG.RU

Идентификаторы окон

 , ,


0

1

Хочется получить активное окно, а именно его ид чтоб сделать скриншот (QPixmap::grabWindget()) и его заголовок. Делаю так:

Display *display = XOpenDisplay(NULL);
Window win, root, parent, *children;
int revert = RevertToParent;
int screen = DefaultScreen(display);
unsigned int nchild;
XGetInputFocus(display, &win, &revert);

if (win != RootWindow(display, screen)) {
    parent = win;
    do {
        win = parent;
        XQueryTree(display, win, &root, &parent, &children, &nchild);
        XFree(children);
    } while(parent != RootWindow(display, screen));
}
После этого скриншот окна с идентификатором win - то что надо. Имя пытаюсь получить так:
Atom nameAtom = XInternAtom(display, "_NET_WM_VISIBLE_NAME", false);
Atom atomType = XInternAtom(display, "UTF8_STRING", false);
Atom actualType;
int format;
unsigned long nitems, after;
unsigned char *data = 0;

int status = XGetWindowProperty(display, win, nameAtom, 0, 65536,
                                false, /*AnyPropertyType*/ atomType, &actualType, &format,
                                &nitems, &after, &data);

std::cout << "Returned status: " << status << std::endl;
if (data) {
  	std::cout << "Active window name: " << data << std::endl;
  	XFree(data);
}
Но статус и data всё время 0.

Дальше заметил что идентификатор окна который возвращает xprop не совпадает с моим win, если его использовать в коде для получения имени - всё работает нормально, а если в коде скриншутера - снимается что-то совсем странное.

Так вот, как разобраться в этих идентификаторах и ЧЯДНТ? И почему апи иксов такое говно?

Скачай исходники wmctrl, xprop, xdotool и разбирайся :D. Вот из wmctrl:

static Window get_active_window(Display *disp) {/*{{{*/
    char *prop;
    unsigned long size;
    Window ret = (Window)0;
    
    prop = get_property(disp, DefaultRootWindow(disp), XA_WINDOW, 
                        "_NET_ACTIVE_WINDOW", &size);
    if (prop) {
        ret = *((Window*)prop);
        g_free(prop);
    }

    return(ret);
static gchar *get_property (Display *disp, Window win, /*{{{*/
        Atom xa_prop_type, gchar *prop_name, unsigned long *size) {
    Atom xa_prop_name;
    Atom xa_ret_type;
    int ret_format;
    unsigned long ret_nitems;
    unsigned long ret_bytes_after;
    unsigned long tmp_size;
    unsigned char *ret_prop;
    gchar *ret;
    
    xa_prop_name = XInternAtom(disp, prop_name, False);
    
    /* MAX_PROPERTY_VALUE_LEN / 4 explanation (XGetWindowProperty manpage):
     *
     * long_length = Specifies the length in 32-bit multiples of the
     *               data to be retrieved.
     */
    if (XGetWindowProperty(disp, win, xa_prop_name, 0, MAX_PROPERTY_VALUE_LEN / 4, False,
            xa_prop_type, &xa_ret_type, &ret_format,     
            &ret_nitems, &ret_bytes_after, &ret_prop) != Success) {
        p_verbose("Cannot get %s property.\n", prop_name);
        return NULL;
    }
  
    if (xa_ret_type != xa_prop_type) {
        p_verbose("Invalid type of %s property.\n", prop_name);
        XFree(ret_prop);
        return NULL;
    }

    /* null terminate the result to make string handling easier */
    tmp_size = (ret_format / 8) * ret_nitems;
    ret = g_malloc(tmp_size + 1);
    memcpy(ret, ret_prop, tmp_size);
    ret[tmp_size] = '\0';

    if (size) {
        *size = tmp_size;
    }
    
    XFree(ret_prop);
    return ret;
}

Bad_ptr ★★★★★
()

А, сори, т.е. активное окно ты получил и скриншот сделал?
Тогда попробуй не _NET_WM_VISIBLE_NAME а просто WM_ICON_NAME или _NET_WM_ICON_NAME

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

Получил, но два разных ид по сути. Да и третий могу получить. Мёрфи во мне шепчет что твой код выдаст четвёртый. Вообще, всё странно и с этими двумя:

xprop моего эмулятора терминала (из него я и запускаю тестовое приложение, он и есть активное окно):

xprop
_NET_WM_USER_TIME(CARDINAL) = 44909533
_NET_WM_ICON_GEOMETRY(CARDINAL) = 565, 741, 180, 24
WM_STATE(WM_STATE):
		window state: Normal
		icon window: 0x0
_NET_WM_DESKTOP(CARDINAL) = 0
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_CHANGE_DESKTOP, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_MOVE, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_FULLSCREEN, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW, _OB_WM_ACTION_UNDECORATE
_KDE_NET_WM_FRAME_STRUT(CARDINAL) = 1, 1, 22, 5
_NET_FRAME_EXTENTS(CARDINAL) = 1, 1, 22, 5
_NET_WM_STATE(ATOM) = 
_OB_APP_TYPE(UTF8_STRING) = "normal"
_OB_APP_TITLE(UTF8_STRING) = "None"
_OB_APP_CLASS(UTF8_STRING) = "Terminator"
_OB_APP_NAME(UTF8_STRING) = "terminator"
_OB_APP_ROLE(UTF8_STRING) = 
_NET_WM_VISIBLE_ICON_NAME(UTF8_STRING) = "/bin/bash"
_NET_WM_VISIBLE_NAME(UTF8_STRING) = "/bin/bash"
WM_HINTS(WM_HINTS):
		Client accepts input or input focus: True
		Initial state is Normal State.
		bitmap id # to use for icon: 0x260001f
		bitmap id # of mask for icon: 0x2600022
		window id # of group leader: 0x2600001
XdndAware(ATOM) = BITMAP
_MOTIF_DRAG_RECEIVER_INFO(_MOTIF_DRAG_RECEIVER_INFO) = 0x6c, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0
_NET_WM_ICON(CARDINAL) = 	Icon (48 x 48):
      иконка ...
_NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 39845893
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
_NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0x2600004
WM_CLIENT_LEADER(WINDOW): window id # 0x2600001
_NET_WM_PID(CARDINAL) = 14102
WM_LOCALE_NAME(STRING) = "ru_RU.UTF-8"
WM_CLIENT_MACHINE(STRING) = "home"
WM_NORMAL_HINTS(WM_SIZE_HINTS):
		program specified resize increment: 8 by 15
		program specified base size: 6 by 11
		window gravity: NorthWest
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST
WM_CLASS(STRING) = "terminator", "Terminator"
WM_ICON_NAME(STRING) = "/bin/bash"
_NET_WM_ICON_NAME(UTF8_STRING) = "/bin/bash"
WM_NAME(STRING) = "/bin/bash"
_NET_WM_NAME(UTF8_STRING) = "/bin/bash"

Насколько я понимаю, оно считает что ид окна: 0x2600001 (39845889). Хардкодом вбиваю этот ид в код, выдаёт _NET_WM_NAME = «terminator», _NET_WM_ICON_NAME = «terminator», WM_ICON_NAME = "", тоесть оно ещё и не совпадает с выхлопом xpropа. Если скриншотить этот ид, то на изображении внезапно кусок иконки случайного(?) запущенного приложения.

Код выше определяет ид 12592589. С ним все три свойства NULL, а скриншот нормальный.

Вот я и не пойму, почему их два разных и один работает для одного, другой - для другого (и то как-то странно).

Kalashnikov ★★★
() автор топика

И почему апи иксов такое говно?

Что здесь такого? Иксы предоставляют только иерархию окон (прямоугольных областей) и механизм по приписыванию им свойств. X-сервер понятия не имеет, кто у тебя top level window. Эти окна есть предмет специальных договоренностей ICCCM и EWMH, которые специально трактуют некоторые окна и выставляют определенные свойства.

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