Shifty/fr

Shifty, c’est quoi ?
Réponse rapide : qu’est-ce que ça n’est pas ‽

Réponse longue : shifty est une extension pour awesome 3 qui implémente la gestion dynamique des onglets. Elle implémente également une configuration des clients qui vous permet d’être le maître de votre bureau, en mettant simplement en place deux variables de configuration et quelques raccourcis ! Voici quelques exemples pour vous montrer à quel point shifty peut rendre awesome encore plus grandiose :
 * création et élimination d’onglets à la volée ;
 * gestion avancée des clients ;
 * déplacement facilité des clients entre onglets ;
 * invite d’ajout ou renommage d’onglets dans la liste d’onglets, avec complétion, maintenant configurable ;
 * réordination des onglets et positionnement configurable ;
 * initiative de nommage des onglets, groupement de clients automatique sans configuration ;
 * raccourcis personnalisables par client et onglet ;
 * configuration simple et puissante à la fois.

Ce module a été maintes fois modifié depuis son lancement et son développement actif ; des améliorations arrivent quotidiennement. Vérifiez le journal des changements pour plus de détails.

Le code est encore en pré-distribution mais le module est pleinement fonctionnel. Vous pourrez découvrir quelques limitations, qui viennent principalement du fait que le développeur de shifty n’utilise pas awesome tout à fait de la même façon que vous. Shifty a le potentiel de pouvoir comprendre de nombreuses approches différentes ; pour cette raison, des retours et commentaires sont nécessaires et de fait très appréciés.

Vidéos
Vous pouvez voir une des premières versions de shifty en action à http://silenceisdefeat.com/~koniu/shifty.ogv (miroir)

Une autre vidéo montrant quelques fonctionnalités améliorées est disponible mais peut être un peu déconcertante car elle montre des onglets qui disparaissent sans raison apparente. Une autre plus propre sera peut-être faite un jour, mais celle-ci permet d’en mettre plein la vue : http://silenceisdefeat.com/~koniu/shifty-new.ogv (5 Mio, désolé)

Enfin, une nouvelle vidéo donne un aperçu des possibilités offertes par les raccourcis par client ou onglet. C’est un morceau du rc.lua du développeur en action, qui crée un onglet spécial pour le développement, en utilisant git : http://silenceisdefeat.com/~koniu/gittags.avi (3,3 Mio)

Obtenir Shifty
Si vous voulez utiliser shifty, vous pouvez utiliser l’une des versions suivantes, d’après la version d’awesome que vous utilisez :


 * pour awesome git maître : par ici (brut) ;


 * Version for awesome 3.3.x : de ce côté (brut)

Utiliser shifty
Les instructions qui suivent ne sont pas tout à fait à jour, donc si vous êtes paresseux et que vous voulez juste essayer rapidement toutes ces choses, un rc.lua par défaut, conçu pour fonctionner avec shifty, peut être trouvé ici :
 * shifty version maître : http://silenceisdefeat.com/~koniu/awesome/shifty.rc.lua ;
 * version de bioe007 : http://github.com/bioe007/awesome-configs/blob/master/shifty.rc.lua (raw)

Exemple d’utilisation
1. Tout d’abord, sauvegardez shifty.lua dans votre dossier ~/.config/awesome.

2. Chargez le module : require('shifty')

3. Supprimez tous les paramètres de création et paramétrage d’onglets existants de votre rc.lua.

4. Désactivez le hook de gestion par défaut dans rc.lua. Vous pouvez faire ça en ajoutant ceci en première ligne : if true then return end

