LINUX.ORG.RU

Xlib полноэкранное ли окно?

 ,


1

2

Весь интернет обшарил, но не нашел как определить является ли активное окно полноэкранным. Подозреваю, нужно использовать XGetWindowProperty, но с какими параметрами(а именно какой атом). Реквестую примеры. И, пользуясь случаем, хотел бы узнать, есть ли возможность посредством xlib засунуть иконку(используя pixmap или bitmap, ну или хотя бы просто символ) в трей.

P.S. Про возможности gtk и Qt мне известно поэтому не стоит о них упоминать. Интересует именно Xlib.


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

Не. Это я читал и нифига не понял. _NET_WM_STATE_FULLSCREEN всегда мне нули возвращает. Вот кусок кода:

    Atom type, filter;
    int format, status;
    unsigned long nitems, bytes_after;
    unsigned char *prop;

    filter = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", True);
    status = XGetWindowProperty(display, window, filter, 0, 256, False, AnyPropertyType,&type,
        &format, &nitems, &bytes_after, &prop);

printf("%s\n", prop);

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

Оно мне каждый раз разные цифры выдает для одного и того же клиента.

[nikita@laptop xlib_window]$ ./xgetfocus 
_NET_WM_PID: 22743
WM_CLASS: lxterminal
_NET_WM_NAME: nikita@laptop:~/Code/xlib_window
_NET_WM_STATE: 167920416
[nikita@laptop xlib_window]$ ./xgetfocus 
_NET_WM_PID: 22743
WM_CLASS: lxterminal
_NET_WM_NAME: nikita@laptop:~/Code/xlib_window
_NET_WM_STATE: 151925536
[nikita@laptop xlib_window]$ ./xgetfocus 
_NET_WM_PID: 22743
WM_CLASS: lxterminal
_NET_WM_NAME: nikita@laptop:~/Code/xlib_window
_NET_WM_STATE: 137507616

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

Покажи код. Он возвращает список атомов. Список! То есть он тебе адрес возвращает, а он разный каждый раз. Смотри, что по ссылке написано.

Zubok ★★★★★ ()
Последнее исправление: Zubok (всего исправлений: 3)
Ответ на: комментарий от Zubok
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>

Display *display;
unsigned long window;
unsigned char *prop;


unsigned char* get_string_property(char* property_name)
{
    Atom type, atom;
    int format, status;
    unsigned long nitems, bytes_after;

    atom = XInternAtom(display, property_name, True);
    status = XGetWindowProperty(display, window, atom, 0, 256, False, AnyPropertyType,
                                &type, &format, &nitems, &bytes_after, &prop);
    return prop;
}

unsigned long get_long_property(char* property_name)
{
    get_string_property(property_name);
    unsigned long long_property = prop[0] + (prop[1]<<8) + (prop[2]<<16) + (prop[3]<<24);
    return long_property;
}

int main(int argc, char** argv)
{

    display = XOpenDisplay(NULL);

    int screen = XDefaultScreen(display);
    window = RootWindow(display, screen);

    window = get_long_property("_NET_ACTIVE_WINDOW");

    printf("_NET_WM_PID: %lu\n", get_long_property("_NET_WM_PID"));
    printf("WM_CLASS: %s\n", get_string_property("WM_CLASS"));
    printf("_NET_WM_NAME: %s\n", get_string_property("_NET_WM_NAME"));
    printf("_NET_WM_STATE: %lu\n", get_string_property("_NET_WM_STATE"));

    XCloseDisplay(display);
    return 0;
}
Yaourt ()
Ответ на: комментарий от Yaourt

В prop - указатель на список атомов. nitems - число атомов. Бежишь по списку и ищешь filter. Вроде так. Мне для уточнения надо лезть в описание xlib. Если filter не найдет (filter - это атом из _NET_WM_STATE_FULLSCREEN), то, значит, нет fullscreen

