Comme beaucoup d’utilisateurs d’interface graphique, je n’aime pas beaucoup la souris. Cela fait un certain temps que j’effectue la plupart des tâches avec principalement le clavier, en particulier tout ce qui doit être fait rapidement. La gestion des fenêtres en fait partie : on a envie de pouvoir passer très vite d’un logiciel à un autre (le classique Alt-Tab), d’un bureau virtuel à un autre, etc.
Cela fait donc quelques mois que j’utilise mon gestionnaire de fenêtres (quel qu’il soit, en pratique Kwin ou Xfwm selon l’humeur, mais à mon stage j’utilise Metacity) principalement avec le clavier. De là vient l’idée naturelle : pourquoi ne pas utiliser un gestionnaire de fenêtre pensé pour être utilisé avec le clavier ? Ce serait certainement encore plus adapté.
J’ai donc envisagé plusieurs alternatives (wmii, etc.), sans les tester (la flemme), et j’ai finalement choisi XMonad. C’est hype, c’est minimaliste, c’est codé dans un langage que j’aime bien (Haskell), bien conçu (Zipper et tout le tralala), bien documenté, ils insistent sur le fait d’avoir peu de lignes de code (j’aime bien), et ils essaient d’exprimer formellement et de vérifier des propriétés de leur programme (pas avec Coq, on ne peut pas tout avoir, mais avec QuickCheck).
J’ai donc fait l’effort d’installer XMonad, de lire la documentation de base (je n’ai retenu au départ que cinq raccourcis). Il y a quelques glitches (par exemple au lancement emacs n’occupe pas tout l’espace de sa fenêtre), mais qui n’en a pas ?
J’ai pris un peu de temps pour le configurer, en pratique ça veut dire installer et utiliser deux petits programmes qui « font une seule chose et le font bien », conseillés par la documentation XMonad :
- xmobar
une petite barre de tâches que l’on configure en lui envoyant des infos sur l’entrée standard, simplissime.
- dmenu
un outil de lancement de programme tout simple (on tappe le nom de l’exécutable jusqu’au moment où on peut auto-compléter, et on fait « Entrée ») ; écrit par les gens de suckless, qui sont cools et aiment Plan9.
Je me suis fait un fichier de configuration XMonad qui résume tout ça, au cas où ça vous intéresse. Dans la suite de ce billet, je détaillerai cette configuration. Ça n’est certainement pas une référence sur l’utilisation de ces outils, j’ai d’ailleurs sans doute fait une ou deux bêtises dans ces configurations, mais le but est de montrer que c’est plutôt facile, au cas où ça motiverait des vocations.
La base de la base
Pour installer XMonad, on peut télécharger la version de développement du code et l’installation à la main, ou passer par le gestionnaire de paquets de son système d’exploitation. La seconde version est évidemment plus simple.
Dans tous les cas, on se retrouve avec une installation plutôt de
base, et en particulier un fichier de configuration essentiellement
vide. Pour lancer XMonad, il suffit de partir d’une session X sans
gestionnaire de fenêtres (par exemple en ayant lancé xinit depuis un
terminal) et de lancer xmonad. Comme tout repose sur le clavier, il
faut avoir à l’avance une idée des raccourcis ; man xmonad est là
pour ça. D’après mon expérience, mod-j (changer de fenêtre),
mod-shift-p (lancer une commande) et mod-space (changer de mode
d’affichage) sont les seules commandes à retenir pour débuter.
mod-j, mod-k | passer le focus à la fenêtre précédente/suivante |
mod-[1..9] | changer de bureau virtuel |
mod-shift-[1..9] | déplacer la fenêtre sous le focus vers un bureau virtuel |
mod-space | changer d’agencement des fenêtres |
mod-p | lancer dmenu
|
mod-shift-p | lancer une commande |
L’inconvénient du fichier de configuration minimaliste, c’est qu’il faut rajouter tout ce qu’on veut configurer en plus. On peut le faire en lisant la doc mais c’est assez délicat : je trouve qu’on s’en sort beaucoup plus vite en bidouillant un exemple qui fonctionne déjà. J’ai donc téléchargé le modèle de configuration XMonad, un long fichier Haskell qui fait la même chose que la configuration par défaut, mais plus bruyamment. On peut alors jeter un coup d’oeil aux différentes parties de la conf, et bidouiller ce qui nous plaît.
Le reste du post est organisé comme une description du diff entre ma
configuration XMonad et ce modèle (template) fourni : un bout du
diff, et un commentaire sur la signification de la chose, et
éventuellement les informations et les fichiers liés.
Imports sans grand intérêt
+import XMonad.Layout.NoBorders
+import XMonad.Hooks.DynamicLog
+import XMonad.Hooks.ManageDocks
Trois imports de bibliothèque en haut du fichier de configuration. Certaines parties de la configuration que j’ai changées dépendent de ces imports. Vous allez voir.
Dans XMonad, la fenêtre qui a le focus est entourée d’une fine et
élégante bordure rouge. NoBorders permettra de configurer les
dispositions de fenêtres (Layout) pour que les fenêtres en mode
plein écran ne soient pas entourées : une telle fenêtre étant seule
à l’écran, on se doute bien qu’elle a le focus.
ManageDocks permettra de réserver un peu d’espace d’affichage pour la
barre de tâches xmobar. DynamicLog servira à envoyer en continu à cette
barre de tâches des informations sur le système.
Changement du terminal par défaut
-- The preferred terminal program, which is used in a binding below and by
-- certain contrib modules.
--
-myTerminal = "xterm"
+myTerminal = "gnome-terminal"
Attention à ne pas confondre les -, + du diff, et les -- qui
dénotent un commentaire Haskell.
J’utilise gnome-terminal par défaut, parce qu’il affiche bien
l’unicode (j’utilise beaucoup de lettres grecques dans mes programmes)
et possède des tabs, ce qui reste bien pratique. Les gens de
suckless, que j’ai déjà mentionnés car ils s’ocupent de dmenu, ont
un outil qui s’appelle tabbed, qui permet en théorie d’apporter des
tabs de l’extérieur à des programmes individuels, c’est sympa mais
j’ai la flemme d’essayer.
Choix de la touche mod pour les raccourcis
-myModMask = mod1Mask
+myModMask = mod3Mask
La touche nommée mod dans la parlance XMonad est la touche centrale,
utilisée pour la grande majorité des raccourcis claviers. C’est une
touche abstraite, et on peut choisir la touche physique du clavier
à laquelle elle correspond. On pourra l’associer par exemple à la
touche « Contrôle » pour avoir des raccourcis de la forme ctrl+j, ou
à la touche « Alt » pour avoir alt+j.
En réalité, l’association n’est pas si directe, elle passe par le
serveur X, qui reçoit de votre clavier des keycodes (« code des
touches » ?), et les transforme en keysyms (« symbole des
touches » ?), qui sont ensuite envoyés aux applications. Dans XMonad,
on choisit quel keysym représentera la touche mod, mais on peut
aussi changer la touche en amont en s’attaquant directement à la
traduction des keycodes, qui est faite par xmodmap, un outil du
serveur X.
C’est d’ailleurs ce que je fais : j’ai mis le symbole mod3 comme
touche mod dans XMonad, mais j’utilise xmodmap pour envoyer la
touche « Caps lock » vers le symbole mod3. C’est fait dans un petit
script, que j’ai nommé startxmonad.sh, qui appelle xmodmap juste
avant le lancement de xmonad :
setxkbmap us intl
xmodmap -e "remove Lock = Caps_Lock"
xmodmap -e "add Mod3 = Caps_Lock"
xmonad
On charge la disposition par défaut du clavier, on réassigne la touche
Caps_Lock au keysym Mod3, et le tour est joué.
Bureaux virtuels
-myWorkspaces = ["1","2","3","4","5","6","7","8","9"]
+myWorkspaces = with_tags ["web", "bibli", "code", "redac"]
+ where with_tags li = li ++ map show [(1 + length li)..9]
XMonad a l’équivalent des bureaux virtuels, qu’il appelle
workspaces. On peut se déplacer dans le bureau virtuel numéro N avec
le raccourci mod-N (mod-1, mod-2…). Par défaut, le nom de
chaque workspace est son numéro, et c’est ce que ma barre de tâches
affiche. Ma modification sert à donner aux quatre premiers bureaux des
noms plus mignons et sémantiques, qui reflètent l’utilisation que j’en
fait. La ligne where sert à montrer que je maîtrise le Haskell
à fond, et que les bureaux suivants gardent leur numéro jusqu’à 9.
Légères modifications des dispositions des fenêtres
-- The available layouts. Note that each layout is separated by |||,
-- which denotes layout choice.
--
-myLayout = tiled ||| Mirror tiled ||| Full
+myLayout = avoidStruts (tiled ||| Mirror tiled ||| noBorders Full)
Comme dit au moment des imports, XMonad permet de choisir entre
plusieurs dispositions de fenêtres différentes. J’ai repris les modes
déjà présents (un mode plein-écran, Full, et deux modes avec une
fenêtre principale, occupant la moitié de l’écran, et des fenêtres
secondaires), en la modifiant légèrement. noBorders retire l’encadré
rouge du mode plein écran, et avoidStruts sert à réserver de
l’espace pour la barre de tâches ; je ne l’ai pas inventé tout seul, je
l’ai lu dans la documentation.
Ajout de cas particuliers de fenêtres flottantes
myManageHook = composeAll
[ className =? "MPlayer" --> doFloat
, className =? "Gimp" --> doFloat
+ , className =? "Display" --> doFloat
+ , className =? "XVroot" --> doFloat
, resource =? "desktop_window" --> doIgnore
, resource =? "kdesktop" --> doIgnore ]
Par défaut, XMonad essaie de faire en sorte que chaque fenêtre occupe
le maximum d’espace disponible. C’est chouette en général, mais ça
peut devenir très laid quand on veut par exemple voir une image, et
qu’elle est redimensionnée, sans respect des proportions, pour remplir
parfaitement la place libre entre les fenêtres existantes. doFloat
sert à rendre certaines fenêtres flottantes (non redimensionnées), et
className =? fait visiblement un test sur la classe de la fenêtre
X. Je ne connais pas les subtilités des fenêtres X, mais il y avait
des lignes déjà présentes pour montrer l’exemple, et j’ai lu sur
internet qu’il fallait utiliser l’utilitaire xprop pour récupérer la
classe d’une fenêtre X. J’ai rajouté display et xv, mes
visionnaires d’image en ligne de commande préférés (saviez-vous que
display d’ImageMagick gère même le format de graphes dot quand il
est compilé avec les bonnes options ?), et ça marche.
Configuration de xmobar
-- Run xmonad with the settings you specify. No need to modify this.
--
-main = xmonad defaults
+main = xmonad =<< xmobar defaults
main est la grosse fonction de Haskell, le moment où on lance
carrément XMonad et tout. Je l’ai modifiée comme suggéré par la
documentation de DynamicLog, pour qu’elle envoie des
informations à xmobar, ma barre de tâches.
xmobar est un petit programme qui affiche une barre de tâches, lui
aussi écrit en Haskell. Il faut le configurer indépendamment,
concrètement j’ai mis le fichier suivant sous le nom
~/.xmonad/xmobarrc :
Config { font = "xft:DejaVu Sans-8:"
, bgColor = "black"
, fgColor = "grey"
, position = Top
, lowerOnStart = True
, commands = [ Run StdinReader
, Run Network "eth0" ["-L","0","-H","32","--normal","green","--high","red"] 10
, Run Network "eth1" ["-L","0","-H","32","--normal","green","--high","red"] 10
, Run Cpu ["-L","3","-H","50","--normal","green","--high","red"] 10
, Run Memory ["-t","Mem: <usedratio>%"] 10
, Run Date "%a %b %_d %Y %H:%M:%S" "date" 10
]
, sepChar = "%"
, alignSep = "}{"
, template = " %StdinReader% }{ %cpu% | %memory% | <fc=#ee9a00>%date%</fc>"
}
Je l’ai encore une fois adapté d’une configuration donnée dans la
documentation. En gros, la disposition de la barre ressemble à ce qui
est marqué dans template, et les définitions / configurations sont
celles du champ commands. La partie StdinReader lit sur l’entrée
standard, c’est-à-dire les informations données par xmonad, et
affiche donc, sans que je lui ai rien demandé, mes bureaux virtuels en
mettant en valeur celui sur lequel je me trouve, le nom de la
disposition de fenêtres courantes, et le titre de la fenêtre qui a le
focus. Le reste, c’est moi qui l’ai configuré comme un grand, ce sont
des stats sur l’utilisation du CPU, de la mémoire (ça sert à rien mais
c’est classe), et l’heure qu’il est (très utile par contre).
Utilisation avec Gnome
À mon stage, j’utilise une machine debian avec Gnome. Je pourrais installer autre chose, mais je n’aime pas beaucoup faire de l’administration sur mes heures de travail, et j’avais envie d’essayer pour voir comment ce bureau progresse.
À l’occasion d’un changement de machine, j’ai essayé la combinaison
Gnome+Xmonad : utilise Gnome comme gestionnaire de bureau, mais avec
Xmonad à la place de Metacity comme gestionnaire de fenêtre. C’est
très facile à mettre en place, la démarche est expliquée dans la
documentation. J’ai utilisé la solution la plus simple, à savoir
créer /usr/share/applications/xmonad.desktop et
/usr/share/xsessions/xmonad.desktop, et choisir Xmonad depuis GDM.
Ça donne un environnement assez agréable : la barre de tâches et la
plupart des utilitaires Gnome sont actifs, ce qui est pratique pour
avoir par exemple l’applet NetworkManager depuis notre session Xmonad
(on pourrait peut-être coder quelque chose d’équivalent pour
xmobar). mod-p appelle le lanceur d’application Gnome (que je
trouve en réalité moins agréable que dmenu car plus intrusif), donc
l’intégration est plutôt bonne.
Pour mon portable, qui a un petit écran 13", je préfère la sobriété et
la finesse d’une xmobar configurée à la spartiate, mais je pense que
les amateurs de gnome seraient satisfaits de la combinaison
Gnome+Xmonad.
Multi-écran
Toujours à mon stage, j’utilise deux écrans. XMonad a, de base, un bon support du multi-écran : il met un bureau virtuel sur chaque écran, et on peut facilement changer le focus d’un écran à l’autre ou déplacer des applications.
Le mot de la fin
Voilà, j’ai fait le tour de ma configuration XMonad. C’est vraiment pas très compliqué. Est-ce que ça vaut le coup ?
Ce dont j’avais peur, c’est que ces outils (les tiling window managers) soient trop élite pour moi : le truc qu’il faut comprendre en profondeur pour pouvoir utiliser, et après on est super-productif de la mort, mais il faut commencer par se farcir des kilomètres de doc. En pratique ce n’est pas du tout l’expérience que j’ai vécue avec Xmonad, j’ai juste retenu deux ou trois raccourcis indispensables et bidouillé un peu la configuration en copiant-collant lâchement ce que je trouvais sur le net, et en quelques essais j’ai quelque chose de simpliste qui me convient bien.
Je pense que je suis essentiellement aussi productif qu’avant, avec Kwin ou Xfwm, et c’est vrai que je m’embête moins à agrandir mes fenêtres, les changer de bureau ou d’écran, etc. L’avantage principal reste le sentiment satisfaisant et rassurant d’utiliser un outil simple, que l’on peut modifier si l’on veut, et adapté à l’usage qu’on en fait.
# haveo
18.07.10, 17:06.
# haveo
18.07.10, 17:23.
# xa
18.07.10, 18:08.
# drk-sd
18.07.10, 19:09.
Moi j’ai testé le multi-écran sous wmii, ça marche pas. Donc les rares fois où j’en avais besoin j’utilisais xmonad justement. Mais j’ai jamais eu la motivation pour configurer le truc. Du coup pour une utilisation quotidienne je suis resté à wmii qui démande un minimum de configuration (j’ai changé de touche mode et de term) et me convient parfaitement.
Voilà voilà.
# Cygal
21.07.10, 12:32.
# mota
21.07.10, 14:48.