Rendez-vous sur Arrakis

C'est lorsque nous croyons savoir quelque chose qu'il faut justement réfléchir un peu plus profondément. F. Herbert

dwm

Présentation

Dwm est un gestionnaire de fenêtres de type tiling (Gestionnaire de fenêtres en tuile). L'emplacement des fenêtres est automatique, et optimisé pour que vous n'ayez pas à vous préoccuper de les organiser. De plus, sachez que tout peut être réalisé au clavier, ce qui est un gain de temps non négligeable.

Fidèle à la philosophie suckless, le programme est écrit en C, dans un code très propre et léger, qui assure rapidité et fiabilité. La configuration se déroule dans un fichier à la syntaxe simplifiée : le config.h dont nous parlerons ensuite. Il est donc accessible malgré les apparences. Un système de patches permet d'étendre les fonctionnalités de dwm.

Debian propose un paquet de démonstration. Nous verrons dans la suite du document comment configurer dwm, et comment reconstruire un paquet proprement. Mais avant de commencer, voici quelques aperçus (cliquer pour agrandir):

Tester sur debian

Pour commencer, vous pouvez installer la version de test proposée dans les dépots debian : apt-get install dwm.

Choisissez ensuite la session dwm dans gdm/kdm, ou bien rajoutez au fichier ~/.xinitrc la ligne suivante: exec dwm . Voilà, vous vous retrouvez devant dwm, avec une barre grise et bleue. Maintenant, intéressons nous à son utilisation.

Utilisation

Par défaut, vous disposez par défaut de 9 vues, ou plutôt 9 étiquettes à attribuer aux fenêtres. Oubliez le paradigme habituel des espaces de travail : avec dwm, vous collerez des étiquettes (tags) sur les fenêtres, comme si vous leur donniez un label.

Une fois l'habitude prise, vous comprendrez pourquoi dwm veut dire Dynamic window manager.

Chaque petit chiffre correspond à une étiquette (ou tag), qui est affecté à une fenêtre. Vous donnez à chaque fenêtre une étiquette, allant de 1 à 9, pour ensuite afficher les fenêtres portant la même étiquette, ou les fenêtres portant les étiquettes 1 et 2, etc.

À vous de choisir si vous souhaitez afficher les fenêtres qui ont l'étiquette 1, 3, ou bien 3 et 4, ou encore “net” et “video”… En gros, ça ne marche pas exactement comme un espace de travail, vous choisissez les fenêtres que vous voulez voir, et pour cela, ce n'est plus vous qui vous déplacez, c'est vous qui demandez aux fenêtres HEP! viens par là!

Concrètement, cela veut dire que lorsque votre “vue” commence à être trop chargée, qu'il y a trop de fenêtre, vous pouvez donner à certaines d'entre elles une autre étiquette. Cette autre étiquette, pous pourrez plus tard choisir de l'afficher. Maintenant, vous changez d'activité. Vous choisissez une nouvelle étiquette avec Alt+chiffre, et ouvrez de nouvelles fenêtres. Mais vous voudriez pouvoir revenir à l'ancienne vue rapidement, pour retrouver votre ancienne activité. Avec le raccourci Alt+Tab, vous affichez une nouvelle vue vide. Pour revenir à la précédente, il suffit de refaire Alt+Tab.

En somme, une “vue” correspond à un arrangement particulier des fenêtres, une sélection de plusieurs étiquettes. Cette vue pourra être retrouvée à tout moment.

Plus d'infos sur ce blog : Tags aren’t workspaces

Les raccourcis claviers

Dwm a été pensé pour être entièrement piloté au clavier. Attention toutefois, ne pensez pas utiliser dwm en utilisant les tags comme de simples espaces de travail, ce serait passer à côté de l'utilité de dwm. Ainsi, vous aurez la plupart du temps plusieurs fenêtres ayant un tag particulier à la fois d'affichés. Essayez, une fois que vous y serez habitué, vous serez beaucoup plus efficaces.

Voici un descriptif des raccourcis clavier par défaut. La touche Mod1 désigne la touche Alt.