A list of hints describing the window state. Atoms present in the list MUST be considered set, atoms not present in the list MUST be considered not set.

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

Тут я как раз и не понимаю. Вот указатель _NET_WM_STATE я получил, как теперь из него _NET_WM_STATE_FULLSCREEN вытащить? Я пробовал получать _NET_WM_STATE_STICKY из prop таким способом: printf(«%d», prop[1]); и все получалось, но FULLSCREEN так не канает(пробовал prop[8])...

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

Да нет же! Cписок атомов в документации это возможные значения. Они могут идти в любом порядке, они могут отсутствовать или присутствовать. У них нет фиксированных номеров. Надо бежать по списку prop[i] (от 0 до nitems-1) и искать filter.

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

Блин, теперь я не знаю как искать атом в списке. Допустим, циклом перебираю значения по одному, как узнать, что мне попалось искомое значение? XInternAtom? Оно атом просит, а не prop...

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

Делаешь

filter = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
net_wm_state = XInternAtom(display, "_NET_WM_STATE", False);

Потом получаешь свойство net_wm_state, получаешь prop, ищешь в prop filter

UPD. Подправил.

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

Я сейчас с ума сойду. Говорю же, что не знаю как искать атом(filter) в prop. По порядку: получил фильтр, получил стейт, получил проп из стейта, дальше как, что с чем сравнивать?

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

Atom *prop;

...

for (i = 0; i < nitems; i++) {
    if (prop[i] == filter) {
        BINGO!!!
        XFree(prop);
        return TRUE;
    }
}

XFree(prop);
return FALSE;

+ проверь перед обходом, что nitems > 0

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

Не, не так. При переборе на том же окне(фуллскрин и не фуллскрин) параметры отличаются, как и должно быть, но они ни одно не соответствует значению фильтра. Кусок кода и вывод(на окне простом Chrome, потом на фуллскрин):

    filter = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", 1);
    net_wm_state = XInternAtom(display, "_NET_WM_STATE", 1);
    
    Atom type, atom, *prop1;
    int format, status;
    unsigned long nitems, bytes_after;

    status = XGetWindowProperty(display, window, net_wm_state, 0, 10000, False, AnyPropertyType,
                                prop1, &format, &nitems, &bytes_after, &prop);
                                
    printf("FULL %d\nNITEM %d\n", filter,nitems );
    int i;
    if (nitems != 0){
    for (i = 0; i < nitems; i++) { /* проверка через Atom* */
        printf("    %d\n", prop1[i]);    
    }
    printf("-----\n");
    for (i = 0; i < nitems; i++) { /* проверка через unsigned char** */
        printf("    %d\n", prop[i]);    
    }
}

ВЫВОД
[nikita@laptop xlib_window]$ sleep 3 && ./xgetfocus 
FULL 359
NITEM 2
    4
    0
-----
    101
    1
[nikita@laptop xlib_window]$ sleep 3 && ./xgetfocus 
FULL 359
NITEM 3
    4
    0
    -1075594775
-----
    101
    1
    0
[nikita@laptop xlib_window]$ 

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

Давай разложу на кусочки, чтобы понятнее:

Atom *atoms;

filter = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
net_wm_state = XInternAtom(display, "_NET_WM_STATE", False);

status = XGetWindowProperty(... , &prop);
atoms = (Atom *)prop;

for (i = 0; i < nitems; i++) {
    printf("    %d\n", atoms[i]);
}

И ты уверен, что у тебя твое окно fullscreen? Проверь через утилиту xprop, она показывает список _NET_WM_STATE.

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

У тебя тут все неправильно вообще.

status = XGetWindowProperty(display, window, net_wm_state, 0, LONG_MAX, False, XA_ATOM,
                            &type, &format, &nitems, &bytes_after, (unsigned char **)&prop);

с чего ты вдруг prop1 выводишь? Туда *тип* возвращается, а не атом. Там будет XA_ATOM.

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