5. Quelque part au début de votre rc.lua, ajoutez des préférences d’onglets et de clients. Par exemple : shifty.config.tags = { ["1:sys"] = { init = true, position = 1, screen = 1, mwfact = 0.60                }, ["3:www"] = { exclusive = true, max_clients = 1, position = 3, spawn = "firefox"  }, ["2:term"] = { persist = true, position = 2,                                       }, ["ardour"] = { nopopup = true, leave_kills = true,                                 }, ["p2p"] = { icon = "/usr/share/pixmaps/p2p.png", icon_only = true,              }, ["gimp"] = { layout = "tile", mwfact = 0.18, icon="/usr/share/pixmaps/gimp.png", }, ["fs"] = { rel_index = 1,                                                      }, } shifty.config.apps = { { match = {"htop", "Wicd", "jackctl"       }, tag = "1:sys",        screen = 1,     }, { match = {"Iceweasel.*", "Firefox.*"      }, tag = "3:www",                        }, { match = {"urxvt"                         }, tag = "2:term",       screen = 1,     }, { match = {"foobar2000.exe",               }, tag = "fb",           nopopup = true, }, { match = {"Ardour.*", "Jamin",            }, tag = "ardour",                       }, { match = {"Live.*",                       }, tag = "live",         nopopup = true, }, { match = {"Deluge","nicotine"             }, tag = "p2p",                          }, { match = {"Gimp","Ufraw"                  }, tag = { "img", "gimp" }             }, { match = {"gimp%-image%-window"           }, slave = true,                         }, { match = {"gqview"                        }, tag = { "img", "gqview" }           }, { match = { "Pcmanfm"                      }, tag = "fs",                           }, { match = {"gcolor2", "xmag"               }, intrusive = true,                     }, { match = {"gcolor2"                       }, geometry = { 100,100,nil,nil },       }, { match = {"recordMyDesktop", "MPlayer", "xmag", }, float = true,                        }, { match = { "" }, buttons = { button({ }, 1, function (c) client.focus = c; c:raise end), button({ modkey }, 1, function (c) awful.mouse.client.move end), button({ modkey }, 3, awful.mouse.client.resize ), }, }, } shifty.config.defaults = { layout = "max", run = function(tag) naughty.notify({ text = tag.name }) end, } shifty.init

Les explications concernant cet exemple sont données plus bas.

6. Après les définitions de la liste d’onglets dans rc.lua, ajoutez la ligne suivante, en remarquant bien que mytaglist doit être un tableau de listes d’onglets et pas un simple objet « liste d’onglets » : shifty.taglist = mytaglist

7. Ajoutez quelques raccourcis claviers à rc.lua'. Par exemple : awful.key({                  }, "XF86Back",    awful.tag.viewprev), awful.key({                  }, "XF86Forward", awful.tag.viewnext), awful.key({ modkey           }, "XF86Back",    shifty.shift_prev), awful.key({ modkey           }, "XF86Forward", shifty.shift_next), awful.key({ modkey           }, "t",           function shifty.add({ rel_index = 1 }) end), awful.key({ modkey, "Control" }, "t",          function shifty.add({ rel_index = 1, nopopup = true }) end), awful.key({ modkey           }, "r",           shifty.rename), awful.key({ modkey           }, "w",           shifty.del),

8. Remplacez les raccourcis claviers Super+1, …, Super+9 par ceux-ci : for i=1,9 do globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey }, i,  function local t = awful.tag.viewonly(shifty.getpos(i)) end)) globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey, "Control" }, i, function local t = shifty.getpos(i) t.selected = not t.selected end)) globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey, "Control", "Shift" }, i, function if client.focus then awful.client.toggletag(shifty.getpos(i)) end end)) -- déplace les clients vers d’autres onglets globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey, "Shift" }, i,   function if client.focus then local t = shifty.getpos(i) awful.client.movetotag(t) awful.tag.viewonly(t) end end)) end

Remarquez que shifty opère sur les liens numériques en accord avec l’attribut position (comment ça marche ?) avec une fonction appelée 'getpos''.

La fonction shifty.getpos est conçue pour gérer les combinaisons Super+1, …, Super+9 en mappant les attributs position des onglets :
 * si l’onglet à la position i existe, on s’y déplace, à condition que le deuxième argument switch soit true ;
 * s’il y a plus d’un onglet avec la position i, Super+i vous fera circuler parmi tous ceux-ci ;
 * si aucun onglet n’existe avec la position i, un nouvel onglet sera créé à cette position, en utilisant les paramètres par défaut de config.tags ;
 * s’il n’y a pas de paramètre par défaut, shifty crée un onglet qui s’appelle « i:  » et lance l’invite pour lui donner un nom.

9. Les définitions suivantes disent à shifty ce qui se passe : -- Mise en place des raccourcis root.keys(globalkeys) shifty.config.globalkeys = globalkeys shifty.config.clientkeys = clientkeys

