Un petit tour avec XMonad
Posted on 09 Dec 2009 by David in geek, linux
Depuis quelques temps, sous Linux, j'utilisais principalement Enlightenment DR17 comme window manager. Il me permettait de configurer aux petits oignons mon environnement desktop : avec les raccourcis clavier pour manipuler les fenêtres, les fenêtres attachées à un workspace particulier avec la taille, la position, ... sauvegardés. Parmi la configuration d'Enlightenment, un petit module m'intriguait : le module Tiling.
En effet, j'avais déjà entendu parlé des Tiling Window Manager lorsque j'étais encore à l'école mais je n'avais jamais pris le temps de creuser le sujet. Ce coup-ci, avec ce module, je me suis dis qu'il fallait essayer, surtout que je restais avec le window manager que je maitrisais. Seulement voilà, le bousin est pas vraiment stable, et ne propose que peu de fonctionnalités (à ce moment là elles me suffisaient largement).
Qu'est-ce qu'un Tiling Window Manager et pourquoi XMonad ?
Avant de continuer, revenons sur le principe du Tiling Window Manager : un window manager, c'est le truc qui dessine un cadre autour des fenêtres de l'application et qui affiche généralement un bouton pour fermer, agrandir et réduire la fenêtre, et qui permet de déplacer et redimensionner cette même fenêtre. Sous Gnome, c'est Metacity par défaut, sous KDE, c'est KWin. Et pour ceux qui ne le savait pas, on peut choisir celui qui nous convient le mieux :).
Un Tiling Window Manager a de particulier qu'il est en général dépourvu de cadre et de bouton et dimensionne les fenêtres automatiquement selon un layout configuré par nos soins en prenant le plus d'espace possible (ie. il n'y a pas d'espace non utilisé par une fenêtre). De plus, il est plus adapté à une utilisation au clavier qu'à la souris (n'ayez pas peur, avec 3 ou 4 raccourcis, le bénéfice est déjà accessible).
Après m'être apperçu que le module Tiling d'Enlightenment était pas vraiment stable, je me suis dit que ce serait pas mal de pousser un peu plus l'expérimentation de ces fameux Tiling Window Manager (dont on m'avait d'ailleurs vanté les mérites).
Première étape donc, lequel choisir ? Xmonad, Awesome ou encore Ion ? J'avoue ne pas avoir fait une étude très approfondie pour les comparer et un sentiment très subjectif me poussait vers Xmonad : il y a de la doc, des exemples de fichiers de conf, les avis sur le web sont vraiment bon et puis il est écrit en Haskell, ça faisait un moment aussi que je voulais jeter un oeil à Haskell ;).
La prise en main
Avant de regarder la configuration, je commence par lancer la bête en utilisant mon fichier ~/.Xsession :
#!/bin/sh
exec xmonad
Une fois la session ouverte, on se retrouve avec un écran vide et on ne sait plus trop quoi faire :).

Le premier raccourci indispensable est celui pour ouvrir un terminal (la syntaxe que j'utiliserai pour décrir un raccourci clavier est : M = Alt, C = Ctrl, S = Shift) : M-S-Enter.
Si on lance un terminal, celui-ci prend automatiquement tout l'espace sur l'écran :

Rien d'extraordinaire, mais voyons ce qu'il se passe si l'on ouvre un second terminal (faut pas s'inquiéter, après on ouvrira autre chose que des terminaux ;) ) toujours avec M-S-Enter :

XMonad cette fois-ci découpe l'écran en 2 zones égales. Par défaut, la fenêtre active devrait être dans un fin cadre rouge (sur mes screenshot, il sera bleu clair parce que ce n'est plus la config par défaut).
Le second raccourci à connaître est M-TAB pour changer de fenêtre active, celui-là il est facile et bien connu :).
Si on continue à ouvrir des terminaux et un Emacs, voilà ce que ça donne :

La fenêtre de gauche garde la moitié de l'écran, les autres fenêtres se partagent l'autre moitié. La fenêtre Emacs qui prend la moitié de l'écran est la fenêtre principale. Le raccourci M-Enter permet de sélectionner une autre fenêtre principale (après lui avoir donné le focus avec M-TAB) qui viendra se placer dans la zone de gauche :