Вот я быстро накидал. Это работает. Вместо window надо идентификатор окна поставить. Не знаю, как ты его захватываешь в своей программе.

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

Display *display;
unsigned long window;

int main(int argc, char** argv)
{

    Atom filter, net_wm_state, type;
    int i, format, status;
    unsigned long nitems, bytes_after;
    Atom *atoms;
    unsigned char *prop;

    display = XOpenDisplay(NULL);

    filter = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
    net_wm_state = XInternAtom(display, "_NET_WM_STATE", False);

    status = XGetWindowProperty(display, window, net_wm_state, 0, LONG_MAX, 
				False, XA_ATOM, &type, &format, &nitems, 
				&bytes_after, &prop);
    atoms = (Atom *)prop;

    for (i = 0; i < nitems; i++) {
	if (atoms[i] == filter) {
	    printf("Fullscreen!\n");
	} 
    }
    
    XFree(prop);
    XCloseDisplay(display);
    return 0;
}
Zubok ★★★★★ ()
Последнее исправление: Zubok (всего исправлений: 2)

Вкусная тема, жаль на ЛОРе редко обсуждения на таком уровне проходят.

// Сам xlib не осилил, пишу на Qt.

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

Только я не очень понял, почему ты в программе передаешь RootWindow. Тебе надо идентификатор конкретного окна передать.

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

Да то для примера. Так я беру окно на котором инпутфокус XGetInputFocus().

Yaourt ()

И, пользуясь случаем, хотел бы узнать, есть ли возможность посредством xlib засунуть иконку(используя pixmap или bitmap, ну или хотя бы просто символ) в трей.

Если речь идет про системный трей, то нужно читать:

http://standards.freedesktop.org/systemtray-spec/systemtray-spec-0.3.html

И XEMBED:

http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html

Сложное чтение. Ищи примеры в сети.

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

В принципе, из соображений пуризма теперь можешь убрать atoms. Я ее использовал выше там в примере, чтобы понятно было, что и откуда берется. Сейчас можно заменить:

Atom *prop;
/* Atom *atoms; <----- убрать */
...
status = XGetWindowProperty(... (unsigned char **)&prop); /* замена */

/* atoms = (Atom *)prop;  <----- убрать */

...
    if (prop[i] == filter) {  /* замена */

Ну и лучше всего проверять status, а также, что prop не NULL. Не забывать при любом исходе делать XFree(prop).

Zubok ★★★★★ ()
29 июня 2016 г.
Ответ на: комментарий от Zubok

активное окно

Добрый день!

в терминале запускаю программу с таким кодом:

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

то есть хочу получить активное (как я думаю это терминал) окно и тут же его закрыть .

но терминал не закрывается.

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

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

Ой, только сейчас заметил среди уведомлений, что есть вопрос в старую тему. Вообще, лучше новую тему всегда создавать по другому вопросу. Тут-то совсем другой вопрос обсуждается.

Ладно, а сравнивал window id, который ты получил из XGetInputFocus и window id, который возвращает программа xprop, например. Ведь фокус может иметь не top level window приложения, а какой-то его сотый потомок (он же тоже окно). Иксы - это просто древовидная иерархия окон. И в них нет понятия окна приложения. Это понятие есть в ICCCM и EWMH. В иерархии окон терминала может быть несколько окон. И ты пытаешься закрыть какое-то субокно. В общем, ты сначала сравни то, о чем я в первой строчке спросил.

И вот еще ветка про поиск Top level window в иерархии окон. Мне кажется, она к твоему вопросу имеет прямое отношение. В конце есть код:

XGetInputFocus возвращает неверное значение

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

В конце есть код:

только там в момент поиска по результатам XQueryTree надо сграбить сервер, чтобы структура, пока ты ищешь нужное окно, не поменялась. После поиска, ungrab сделать. XGrabServer/XUngrabServer.

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