================================================================================
I3-WOMAN
Two-dimensional workspace manager for i3wm
(c) 2022 Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
================================================================================
Installation
Install all Python dependences (from pip
or your package manager):
- Xlib
- i3ipc
- argparse
- typing
- pyqt5 (optional)
Install osd
Python package from:
http://mj.ucw.cz/sw/
Build woman client (written in C language) by:
make
Symlink client and daemon script to some directory in $PATH
:
ln -s daemon.py ~/bin/i3-woman-daemon
ln -s client ~/bin/i3-woman
See i3.conf
and merge it with your i3 config (or just copy it to ~/.config/i3/config
)
Restart i3wm:
i3-msg restart
User documentation
See i3-woman -H
, i3-woman -h
, i3-woman-daemon -h
and help in GUI.
Developer documentation
Czech language only, sorry.
Rozdělení na klienta a daemonka
Hlavní částí projektu je program daemon.py
. Je možné ho ovládat pomocí
programu client
.
Klient je psaný v C a kompilovaný pomocí make. Pyton má moc pomalý startup a tedy není vhodné ho spouštět pro každé přepnutí workspacu. Daemon se oproti tomu pouští jen jednou za celou životnost window manageru, takže startup je zanedbatelný a je možné využívat výhody vyššího programovacího jazyka v převážné většině kódu.
Klient předává zprávy (příkazy) daemonkovi pomocí X11 protokolu (skrz X server).
Tento způsob je zvolený zejména proto, aby se nemuselo řešit žádné další sdílení
prostředků jako například socketu/potrubí tak, aby různé X sessions měli vlastní
ovládání a přitom se vždy našlo, jak se připojit. Nyní tedy stačí, aby měl klient
správně nastavenou systémovou proměnnou DISPLAY
.
Vedlejším efektem této konstrukce je, že je možné ovládání skrz ssh X tunel
(po připojení vedené z ovládaného počítače někam pryč). Nejsem si jistý, jestli
je to bug, nebo featurka.
Nevýhodou dané konstrukce je absence zpětné vazby. Tedy po odeslání příkazu
není uživatel skrz klienta informován o výsledku.
Zprávy se posílají přidáním textu do attributu root okna (jméno atributu viz
woman/constants.py
). Protokol každý argument posílaného příkazu začne >
a
ukončí \n
. Příkazy se oddělují prázdným řádkem.
Klient umí ověřovat syntaxi posílaných příkazů a stěžovat si, když něco nesedí.
Aby nebyl popis příkazů a jejich argumentů na více místech, tak se část kódu
klienta generuje pomocí Pythonu ze sdílených dat. O celé generování se stará
make, který volá gen_c.py
. Tímto způsobem se do klienta dostane i
uživatelská dokumentace a jméno attributu X11 protokolu.
V další části textu se budeme věnovat již pouze daemonkovi.
Vlákna
Daemonek se skládá z 2 hlavních vláken.
Vlákno X serveru čeká na příkazy od klienta a stará se o jejich vyhodnocení.
Vlákno i3_watch
se stará o zpracovávání událostí generovaných i3wm jako
například focus na workspace, vytvoření a zaniknutí atd. Zejména se stará o
správu sdílených datových struktur popisující aktivní mastery a jejich hlavní
slavy. Tyto data bydlí v modulu woman/shared
a jsou chráněné jedním zámkem
(zámek obsahuje hack pro zabránění daedlocku při komunikaci s vláknem
obsluhující Qt).
V případě, že je aplikace spuštěna s GUI, tak vznikne ještě jedno vlákno, ve kterém běží hlavní smyčka Qt. Z technických omezení pyqt se toto vlákno v tomto případě spouští jako hlavní. Qt vlákno jednak využívá sdílené datové struktury a také od ostatních vláken dostává příkazy. Ty jsou doručované pomocí pyqt signálu/slotu obaleného do třídy Tasker. Tímto způsobem se doručují požadavky na překreslení částí GUI (tedy informace o tom, že nastala nějaká událost). Když nějaké vlákno (zejména vlákno X serveru) chce změnit workspace, tak tímto protokolem požádá Qt vlákno a to nejprve vyrobí screenshot aktuálního workspacu a pak teprve pošle i3wm požadavek na změnu. Když Qt vlákno neexistuje, tak se požadavek přímo pošle i3wm.
Každé vlákno má vlastní spojení s i3wm (implementace pomocí threading.local
).
Komunikace probíhá pomocí socketu a protokolu i3ipc, o jehož zpracovávání se
stará knihovna i3ipc
. Modul woman.lib
obsahuje části kódu, které mohou být
použity v libovolném vlákně.
GUI
Grafické rozhraní je navrhováno na vysokou efektivitu při ovládání z klávesnice i pouze pomocí myši. Proto většina funkcí má zdvojené ovládání pouze za pomocí klávesnice nebo pouze za pomocí myši. Je spíše optimalizováno na pokročilé uživatele využívající rozhraní každý den než na začátečníky držící ho poprvé v ruce.
Grafické rozhraní je postavené na knihovně pyqt5. Ta byla zvolena zejména proto, že je možné ji alespoň částečně ohýbat (i když za cenu zhoršení objektového návrhu) k lepšímu chování pro pokročilé uživatele (například jednoklávesové klávesové zkratky a vlastní layout), umí vyrábět screenshoty a je rozumně rychlá.
Aplikace se skládá z hlavního okna, které obsahuje widget pro každý workspace. Hlavní okno se zejména stará o ošetření většiny klávesových zkratek. Workspacy také obsahují widgety reprezentují stromovou strukturu otevřených oken. Tato struktura se při každém reloadu smaže a vytvoří úplně znovu.