Ce placement des fenêtres est défini par un layout. Le raccourci M-SPACE permet de switcher parmis les layouts. Celui qu'on vient de voir s'appelle Tall. Par défaut, il y en a 2 autres qui sont configurés lorsque l'on switch :
Mirror Tallqui est identique àTallmais en horizontal :

- et
FullScreenqui comme son nom l'indique place la fenêtre principale en plein écran.
Il en existe plein d'autres qui sont customizable simplement.
Il reste deux raccourcis qui peuvent aider (bon OK, on doit avoir dépasser les 4 raccourcis à connaitre maintenant :) ), qui sont : M-[1-9] qui permet de switcher d'un workspace à un autre (ie. au 1er avec M-1, au second avec M-2, ...), M-S-[1-9] qui permet d'envoyer une fenêtre sur un autre workspace.
Voilà pour la prise en main de XMonad, reste maintenant à le configurer pour qu'il réponde exactement à notre besoin.
La configuration
Pour configurer XMonad, il va falloir faire un petit peu d'Haskell et là, ça fait mal quand on connait pas Haskell. Ce n'est pas aussi évident que je l'imaginais ! Heureusement pour nous, il y a beaucoup d'exemples et pas mal de doc qui m'ont permi de faire tout ce que je voulais.
Voici juste un petit panorama des fonctionnalités que j'utilise :
Placer les fenêtres sur un workspace suivant l'application :
myManageHook = composeAll [ className =? "Gimp" --> doShift "9:gimp" , className =? "Vncviewer" --> doFloat , className =? "MPlayer" --> doShift "6:video" , className =? "xine" --> doShift "6:video" , className =? "Gajim.py" --> doShift "1:im" , className =? "psi" --> doShift "1:im" , className =? "Pidgin" --> doShift "1:im" , className =? "Empathy" --> doShift "1:im" , className =? "Firefox" --> doShift "2:web" , (className =? "Firefox" <&&> resource =? "Dialog") --> doFloat , className =? "Emacs" --> doShift "3:dev" , className =? "Rhythmbox" --> doShift "5:music" , className =? "Amarok" --> doShift "5:music" , className =? "Banshee" --> doShift "5:music" , className =? "Transmission" --> doShift "7:download" , className =? "stalonetray" --> doIgnore , isFullscreen --> doFullFloat , isSplash --> doIgnore ] where copyToWss ids win = map (copyWindow win) ids isSplash = isInProperty "_NET_WM_WINDOW_TYPE" "_NET_WM_WINDOW_TYPE_SPLASH"
Avoir un thème personnalisé :
myTheme = defaultTheme { fontName = myFont, activeColor = "#343434", activeTextColor = "#2B7598", activeBorderColor = "#2B7598", inactiveColor = "#343434", inactiveTextColor = "#FFFFFF", inactiveBorderColor = "#343434" }
Avoir un layout personnalisé suivant le workspace (et donc l'application) :
... , layoutHook = onWorkspace "9:gimp" gimpLayout $ onWorkspace "1:im" imLayout $ onWorkspace "2:web" webLayout $ onWorkspace "6:video" videoLayout $ onWorkspace "8:log" logLayout $ avoidStruts $ layoutHook gnomeConfig ... where gimpLayout = avoidStruts $ withIM (0.11) (Role "gimp-toolbox") $ reflectHoriz $ withIM (0.15) (Role "gimp-dock") $ tabbed shrinkText myTheme videoLayout = smartBorders (tabbed shrinkText defaultTheme) logLayout = simpleDeco shrinkText myTheme $ avoidStruts $ Grid ||| Full ||| Accordion imLayout = avoidStruts $ withIM (1%6) (Or (Or (Or (Role "psimain") (Role "roster")) (Role "buddy_list")) (Role "contact_list")) (tabbed shrinkText myTheme) webLayout = avoidStruts $ tabbed shrinkText myTheme ||| Accordion ||| Grid
Dans l'exemple précédent, l'
imLayoutplace la liste de contacts sur la gauche avec une taille fixée (withIM (1%6)) et les autres fenêtres dans l'espace restant avec des onglets (tabbed shrinkText myTheme).Autre exemple, le
webLayout(où Firefox est envoyé) utilise un layout avec des onglets, en accordéon ou en grille.Et des raccourcis clavier personnalisés :
[ ("M-l", spawn "gnome-screensaver-command -l") , ("M-S-q", spawn "gnome-session-save --gui --logout-dialog") -- moving workspaces , ("M-<Left>", prevWS ) , ("M-<Right>", nextWS ) , ("M-S-<Left>", shiftToPrev ) , ("M-S-<Right>", shiftToNext ) , ("M-s", sshPrompt myPromptConfig ) , ("M-m", manPrompt myPromptConfig ) , ("M-S-t", themePrompt myPromptConfig ) , ("M-S-g", windowPromptGoto myPromptConfig ) , ("M-S-b", windowPromptBring myPromptConfig ) , ("M-S-x", xmonadPrompt myPromptConfig ) , ("M-x", runOrRaisePrompt myPromptConfig ) , ("M-C-f", spawn "firefox" ) , ("M-C-e", spawn "e" ) , ("M-C-S-e", spawn "emacs" ) , ("M-C-r", spawn "emacsclient -n -e '(make-remember-frame)'" ) , ("M-C-m", spawn "emacs" ) ]
Dans les screenshots précédent, on voit que j'utilise la barre Gnome comme zone de notification et qui affiche le nom de mes workspaces Xmonad ainsi que le titre de la fenêtre qui a le focus. Pour cela, j'ai développé une petite applet Gnome en Python (forcément ;) ) car je n'arrivais à faire marcher celle-ci. Il reste à envoyer ces infos par XMonad via DBus :
Les sources de l'applet sont dispos par ici. Ce n'est pas encore du tout propre ! Il me reste encore à faire une vraie procédure d'install et un code un peu plus propre :).xmonadAppletLogHook = myLogHook $ defaultPP { ppOutput = \ str -> do let str' = "<span>" ++ str ++ "</span>" spawn("dbus-send --session --type=signal /org/xmonad/Log org.xmonad.Log.Update string:'" ++ str' ++ "'") return () , ppTitle = pangoColor "#2B7598" . shorten 50 , ppCurrent = pangoColor "#2B7598" . wrap "[" "]" , ppVisible = pangoColor "#2B7598" . wrap "(" ")" , ppHidden = wrap " " " " , ppUrgent = pangoColor "red" } pangoColor :: String -> String -> String pangoColor fg = wrap left right where left = "<span foreground=\"" ++ fg ++ "\">" right = "</span>"
- dernière feature, qui pour moi est super importante : une bonne gestion du multi-écran. Je m'explique, avec beaucoup de window manager (y compris ceux de Windows et MacOSX), je trouve la gestion du multi-écran complètement pourrie. Elle ne consiste qu'à agrandir l'espace de travail du premier écran avec juste une gestion du maximize des fenêtres pour que celles-ci restent sur un seul écran. Au-delà, si les écrans n'ont pas la même taille, il existe une zone non visible où les fenêtres peuvent se ballader, il n'est pas possible de garder un écran fixe lorsque l'on switch de de workspace, ... XMonad associe simplement un workspace à un écran. Ainsi, quand je switch de workspace, je ne switch que le workspace de l'écran qui a le focus (
M-Wpour donner le focus au 1er écran,M-Epour le donner au second), plus de zone invisible, les fenêtres sont agrandis/reduites automatiquement suivant le layout et la taille de l'écran. Exactement ce que je voulais en fait :).
Conclusion
Finalement, c'est un aller simple pour les tiling window managers. Je suis vraiment efficace pour jouer avec mes fenêtre, plus d'aller retour entre le clavier et la souris, coupler avec un launcher du type Gnome Do, je peux tout faire avec mon clavier :). Malgré la courbe d'apprentissage d'Haskell et de la configuration, je suis arrivé à faire tout ce que je voulais même si je ne sais toujours pas codé en Haskell :).
Ma config complète d'XMonad est dispo par ici.
Maintenant, le plus dur c'est que j'ai du mal à m'en passer et quand je reviens sous Windows ou MacOS, je pleure !!!
Migration de Wordpress vers Jekyll
Posted on 09 Nov 2009 by David in geek, blog
Les rares abonnés au flux RSS de mon blog l'auront remarqué, je ne poste pas vraiment régulièrement (j'espère m'améliorer, j'ai plein de sujets de geek à partager :) ). En fait, jusqu'à maintenant, je passais plus de temps à mettre à jour Wordpress pour éviter d'être à la traine niveau correction de failles de sécu. Si seulement c'était juste Wordpress, les plugins que j'utilisais devaient eux aussi subir une mise à jour pour suivre l'évolution des APIs de Wordpress. Et tout ne se passait pas toujours très bien :(.
Comme je suis dans ma période "revenons aux sources, pourquoi ai-je besoin de m'encombrer avec ce #$%@!!. de XXX ?" (remplacer XXX par Wordpress, Eclipse, OpenOffice ou tout autre soft qui finit immanquablement en usine à gaz), et que je suis un peu un geek sur les bords, je me suis dis que j'allais essayer Jekyll.
Qu'est ce que Jekyll ?
C'est un petit outil écrit en Ruby qui à partir de templates Liquid et de fichiers Markdown (ça ressemble à une syntaxe de Wiki : voyez le source de ce post) génère un blog en statique que je dépose ensuite derrière un Apache.
Par où commencer ?
Je n'ai toutefois pas fait table rase, j'ai repris l'existant de mon Wordpress en commençant par migrer le système de commentaire sur le service Disqus à l'aide du plugin Wordpress qui va bien. Oui, un site avec des pages HTML en statique va avoir du mal à conserver les commentaires des posts! Je délègue donc, tout en me permettant une migration des commentaires tout en douceur :
- Le plugin Disqus pour Wordpress a une fonction de migration,
- Le nouveau site inclus ensuite Disqus avec les quelques lignes de Javascript qui vont bien.
Ensuite, un petit script permet d'extraire les posts de la base de données Wordpress pour les transformer en fichier Markdown. Le résultat n'est pas parfait, mais ça permet de débuter.
Le templating
Une fois les posts migrés, il reste encore à écrire les templates dans lesquels les articles (et autres pages) s'insèreront.
Rien de magique, du HTML, du CSS, une pincée de Javascript et un peu de Liquid pour faire quelques boucles, quelques conditions :
<div id="recent_posts" class="sidebar_section">
<h4 class="sidebar_title">Recent posts</h4>
<div class="sidebar_content">
<ul>
<li><a href="/2009/12/09/un-petit-tour-avec-xmonad">
Un petit tour avec XMonad
</a></li>
<li><a href="/2009/11/09/migration-wordpress-jekyll">
Migration de Wordpress vers Jekyll
</a></li>
<li><a href="/2008/05/24/utiliser-time-machine-avec-un-lecteur-reseau">
Utiliser Time Machine avec un lecteur réseau
</a></li>
<li><a href="/2008/03/12/gerer-la-diffusion-de-la-musique-de-son-neuros-osd-depuis-son-pc">
Gérer la diffusion de la musique de son Neuros OSD depuis son PC
</a></li>
<li><a href="/2008/03/10/first-beta-of-jabber-mail-component-v03">
First beta of Jabber Mail Component v0.3
</a></li>
</ul>
</div>
</div>
Et donc ?
Oui, et donc ? Et bien je dirais que je me suis bien fait plaisir ;), j'ai passé un peu plus de temps que prévu quand même vu le niveau HTML+CSS que j'avais.
Le blog est versionné dans un repo Git, donc plus de problème de backup de base MySQL, de migration, de restauration approximative, un git clone suivi de rake suffit (j'utilise Rake pour générer quelques pages supplémentaires, et lancer la génération du site par Jekyll).
Utiliser Time Machine avec un lecteur réseau
Posted on 24 May 2008 by David in geek, mac
Après avoir crashé le disque dur de mon Macbook pro (1 mois après l'avoir reçu :( ), je me suis dis que ce serait pas mal de faire des sauvegardes pour la prochaine fois où ça m'arrivera (si, si ça m'arrivera encore). Je me suis donc intéressé à Time Machine. Avec un NAS de près de 1 To sur mon réseau, ça doit pouvoir le faire. Seulement voilà, Time Machine ne me permet pas de séléctionner un lecteur réseau (via SMB ou AFP). Un petit coup de Google, et je trouve la réponse, dans un terminal :
$ defaults write com.apple.systempreferences \
TMShowUnsupportedNetworkVolumes 1
Et voilà, maintenant TM veux bien me laisser choisir un montage réseau (SMB et AFP), seulement quelques secondes après le démarrage du backup voilà ce qu'il me sort :
Time Machine Error - The backup disk image could not be created.
Encore, une fois après quelques recherches sur le web voilà la solution pour forcer la main à notre amis TM :
Lancer un backup en surveillant le répertoire du montage réseau. TM créé un répertoire avec l'extension .sparsebundle (de la forme ${HOSTNAME}_${adresse MAC de l'interface en0 sans les :}.sparsebundle). Copier le nom de ce répertoire.
Lancer l'utilitaire disque et créer une nouvelle image disque vide au format "image disque de faible densité" de la taille à réserver pour le backup et du nom copier à l'étape précédente (avec l'extension .sparsebundle). Le fichier créé devrait faire ~114 Mo.
Déplacer ce fichier à la racine du montage réseau (là où TM a tenté de créer le backup)
Relancer le backup de TM et tout devrait aller comme sur des roulettes :)
Gérer la diffusion de la musique de son Neuros OSD depuis son PC
Posted on 12 Mar 2008 by David in geek, neuros
Depuis quelques temps déjà, le Neuros OSD intègre xmms2 comme player pour la musique. Seulement voilà, gérer une playlist avec une télécommande infrarouge est quelque peu fastidieux. C'est là que l'aspect daemon d'xmms2 (oui, en vrai xmms2 n'est qu'un démon) entre en jeux. Il est possible de le piloter via le réseau.
Voici donc la marche à suivre pour faire marcher le tout avec le seul client potable (qui sache accéder au daemomms2 via le réseau) Esperanza :
Il faut commencer par se connecter en telnet sur l'OSD.
login : root mot de passe : pablod
Une fois connecté, il faut activer l'écoute sur un port réseau avec la commande suivante :
En fait cela active non seulement l'écoute réseau sur le port 4242, mais garde aussi l'ancienne configuration$ xmms2 config core.ipcsocket \ 'unix:///var/tmp/xmms-ipc-root;tcp://0.0.0.0:4242'
unix:///var/tmp/xmms-ipc-root.Tout les clients xmms2 que j'ai pu tester ne sont capable d'ajouter que des fichiers locaux (au client) et donc illisible depuis l'OSD (ou du moins pas avec le chemin de fichier). Pour résoudre ce problème, il faut donner à xmms2 un (ou plusieurs) répertoire(s) contenant l'ensemble des fichiers musicaux que l'on voudra jouer afin qu'il créé une base de données des fichiers musicaux :
$ xmms2 config medialib.path \ /mnt/tmpfs/media/SD-card/medialib.db $ xmms2 mlib addpath /mnt/tmpfs/media/nas/Music
La première ligne sert à déplacer la base de données SQLite que va créer xmms2. C'est nécessaire car la taille de ce fichier va grossir et ne pourra pas rester dans le répertoire par défaut (
/var/tmp/xmms2/medialib.db). Chez moi, je l'ai donc placé sur une carte SD qui reste constamment branchée sur l'OSD.La deuxième ligne ajoute un chemin où chercher les fichiers musicaux à la base de données xmms2. Tout les montages visible depuis l'interface de l'OSD devraient être montés dans
/media/tmpfs/media.Il ne reste plus qu'à se connecter au daemon avec Esperanza :



Voilà, maintenant, plus besoin d'allumer sa TV et de se faire @#@$! avec la télécommande pour écouter de la musique sur son Neuros.
Esperanza permet d'ajouter des flux shoutcast à la playlist xmms2 mais pour une raison encore inconnu, le xmms2 du neuros ne semble pas d'accord. Peut-être manque-t-il un plugin ? La solution peut-être dans un autre post ...
Update: il semble que le support shoutcast ait été ajouté sur la branche trunk (qui est aussi celle qui apportera la nouvelle interface QT).
First beta of Jabber Mail Component v0.3
Posted on 10 Mar 2008 by David in project
I have released a first beta of Jabber Mail Component of its third version. Here are the feature introduce by this version:
- SMTP support for sending emails
- Ad-hoc commands for admins and users
- XEP-0033 support to reply emails received through JMC
- IMAP folder tree browsing
It can be downloaded from here and to install it, follow this documentation (configuration and usage documentations will be added soon).
Before releasing the final 0.3 version, I need your help to track bugs and to update translation (corrections in the English translation are also welcome :) ).



