úterý 21. února 2012

Další hrátky s okny

Již jsem tu párkrát zmínil a použil program wmctrl, který se dá do Ubuntu nainstalovat ze základních repozitářů. Součástí systémů založených na X serveru bývá již v základní instalaci pár dalších zajímavých nástrojů pro manipulaci s okny...

Pokud potřebujete například kliknutím myši identifikovat okno, které se nachází pod kurzorem myši, můžete použít následující příkaz:

xwininfo

Po spuštění se kurzor myši změní na křížek a očekává se, že kliknete na okno, o kterém se chcete něco dozvědět. Výpis může vypadat následovně:

xwininfo: Window id: 0x5800003 "Kalkulačka"

Absolute upper-left X: 752
Absolute upper-left Y: 423
Relative upper-left X: 752
Relative upper-left Y: 423
Width: 304
Height: 329
Depth: 24
Visual: 0x21
Visual Class: TrueColor
Border width: 0
Class: InputOutput
Colormap: 0x20 (installed)
Bit Gravity State: NorthWestGravity
Window Gravity State: NorthWestGravity
Backing Store State: NotUseful
Save Under State: no
Map State: IsViewable
Override Redirect State: no
Corners: +752+423 -224+423 -224-272 +752-272
-geometry 304x329+752+423


Dozvíte se tedy, mimo jiné, velikost a umístšní okna na obrazovce a identifikační číslo okna. Nejzajímavější bude dnes právě id okna, podle něj můžete na okno zacílit další nástroje. Vypreparovat čistě ID okna půjde tímto příkazem:

xwininfo | grep -Eom 1 '0x[0-9a-f]+'

Aby bylo jasno: přepínač -E pro regulární výrazy,  -o vypíše pouze řetězec hledanému výrazu odpovídající, a -m určuje hloubku hledání, tedy s parametrem 1 se zastaví na prvním nalezeném řetězci a další již nehledá.

Základním úkolem může být okno sejmout:

xkill -id 0x5800003

Xkill vyhledá proces, který okno dané identifikátorem vlastní a ten zamorduje. Tedy pošle mu nějaký kill signál, předpokládám, že 15, tedy TERM. Ten proces ovšem najít nemusí, protože hlásit informace tohoto typu není pro aplikace povinné a fůra z nich drží svá okna v prostředí X serveru inkongínto (určitě tušíte, co jsem tím chtěl říci ;) ). Xkill umí i sám zaměřit okno myší, stejným způsobem, jako xwininfo, a tak stačí napsat samotný příkaz xkill a kliknutím okno, resp. jeho proces, ukončíte. Tím zavřete všechna okna, která procesu (většinou proces == aplikace) patří.
Ne vždy je potřeba ukončit proces vlastnící okno, například správce souborů Nautilus může mít oken mrak, včetně Pracovní plochy. Pak můžete použít zmíněný wmctrl, který umí komunikovat se správcem oken a umí zařídit to, co se stane, když kliknete na křížek pro zavření okna v jeho dekoraci.

wmctrl -ic 0x5800003

Ovšem i wmctrl zaměřovač oken implementuje a tak je možné ho použít pro předchozí aplikaci přímo:

wmctrl -c :SELECT:

No, tady by se dalo říct, že toto počínání je absurdní, když zrovna tak můžete kliknout rovnou na příslušné tlačítko v dekoraci okna. Ale co když okno dekoraci nemá... a co když má zakázaný fokus, takže na něj nejde přepnout a zavřít ho klávesovou zkratkou...

V automatizaci procesů (myslím tím nějaké to skriptování) se vám může hodit kliknutím si zapsat okno/process a naložit s ním později, třeba na základě nějaké jiné události. Chcete-li si podle identifikátoru okna dohledat číslo procesu, pokud tedy je k mání, můžete použít další X program:

xprop -id 0x5800003 _NET_WM_PID | grep -Eo '[0-9]+'

Xprop vypíše plno informací, dokonce vám do terminálu vykreslí i ikony k oknu patřící. Je potřeba dolovat, tedy parsovat výstup podle potřeby. Uvedený příkaz vyplivne čistý PID, tedy číslo procesu.

Ale xprop také implementuje zaměřovač oken a tak se k PID dostanete jen jedním příkazem. Dobře, dvěma zrourovanými, filtrovat je třeba:

xprop _NET_WM_PID | grep -Eo '[0-9]+'

Drobný příklad, jak na základě zavření uživatelem vybraného okna, tedy vlastně ukončení procesu kterému okno patří, spustit nějaký příkaz. Zde jen zprávu:

#!/bin/bash

pid=`xprop _NET_WM_PID | grep -Eo '[0-9]+'`
if [ $pid ]; then echo "Čekám na smrt procesu $pid, dám vědět..."
    while [ -e /proc/$pid ]; do sleep 1; done
    echo "Proces $pid právě zemřel!"
  else echo "Proces, kterému vybrané okno patří, nebyl nalezen"
fi

Čekání čistě na zavření okna bez spojitosti s procesem, kterému patří, by mohl vypadat třeba následovně:

#!/bin/bash

win_id=`xwininfo | grep -Eom 1 '0x[0-9a-f]+'`
if [ $win_id ]; then echo "Čekám na smrt okna $win_id, dám vědět..."
    while xprop -id $win_id &>/dev/null; do sleep 1; done
    echo "Okno $win_id bylo právě zavřeno!"
  else echo "Vybrané okno nebylo identifikováno"
fi

Mezi další základní X příkazy patří i xlsclients, který vypíše seznam všech oken, s přepínačem -l vypíše i podrobnosti jako id okna, jeho jméno, jméno ikony (kterou najdete v adresáři /usr/share/pixmap/) atd.

S okny se dá dělat fůra věcí, určitě vás toho spousta napadne a z uvedeného si vyvodíte potřebné závěry. Když si vzpomenu na něco nezapomenutelného napíšu další články.

Ohledně wmctrl a prostředí Compizu jsem psal již dříve, najdete tam další použití tohoto programu:
Zachování rozmístění oken při přepínání mezi Metacity a Compizem

Další legraci nabízí ovládání myši:
Skriptem na myš

2 komentáře:

  1. Díky za článek, zajímavé čtení!

    OdpovědětVymazat
  2. Díky za info, rádo se stalo :)

    OdpovědětVymazat

Zkuste prosím při komentováni používat místo volby Anonymní volbu Název/adresa URL, kde vyplníte nějakou přezdívku, adresu zadávat nemusíte. Vědět, které příspěvky jsou od jednoho člověka, je fajn. Díky.

Pokud by se vám náhodou odeslaný komentář na stránce nezobrazil, vytáhnu ho z koše hned jak si toho všimnu. I Google spam filter se občas sekne.