De l'usage des étiquettes

Je vais présenter ici une utilisation de dwm que je trouve extrêmement pratique : l'utilisation avancée des étiquettes.

Rappelons tout d'abord que l'on peut alterner entre la vue actuelle et la vue précédente avec mod+TAB.

À chaque fenêtre est attribuée une étiquette (tag). Afin de consulter/cacher une fenêtre, je ne me déplace pas dans son “tag” avec mod+chiffre, mais j'affiche les fenêtres ayant cette étiquette avec ctrl+mod+chiffre.

Par contre, je peux créer une seconde “vue” en allant choisissant d'autres fenêtres. En faisant mod+TAB, j'alterne rapidement entre les vues.

Prenons un exemple. J'écris actuellement cette page dans un terminal ayant l'étiquette 1 :

Je souhaite afficher la fenêtre de conversation qui a l'étiquette 3. Je tape alors mod+ctrl+3 :

Désormais, je souhaite naviguer sur internet, mon navigateur a l'étiquette 2. Je tape alors mod+2

Pour revenir à la vue précédente, qui contenait la fenêtre de discussion et le terminal où j'écris cette page (étiquettes 1 et 3), il me suffit de faire mod+TAB

Pour retourner au navigateur, on refait mod+TAB.

Par défaut, les raccourcis claviers ne sont peut-être pas les plus pratiques. Afin de simplifier la vie, je vous conseille d'échanger les raccourcis, afin que mod+chiffre affiche un tag en plus des autres, et mod+ctrl+chiffre n'affiche que les fenêtres ayant l'étiquette “chiffre”.

Je vous laisse le fichier diff associé, tiré d' ici. Pour l'appliquer : patch -p1 < config.h.diff après l'avoir enregistré dans le fichier config.h.diff. Voir la section appliquer un patch.

Remarquez que sa lecture est très simple, les lignes précédées d'un - sont supprimées, les lignes précédées d'un + sont ajoutées à la place.

--- a/config.h  2013-01-25 05:20:04.618352250 +1100
+++ b/config.h  2013-01-25 05:22:40.357508538 +1100
@@ -37,8 +37,8 @@ static const Layout layouts[] = {
/* key definitions */
#define MODKEY Mod1Mask
#define TAGKEYS(KEY,TAG) \
-   { MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
-   { MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
+   { MODKEY,                       KEY,      toggleview,     {.ui = 1 << TAG} }, \
+   { MODKEY|ControlMask,           KEY,      view,           {.ui = 1 << TAG} }, \
    { MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
    { MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },

@@ -97,8 +97,8 @@ static Button buttons[] = {
    { ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} },
    { ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} },
    { ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} },
-   { ClkTagBar,            0,              Button1,        view,           {0} },
-   { ClkTagBar,            0,              Button3,        toggleview,     {0} },
+   { ClkTagBar,            0,              Button1,        toggleview,     {0} },
+   { ClkTagBar,            0,              Button3,        view,           {0} },
    { ClkTagBar,            MODKEY,         Button1,        tag,            {0} },
    { ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} },
};

Installation

Dwm est téléchargeable depuis le site officiel. Choisissez alors l'archive la plus récente. Vous pouvez aussi choisir d'utiliser l'archive debian. C'est en toute franchise ce que je vous conseille. Pour cela, assurez-vous d'activer les dépots sources dans le fichier /etc/apt/sources.list (lignes commençant par deb-src), puis lancez :

apt-get source dwm``

Il est aussi possible de récupérer la dernière version en développement de dwm avec git :

git clone git://git.suckless.org/dwm``

Vous obtenez alors un dossier contenant les sources dwm.

À partir du dossier des sources

Il suffit de lancer make &amp;&amp; make install. Si vous ne souhaitez pas installer les exécutables dans /usr/local/bin, vous pouvez toujours préciser le chemin du dossier de destination dans le fichier config.mk, à la ligne PREFIX =.

Les dépendances sont libx11-dev et libxinerama-dev.

À partir des sources debian

On récupère les sources ainsi :

apt-get source dwm``