10. Vous avez réussi ! Maintenant, quand vous lancerez awesome, il n’y aura aucun onglet créé sauf si vous l’avez demandé dans la configuration initiale avec le drapeau init. Dans le premier cas, un nouvel onglet sera créé à l’ouverture d’une fenêtre qui n’a pas de configuration prédéfinie, et son nom sera celui de la classe du client, ou bien « new » si shifty.config.guess est false ou non définie. Si vous lancez Firefox, un nouvel onglet « www » sera créé. Si vous ouvrez une console virtuelle, un nouvel onglet « term » sera créé. Si vous vous déplacez sur « www » et que vous lancez une autre console virtuelle, vous irez directement sur l’onglet « term » pour y voir son ouverture. Si vous avez mis nopopup pour les clients qui sont liés à « term », ils seront encore ouverts dans l’onglet prédéfini, mais en fond, c’est-à-dire que vous ne vous déplacerez pas vers cet onglet. Et ainsi de suite…

Explications de l’exemple
Voici le descriptif du code mis au point 5. :
 * l’onglet « gimp » aura du texte et une icône sur lui, alors que l’onglet « p2p » n’aura qu’une icône ;
 * persist oblige l’onglet « term » à ne pas être détruit quand la dernière console virtuelle est fermée ;
 * init force la création de l’onglet « sys » au démarrage. Cela implique persist ;
 * screen dit à l’onglet « sys » qu’il ne doit être créé que sur l’écran nº1 ;
 * position fait que l’onglet « sys » est toujours inséré le premier dans la liste, « term » en deuxième et « www » en troisième ;
 * mwfact donne un facteur de 0,60 (60%) à la taille de la fenêtre maître de l’onglet ;
 * nopopup oblige l’onglet « ardour » à ne pas être au premier plan à sa création ;
 * l’option leave_kills signifie que l’onglet « ardour » ne sera pas détruit après que la dernière fenêtre présente dessus soit fermée, sauf si vous allez vers un autre onglet. Remarquez que les onglets ne seront pas détruits avant qu’ils aient été utilisés, c’est-à-dire avant qu’ils aient un client ;
 * exclusive permet de bouger vers un nouvel onglet tout client ouvert dans l’onglet « www », qui ne lui est pas lié dans config.apps, sauf s’il est marqué avec intrusive, comme c’est le cas pour « gcolor2 » et « xmag » ;
 * max_clients force « www » à n’accepter qu’un seul client. Si plus d’une fenêtre est ouverte, un nouvel onglet « www » sera créé pour l’accueillir. Vous pouvez naviguer parmi ces onglets avec Super+3 ;
 * donner à rel_index la valeur 1 dit à l’onglet « fs » de rester toujours ouvert à côté de l’onglet actuel et pas à la fin. Si on mettait rel_index = 0, ça le créerait à la position actuelle de la liste des onglets, juste avant l’onglet courant ;
 * spawn définit le nom du programme, ici Firefox, à exécuter quand l’onglet « www » est créé ; en combinaison avec position, cela permet de lancer Firefox en appuyant sur Super+3 ;
 * run définit une fonction qui est lancée à la création d’un onglet ; dans l’exemple ci-dessus, cela demande à naughty d’afficher une notification avec un nom à chaque création d’onglet ;
 * float demande à ce que recordMyDesktop, MPlayer et xmag soient en clients flottants ;
 * geometry force la création de la fenêtre gcolor2aux coordonnées (100,100). Le format de tableau est {x,y,w,h} ;
 * slave oblige les fenêtres d’images de Gimp à être esclaves : les boîtes à outils sont maîtres.

Remarquez que la liaison des clients et des onglets par config.apps est faite par rôle, instance, classe, type et titre. Elle supporte des motifs via string.find donc si vous liez quelque chose d’autre que le titre, que vous devriez utiliser une liaison aussi juste que possible. Exemple : "^Iceweasel$".

Dans le champ « tag » de config.apps, vous pouvez même fournir les noms d’onglets qui n’ont pas de paramètres par défaut dans config.tags : ils seront créés avec le nom de config.apps et d’après config.defaults s’il y en a un.

Le fait de lancer shifty.init après la mise en place des variables de configuration crée les onglets configurés avec le drapeau init.

