Nowe posty

Autor Wątek: Jak ustawić WM_NAME i WM_CLASS?  (Przeczytany 4505 razy)

arctgx

  • Gość
Jak ustawić WM_NAME i WM_CLASS?
« dnia: 2011-04-07, 20:23:08 »
W swoim konfigu Openboksa chciałbym dla przykładu nadać oknom przeglądarki Geeqie odmienne własności, np. raz otwieranie się w bieżącej przestrzeni roboczej, innym razem w ustalonej na sztywno.

Do rozróżnienia mogę użyć WM_NAME, WM_CLASS czy WM_ROLE: wartości dających się odczytać za pomocą
xprop WM_CLASS
lub w toporniejszych wypadkach (np. Firefox)
xwininfo -root -tree | grep co_wyobraźnia_zwęszy
Mało która aplikacja pozwala ustawić na starcie te ciągi znaków. Dobrym wyjątkiem są emulatory terminali.

Jakiś czas szukam polecenia, które pozwoliłoby ustawić te wartości dla okna, które już istnieje lub ma się dopiero pojawić wraz z uruchomionym programem. Niczego też nie wiem o lokalnych zmiennych powłoki, które miałyby służyć do tego.

Bogaty w funkcje wmctrl nie ma takiej możliwości. Wypróbowałem
wmctrl -i -r 0x01c0001f -N KKK
xprop -id 0x01c0001f WM_CLASS
# gdzie 0x01c0001f wziąłem z
wmctrl -l
- zmienił się tylko tytuł okna.

Problem leży daleko od serwera Xorg, ale nie mam lepszego pomysłu na temat wyboru działu.

Offline vanhelzing

  • Users
  • Prawie jak Guru
  • ****
  • Wiadomości: 314
    • Zobacz profil
Jak ustawić WM_NAME i WM_CLASS?
« Odpowiedź #1 dnia: 2011-04-08, 10:22:58 »
Jeżeli chcesz zmienić parametr WM_CLASS, możesz to zrobić w c:

wmclass.c
#include 

Display *dpy;
Window w;

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

XClassHint ch;

ch.res_name = argv[2];  // nazwa aplikacji
ch.res_class = argv[3];   // klasa aplikacji

dpy = XOpenDisplay (NULL);

sscanf (argv[1], "0x%X", &w);  // konwersja na liczbe

XSetClassHint (dpy, w, &ch);

XCloseDisplay (dpy);

return (0);
}
Kompilujesz przez
gcc -lX11 wmclass.c -o wmclass
Pierwszy parametr to identyfikator okna (szesnastkowo), drugi to nazwa aplikacji i trzeci to klasa aplikacji.
wmclass 0x0000001 "Name" "Class"
Jeżeli chcesz dodatkowo zmienić tytuł okna to musisz dodać jeszcze funkcję XStoreName(). Nie wiem czy o to Ci chodzi, dlatego nie chciałem komplikować kodu i darowałem sobie sprawdzanie błędów i rzutowanie typów.

arctgx

  • Gość
Jak ustawić WM_NAME i WM_CLASS?
« Odpowiedź #2 dnia: 2011-04-08, 18:15:14 »
pid2wid() { 
wmctrl -p -l | while read wid x pid reszta; do
[[ "$pid" == "$1" ]] && {
echo $wid
return 0;
}
done
return 1;
}
pkill cairo-clock
cairo-clock 2>/dev/null & {
sleep 1
wid="$(pid2wid ${!})"
        ./wm ${wid} [b]x y[/b]
xprop -id "${wid}" WM_CLASS
}
daje WM_CLASS(STRING) = "x", "y". Dziękuję zatem - wydawałoby się, że kawałek problemu mamy z głowy. Fragment konfigu Openboksa
        
                3
       
oznacza ładowanie okna z klasą Geeqie na pulpicie nr 3 (wmctrl, licząc od zera, pokazuje 2).

Odpalam Geeqie, nadaję mu "x", "y", przenoszę na inny pulpit, restartuję Openboksa. Geeqie wskakuje na pulpit 3, ignorując WM_CLASS(STRING) = "x", "y".

Może Openbox bierze te nazwy z innych zmiennych:
$ xprop -id 0x01600003 | grep -Ei 'geeqie|WM_CLASS\\('
_NET_WM_VISIBLE_ICON_NAME(UTF8_STRING) = "Geeqie"
_NET_WM_VISIBLE_NAME(UTF8_STRING) = "Geeqie"
_OB_APP_CLASS(UTF8_STRING) = "Geeqie"
_OB_APP_NAME(UTF8_STRING) = "geeqie"
_OB_APP_ROLE(UTF8_STRING) = "geeqie"
WM_WINDOW_ROLE(STRING) = "geeqie"
WM_CLASS(STRING) = [b]"x", "y"[/b]
WM_ICON_NAME(STRING) = "Geeqie"
_NET_WM_ICON_NAME(UTF8_STRING) = "Geeqie"
WM_NAME(STRING) = "Geeqie"
_NET_WM_NAME(UTF8_STRING) = "Geeqie"
Napisałem wyżej "kawałek problemu", bo w normalnym użyciu nie chciałbym za każdym razem restartować menedżera okien, a uruchamiać z ustawionymi już prędzej tymi nazwami.

Bash i masa takich naturalnych zewnętrznych narzędzi rozleniwiają mnie w poznawaniu bibliotek i samego języka C (chyba z wyjątkiem używanej przez powłokę GNU libc). Tu jest dość wyjątkowa sytuacja - cały czas jestem gotów podejrzewać, że źle szukam i to potrzebne mi narzędzie siedzi sobie gdzieś w repozytorium. Chciałem uprzedzić, że próba przeróbki Twojego kodu wydaje się przekraczać moje możliwości (szczególnie wiedzę, gdzie trafnie szukać) - przynajmniej gdybym, powiedzmy, miał dziś zrozumieć całość włącznie z zainkludowanymi definicjami.

Chyba łatwiej (mi przynajmniej) będzie napisać skrypt przenoszący z pomocą wmctrl świeżo otwarte okno na wybrany pulpit.