On se déplace dans le dossier des sources. Avec le caractère “*”, on n'a pas besoin de préciser la version de dwm :

cd dwm*``

Attention: Si vous voulez configurer dwm, éditez ici le config.def.h, pas le config.h (c'est la petite exception debian).

Une fois satisfaits, reconstruisez le paquet :

dpkg-buildpackage -rfakeroot -uc -b``

Un paquet est alors disponible dans le répertoire parent, sour la forme dwm- version.deb. Pour vous assurer d'avoir les dépendances nécéssaires, il suffit de lancer

apt-get build-dep dwm``

Pour installer le paquet créé :

dpkg -i dwm*.deb``

Note: Afin d'éviter toute mise à jour non souhaitée de dwm, écrivez ceci dans le fichier /etc/apt/preferences:

Package: dwm
Pin: release a=now
Pin-Priority: 1001

Ou alors lancez aptitude hold dwm

Démarrer une session dwm

Voyons comment démarrer une session dwm.

Avec GDM

Par défaut, gdm va lire le fichier /usr/share/xsession/dwm.desktop pour démarrer une session dwm. Cela n'est pas toujours pratique, surtout si plusieurs utilisateurs veulent utiliser des configurations de dwm qu'ils ont chacun compilés dans leur dossiers personnels.

Une solution possible est de créer de nouveaux fichiers de démarrage sur le même modèle que dwm.desktop, en remplaçant ce qui est exécuté par un script écrit pas vos soins.

Par exemple, créons une session pour l'utilisateur paskal (qui se reconnaîtra ☺). On va alors mettre dans un fichier /usr/share/xsession/dwm-paskal.desktop :

[Desktop Entry]
Encoding=UTF-8
Name=Dwm-paskal
Comment=Dynamic window manager
Exec=/home/paskal/startdwm.sh
Icon=dwm
Type=XSession

Et dans le dossier de paskal, on a créé le fichier /home/paskal/startdwm.sh

#!/bin/sh
# Lancement automatique de firefox
firefox &amp;
# Lancement de mon dwm perso.
exec /home/paskal/dwm-6.0/dwm

Profitez-en pour mettre dans ce script des commandes que vous voulez lancer automatiquement. Il faut juste penser à mettre un “&amp;” à la fin de la ligne.

Avec un script de démarrage

Avec slim ou simplement en tapant startx, ce sera le fichier ~/.xinitrc qui sera lu. Ajoutez donc touts les programmes que vous souhaitez démarrer dans ce fichier, puis terminez-le par exec dwm.

N'oubliez pas les “&amp;” en fin de ligne, ainsi que de préciser le chemin complet vers l'exécutable de dwm si vous l'avez compilé dans un endroit inhabituel.

#!/bin/sh
# fond d'ecran
feh --bg-scale ~/Images/bg.jpg &amp;
exec /home/moi/dwm/dwm

Configuration

La configuration de dwm se déroule dans le fichier config.h (ou config.def.h pour le paquet debian). Je vous invite à lire la documentation de suckless à ce sujet.

Le fichier config.def.h est le fichier de configuration par défaut. Copiez-le en config.h, c'est alors ce fichier qui sera utilisé pour la configuration.

config.h exemple

Vous trouverez un exemple de config.h ici : config.h exemple

///* See LICENSE file for copyright and license details. *///

///* appearance *///
////La police et sa taille utilisée dans dwm//
static const char font[]            = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
static const char font[]            = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
////couleur des bordures de fenêtres//
static const char normbordercolor[] = "#444444";
////couleur d’arrière plan//
static const char normbgcolor[]     = "#222222";
////couleur premier plan//
static const char normfgcolor[]     = "#bbbbbb";
////couleur des bordures des fenêtres selectionnées//
static const char selbordercolor[]  = "#005577";
////couleur de l’arrière plan lorsque l’objet est selectionné /*//
static const char selbgcolor[]      = "#005577";
////couleur de premier plan des objets sélectionnés//
static const char selfgcolor[]      = "#eeeeee";
///* taille en pixel des bordures des fenetres *///
static const unsigned int borderpx  = 1;        ///* border pixel of windows *///
static const unsigned int snap      = 32;       ///* snap pixel *///
///* Montrer la barre par défaut *///
static const Bool showbar           = True;     ///* False means no bar *///
///* Barre en haut ou en bas*///
static const Bool topbar            = True;     ///* False means bottom bar *///

///* tagging *///
//// les differents espaces de travail, et leurs noms, vous pouvez mettre ce que//
//// vous voulez à la place des chiffres//
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };

///* Les règles spécifiques à chaque fenêtres//
//les informations sur les fenêtres peuvent s’obtenir en tapant xprop en console//
//et en cliquant sur la fenêtre en question//
//* isfloating: True : la fenetres est flottante, False : la fenetre est en tiling//
//* tags mask : Dire dans quel tag la fenetre apparaitra//
//1 << 8 définit le tag 9, 1 << 7 représente le tag 8, ~0 représente tous les tags.//
//plus d’infos ici : http://dwm.suckless.org/customisation/tagmask//
//*///
static const Rule rules[] = {
    ///* class      instance    title       tags mask     isfloating   monitor *///
    { "Gimp",     NULL,       NULL,       0,            True,        -1 },
    { "Firefox",  NULL,       NULL,       1 << 8,       False,       -1 },
};

///* layout(s) : Les différents arrangements de fenêtres*///
///* Taille du Master (la fenetre principale) [0.05..0.95] *///
static const float mfact      = 0.55; ///* factor of master area size [0.05..0.95] *///
///*Nombre de fenêtres par défaut dns la zone principale *///
static const int nmaster      = 1;    ///* number of clients in master area *///
static const Bool resizehints = True; ///* True means respect size hints in tiled resizals *///

static const Layout layouts[] = {
    ///* symbol     arrange function *///
    ///* La première entrée est celle par défaut lorsque dwm se lance, mode en tuile *///
    { "[]=",      tile },    ///* first entry is default *///
    ///* Mode flottant, car NULL *///
    { "><>",      NULL },    ///* no layout function means floating behavior *///
    ///* Mode maximisé (plein ecran) *///
    { "[M]",      monocle },
};

///* key definitions *///
///* MODKEK est la touche pour les raccourcis.//
//Ici, c‘est alt(Mod1Mask) (Mod4Mask sera la touche windows) *///