Remarquez bien l’utilisation de l’entrée { match = "" }, … dans config.apps : vous devez utiliser ça si vous voulez que les client aient des boutons.

Options disponibles
Les options disponibles sont les suivantes :


 * config.tags et config.defaults peuvent prendre les valeurs : layout, mwfact, nmaster, ncol, exclusive, solitary, persist, nopopup, leave_kills, position, icon, icon_only, sweep_delay, keys, overload_keys, index, rel_index, run, spawn, screen ;
 * config.apps accepte : screen, tag, float, geometry, slave, nopopup, nofocus, intrusive, fullscreen, honorsizehints, kill, ontop, below, above, buttons, keys, hide, minimized, dockable, urgent, opacity, titlebar, run, sticky, wfact, struts ;
 * config.guess_name : si cette variable est à true, qui est la valeur par défaut, shifty essaiera de mettre des noms des nouveaux onglets correspondant aux noms des classes de clients. Ceci n’a d’effet que lorsqu’un client n’est pas lié et est ouvert quand il n’y a pas d’onglet ou que l’onglet actuel dispose des options solitary ou exclusive (commit)  ;
 * config.guess_position : si elle reçoit la valeur par défaut true, shifty regardera si le premier caractère d’un nom d’onglet est un nombre et mettra la position de cet onglet en conséquence. Fournir une position explicitement outrepasse ce fonctionnement (commit)  ;
 * config.remember_index : si mise à la valeur par défaut true, shifty gardera une trace de l’index de la liste d’onglets et si un onglet est fermé, il sera rouvert à la même position. Les options suivantes outrepassent ce comportement : position, index ou rel_index (commit)  ;
 * config.layouts : si on lui passe un tableau de fonctions de dispositions, permet de paramétrer les dispositions par leur nom (commit)  ;
 * config.clientkeys : le tableau par défaut des clés de clients (commit)  ;
 * config.globalkeys : tableau par défaut des clés globales (commit)  ;
 * config.prompt_sources et config.prompt_matchers : config pour complétion (commit).

Support
Si vous avez des problèmes, des suggestions ou des commentaires, vous pouvez discuter avec Koniu ou Bioe007 sur le canal #awesome, utiliser la liste de diffusion ou la page de discussion du wiki. Remarquez que l’interface de programmation est potentiellement sujette à modifications, donc vérifiez cette page et le journal des changements, surtout si vous avez mis à jour et que quelque chose a arrêté de fonctionner. Si vous choisissez d’utiliser shifty, essayez de rester à jour avec les versions git de shifty et d’awesome : des changements, améliorations et corrections de bogues se produisent tout le temps.

Bogues

 * awful.tag.history est un niveau qui résulte en des modifications imprévisibles, par exemple en supprimant de nombreux onglets à la suite ;
 * quand on renomme un onglet d’un nom pré-établi vers un autre, la disposition n’est pas toujours écrasée et reste sur l’ancienne ;
 * l’alignement de l’invite de renommage est bizarre avec taglist_squares (corrigé ici ou là)

À faire

 * mettre à jour les instructions sur le wiki (partiellement fait) ;
 * permettre de lier des clients à plusieurs onglets : c’est fait ;
 * tester un peu plus le multi-écrans ;
 * corriger l’historique ;
 * nettoyer et séparer les mises en place et les liaisons, notamment les calculs d’onglet- ou écran-cible et l’indexage des onglets ;
 * utiliser awful.client.property{set,get} ;
 * autoriser l’alignement des onglets à droite de la liste d’onglets ;
 * repenser la syntaxe de liaison des clients ;
 * lier de façon plus spécifique (match = { class = "URxvt", inst = "urxvt", }) avec potentiellement plus de liaisons (geom) ;
 * logique et agrégation : AND et OR.

Shifty et eminent
Shifty a été inspirée par eminent et utilisait des morceaux de son code par le passé. Eminent était une autre extension du même genre de gestion dynamique des onglets. Elle avait été développée quand l’interface de programmation d’awesome n’était pas aussi flexible que maintenant et quand il manquait un certain nombre de défauts : les onglets étaient effectivement pré-créés mais les onglets vides restaient cachés. Eminent est maintenant considérée obsolète.