#define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \
    //// Mod+chiffre envoie sur la vue correspondante//
 { MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
    //// Mod+Ctrl+chiffre affiche/cache les fenêtres d'étiquette "chiffre"//
    { MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
    //// Mod+Shift+chiffre définit une étiquette à la fenêtre.//
    { MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
    //// Mod+Ctrl+Shift+chiffre donne le tag à fenêtre sans la suivre//
    { MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },

///* helper for spawning shell commands in the pre dwm-5.0 fashion *///
///* Fonction pratique pour lancer des commandes ex : SHCMD("firefox")*///
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }

///* commands *///
///* Ici, on pourra définir les commandes que l’on veut pour les assigner à des raccourcis ensuite *///
static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
////changer pour votre terminal favori//
static const char *termcmd[]  = { "x-terminal-emulator", NULL };

static Key keys[] = {
    ///* modifier                     key        function        argument *///
    //// Lance dmenu//
    { MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
    //// Lance un terminal//
    { MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
    //// Affiche/cache la barre//
    { MODKEY,                       XK_b,      togglebar,      {0} },
    //// sélectionne fenetre suivante//
    { MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
    //// sélectionne fenetre précédente//
    { MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
    //// Augmente le nb de fenêtres dans la zone maîtresse//
    { MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
    //// Réduit le nb de fenêtres dans la zone maîtresse//
    { MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
    //// Réduit la taille de la zone maîtresse//
    { MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
    //// Augmente la taille de la zone maîtresse//
    { MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
    //// Met la fenetre dans la zone maîtresse//
    { MODKEY,                       XK_Return, zoom,           {0} },
    //// Voir la vue précédente//
    { MODKEY,                       XK_Tab,    view,           {0} },
    //// Fermer la fenêtre//
    { MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
    //// Changement d’organisation des fenetres//
    { MODKEY,                       XK_t,      setlayout,      {.v = &amp;layouts[0]} },
    { MODKEY,                       XK_f,      setlayout,      {.v = &amp;layouts[1]} },
    { MODKEY,                       XK_m,      setlayout,      {.v = &amp;layouts[2]} },
    //// Active l’agencement précédent//
    { MODKEY,                       XK_space,  setlayout,      {0} },
    //// Active/désactive la fenetre en flottant ou non//
    { MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
    //// Voir toutes les fenetres//
    { MODKEY,                       XK_0,      view,           {.ui = ~0 } },
    ////  La fenêtre a toutes les étiquettes//
    { MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },
    //// Sélectionne la fenêtre de l’écran précédent//
    { MODKEY,                       XK_comma,  focusmon,       {.i = -1 } },
    //// Fenêtre de l’ecran suivant//
    { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
    //// Envoie la fenêtre sur l’écran précédent//
    { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
    //// Envoie la fenêtre sur l’écran suivant//
    { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
    //// les touches "chiffres", à modifier pour les claviers francais//
    TAGKEYS(                        XK_1,                      0)
    TAGKEYS(                        XK_2,                      1)
    TAGKEYS(                        XK_3,                      2)
    TAGKEYS(                        XK_4,                      3)
    TAGKEYS(                        XK_5,                      4)
    TAGKEYS(                        XK_6,                      5)
    TAGKEYS(                        XK_7,                      6)
    TAGKEYS(                        XK_8,                      7)
    TAGKEYS(                        XK_9,                      8)
    //// quitte dwm//
    { MODKEY|ShiftMask,             XK_q,      quit,           {0} },
};

///* button definitions *///
///* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin *///

///* On peut cliquer sur le symbole, le texte de status, le titre de la fenêtre,//
// * la fenêtre, le fond d’écran *///

static Button buttons[] = {
    ///* click                event mask      button          function        argument *///
    //// Clich sur le sybole change l'agencement//
    { ClkLtSymbol,          0,              Button1,        setlayout,      {0} },
    //// Quand on clique droit sur le symbole des modes, ça met le 2eme agencement//
    { ClkLtSymbol,          0,              Button3,        setlayout,      {.v = &amp;layouts[2]} },
    //// Clique milieu sur le titre de la fenêtre l’agrandit//
    { ClkWinTitle,          0,              Button2,        zoom,           {0} },
    //// cliquer milieu sur le texte de status lance un terminal,//
    ////bien sûr, il est possible de mettre ce que vous voulez à la place de termcmd//
    { ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } },
    //// Mod + clique déplace la fenetre//
    { ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} },
    { ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} },
    //// mod + clic droit pour redimensionner//
    { ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} },
    { ClkTagBar,            0,              Button1,        view,           {0} },
    { ClkTagBar,            0,              Button3,        toggleview,     {0} },
    { ClkTagBar,            MODKEY,         Button1,        tag,            {0} },
    { ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} },
};

Ajouter un patch

Vous pouvez ajouter toutes sortes de fonctionnalités à dwm, en ajoutant des patches. Le site officiel regorge d’informations à ce sujet, et la configuration de chaque patch est expliqué. De façon générale, pour appliquer un patch, il faudra faire ceci dans le dossier de dwm (pour la version tarball (paquet debian inclus))

patch -p1 < chemin/vers/le/patch.diff``

Mais comment tu fais pour avoir le code des touches, ou les évènements de la souris?

La réponse est simple. Lancez la commande xev en console. Un fenêtre blanche apparaît. Lorsque vous mettez la souris dedans, vous voyez apparaître tout un tas de message dans le terminal : ce sont les évènements qu'il détecte.

Pour avoir le code d'une touche, tapez sur cette touche, vous verrez apparaître un message de ce type (appui sur le 0 du clavier, soit le à):

Vous pouvez donc récupérer le code de la touche entre parenthèses, ici, ce sera XK_agrave.

Notez que cela vaut aussi pour la souris, afin de récupérer le numéro du bouton cliqué, ou tout autre évènement.

Changer la touche méta par défaut

Par défaut, c'est la touche Alt (ou Mod1) qui sert à changer de fenêtres, lancer dmenu, cacher la barre… etc. Par souci de compatibilité avec d'autres logiciels, ou par habitude, il est possible de choisir n'importe quelle autre touche. Par exemple, on peut utiliser la touche “windows” (Mod4), qui ne sert jamais. Elle est reconnue par le code Mod4Mask. Alors, dans le config.h, on remplace la définition de MODKEY par la valeur souhaitée :

/* key definitions */
#define MODKEY Mod4Mask

Règles pour les fenêtres

Il est bon de lire la documentation officielle.

Ici, vous allez apprendre à définir un comportement particulier selon la fenêtre. Par exemple, si je veux assigner l'étiquette “7” au programme gajim, il est possible de définir cette règle :

static const Rule rules[] = {
/* class instance title tags mask isfloating monitor */
{ "Gajim", NULL, NULL, 1 << 6, False, -1 },
};

Trouver class et title d'une fenêtre

Pour récupérer les informations sur une fenêtre, tapez xprop dans une console. Votre curseur va changer de forme. Cliquez alors sur la fenêtre voulue. Vous verrez apparaître dans la console les informations sur la classe, le titre de la fenêtre…

Voici ce que par exemple vous obtiendrez :

WM_CLASS(STRING) = "Navigator", "Iceweasel"
WM_ICON_NAME(STRING) = "Rendez-vous sur Arrakis : dwm - Iceweasel"
_NET_WM_ICON_NAME(UTF8_STRING) = "Rendez-vous sur Arrakis : dwm -
Iceweasel"
WM_NAME(STRING) = "Rendez-vous sur Arrakis : dwm - Iceweasel"
_NET_WM_NAME(UTF8_STRING) = "Rendez-vous sur Arrakis : dwm - Iceweasel"

WM_CLASS donne la “class” de la fenêtre, et WM_NAME le “name” de la fenêtre.

:Notez que l'on peut donner à un terminal un titre précis. Par exemple, avec urxvt, c'est avec l'option “-T”. Avec st, c'est comme xterm, avec “-t”. On peut donc envoyer un terminal à l'étiquette 8, avec cette règle

{ “NULL”, NULL, “MonTerminal”, 1 << 7, False, -1 },

Par contre, il faudra le lancer ainsi : st -t "MonTerminal". Ça peut être utile dans des scripts…

Fenêtre flottante

Vous l’aurez compris, si vous voulez que la fenêtre flotte, il faudra mettre “ True ” dans la colonne //“isfloating”//

Fenêtre à 1 étiquette précise

Pour désigner le tag où l’on veut assigner à une fenêtre, c’est un peu plus complexe.

Changer la police

La police peut maintenant être n'importe laquelle depuis la version 6.1. Il faut modifier les lignes suivantes du fichier config.h :

static const char *fonts[] = {
    "Inconsolata:size=10"
};
static const char dmenufont[]       = "Inconsolata:size=10";

Bien sûr, mettez ce que vous préférez à la place de Incolsolata.

Définir vos raccourcis clavier

Il est bien entendu possible d'exécuter n'importe quelle commande via un raccourci clavier.

Méthode simple

Dwm propose déja une fonction toute prête pour lancer n'importe quelle commande : SHCMD.

/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }

Alors, vous pouvez définir n'importe quel raccourci clavier dans la section static Key keys[] = {.

Pour passer à la chanson suivante de la liste de lecture de mpd, je lance la commande mpc next. Pour l'associer au raccourci ctrl+flèche_droite J'ajoute à la section Key keys :

{ ControlMask,    XK_Right,  spawn,    SHCMD("mpc next") },

Autre exemple. J’ai envie de lancer rox lorsque j’appuie sur Mod4+Mod1+h, et couper le son lorsque j’appuie sur la touche multimédia de mon ordinateur. J'écrirais alors ces lignes suivantes :

{ 0,                0x1008ff12,    spawn,          SHCMD("amixer -q set Master toggle") },
{ MODKEY|Mod1Mask,  XK_h,          spawn,          SHCMD("rox") },

Hé, mais c'est quoi ça, Mod4 et Mod1 ??? Ah oui, j'allais oublier. Mod4 désigne la touche Méta, souvent la touche “windows” située entre Fn et alt. Mod1 quand à lui, désigne la touche Alt.

Autre méthode

Il faut d'abord définir la commande à éxécuter, puis ensuite, on définira le raccourci.

Les commandes sont définies à cet endroit du config.h, il y en a déja deux :

/* commands */
static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *termcmd[] = { "uxterm", NULL };

La première ligne sert à lancer dmenu avec les couleurs de dwm. C’est en fait ce qui se passe lorsque vous tapez le raccourci Mod+P . dmenu est inclus dans le paquet dwm-tools ou suckless-tools

La deuxième ligne lance un terminal, c’est ce qui se passe lorsque vous faîtes Mod+Shift+Entrée. Vous pouvez modifier la commande uxterm, par votre terminal favori (xterm, urxvt, xfce4-terminal, lxterminal…). Si vous n’êtes pas sûr, suivez le conseil de MisterFreez, indiquez « x-terminal-emulator "

On va ajouter en-dessous de ces lignes nos propres fonctions!

Par exemple, je voudrais ajouter deux raccourcis : l’un pour lancer gajim, l’autre pour couper/activer le son. Il faudra définir deux fonctions sur le même modèle que les précédentes. Donnez leur le nom que vous voulez, du moment que vous vous y retrouvez.

static const char *gajim[] = { "gajim", NULL };
static const char *muteson[] = { "amixer", "-q", "set", "Master", "toggle", NULL };

Note : Remarquez que lorsque une commande contient des espaces, chaque argument doit être entre guillemets suivi d’une virgule.

Les commandes finissent toujours par NULL.

Bien, maintenant que nos fonctions sont définies, on va les associer à un raccourci clavier. Voici ce que ça donnera, dans la section des raccourcis claviers :

static Key keys[] = {
/*il y a d’autres choses avant….*/
{ MODKEY|Mod1, XK_i, spawn, {.v = gajim } },
{ 0, 0x1008ff12, spawn, {.v = muteson } },

Quelques explications:

Et pour la souris?

Bien sûr, on peut reprendre le même schéma que pour le clavier. En fait, j'utilise pour ma part, une action personnalisée pour qu'un clic-droit sur la barre de status ou le fond d'écran, m'affiche un menu.

Voici les étapes à suivre :

Changer le volume sonore avec la molette de la souris

Sur le même modèle que le paragraphe précédent, on peut augmenter/diminuer le volume sonore lorsque l'on fait rouler la molette de la souris sur la barre de status.

Premièrement, lancez xev, et faîtes rouler la molette dedans sa fenêtre pour vois à quel bouton de la souris ça correspond (cela s'affiche dans la console). Chez moi, c'est les boutons 4 et 5.

Et enfin, tout en bas, dans la section de la souris, après static Button buttons[] = { on indique les raccourcis, c'est à dire la molette sur la barre de status, avec la commande permettant de changer le son lancée avec SHCMD :

{ ClkStatusText,        0,              Button4,        spawn,    SHCMD("amixer -q set Master 2dB+ unmute") },
{ ClkStatusText,        0,              Button5,        spawn,    SHCMD("amixer -q set Master 2dB- unmute") },

Modifier la configuration pour les claviers français

Un patch peut vous aider rapidement à effectuer cette opération : azertykey

Les touches “chiffre”

Malheureusement, dwm est configuré par défaut pour les claviers anglais. Les chiffres au dessus des lettres de votre clavier ne seront pas lus comme tels, mais comme étant un « &amp; “ pour le « 1″, un « é ” pour le 2, un “ pour le « 3″… On va donc remédier à tout ça. Le code de nos touches se récupère très facilement avec xev. Il faut lancer xev en console, taper sur une touche, et lire ce qui est retourné.

Remplaçons cette portion :

TAGKEYS(                        XK_1,                      0)
TAGKEYS(                        XK_2,                      1)
TAGKEYS(                        XK_3,                      2)
TAGKEYS(                        XK_4,                      3)
TAGKEYS(                        XK_5,                      4)
TAGKEYS(                        XK_6,                      5)
TAGKEYS(                        XK_7,                      6)
TAGKEYS(                        XK_8,                      7)
TAGKEYS(                        XK_9,                      8)

Par :

TAGKEYS(                        XK_ampersand,                     0)
TAGKEYS(                        XK_eacute,                        1)
TAGKEYS(                        XK_quotedbl,                      2)
TAGKEYS(                        XK_apostrophe,                    3)
TAGKEYS(                        XK_parenleft,                     4)
TAGKEYS(                        XK_minus,                         5)
TAGKEYS(                        XK_egrave,                        6)
TAGKEYS(                        XK_underscore,                    7)
TAGKEYS(                        XK_ccedilla,                      8)

Ainsi que :

{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
{ MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },

Par :

{ MODKEY,                       XK_agrave,      view,           {.ui = ~0 } },
{ MODKEY|ShiftMask,             XK_agrave,      tag,            {.ui = ~0 } },

Pour changer d'écran

Il faut françiser la touche « . “ pour nos claviers. Donc, remplacer dans le config.h « period ” par « semicolon “, car pour nous, c’est le point-virgule :

{ MODKEY, XK_comma, focusmon, {.i = -1 } },
{ MODKEY, XK_semicolon, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_semicolon, tagmon, {.i = +1 } },

Personnaliser la barre d'état

Il est possible d’afficher ce que l’on veut dans la barre d’état. Cela se définit juste avant le lancement de dwm, donc selon les cas dans votre ~/.xinitrc ou autre. Dwm lira ce qui est passé en argument à xsetroot. Cela donnera quelque chose comme ça :

while true; do
xsetroot -name " $( date + "%F %R " ) "
sleep 1m # Update time every minute
done &amp;
exec dwm

Qui affichera la date. Voici mon .xinitrc :

/home/xavier/Documents/Scripts/dmenu/dstatus.py &amp;
exec /usr/local/bin/dwm

Vous remarquerez que le lance un script dstatus.py à part, pour plus de commodité. Ce script récupère plusieurs informations, et les renvoient dans le xsetroot. Voici ce que cela donne :

En fait, vous pouvez afficher ce que vous souhaitez, du moment que vous passez ce texte à travers xsetroot.

Avec conky-cli

Encore plus simple. Conky-cli indique dans la console les information que conky affiche d'habitude en graphique. Pour afficher la sortie de conky-cli dans la barre de dwm, modifiez votre ~/.xinitrc pour qu'il ressemble à ça :

conky | while read -r; do xsetroot -name "$REPLY"; done

Et le conkyrc :

update_interval 1
TEXT
${if_mpd_playing} $mpd_smart $mpd_elapsed/$mpd_length | ${endif}Cpu: $cpu% | Mem: ${memperc}% | Swap: ${swapperc}% | Bat: ${battery_short} | /: ${fs_free_perc /}% /home: ${fs_free_perc /home}% | M:${execi 300 ~/.Scripts/mailinfo.py} | Vol: ${mixer}% | D: ${downspeed wlan0}/s U:${upspeed wlan0}/s | ${time %d/%m/%y %H:%M }

Résultat en image :

Avec dwmstatus

Il est possible de faire exactement la même chose, mais entièrement en C. Je vous laisse imaginer le gain en performance! Voir sur cette page

Des notifications dans la barre

C'est possible, voir sur cette page

Paquet de ma version de dwm .

Vous trouverez ci-dessous un lien vers la version de dwm que j'utilise (avec le paquet debian qui va avec).

dwm-0.6_thuban.tar.gz

Conclusion

Il y a un programme essentiel à utiliser dans dwm : j’ai nommé dmenu. Vous pourrez au fur et à mesure lire des exemples d’utilisation que je posterai ici, dans la catégorie dmenu.

N'hésitez pas à me contacter pour toute précision, commentaire, ou astuces à ajouter.