Ceci est une ancienne révision du document !
Awesome
Awesome est un « Window Manager » minimaliste, très léger et donc extrêmement rapide, conçu pour être utilisé sans souris et spécialement optimisé pour le "multiscreen". C'est un gestionnaire de fenêtre qui utilise la technique dite du "tiling"; comprendre par là que le maximum de l'écran sera toujours utilisé pour les fenêtres et celles-ci ne se chevaucheront jamais. A noter qu'il y a plusieurs modes de tiling disponibles. Néanmoins, le mode "floating" (fenêtres "volantes") peut être utilisé également.
Dans sa conception, awesome ressemble assez à ion ou encore Wmii .
Le gestionnaire de fenêtres (WM, « Window Manager ») Awesome est basé sur le code de dwm, qu'il tente d'améliorer en gardant les idées du concept de base de ce gestionnaire, tout en l'améliorant grandement en terme d'usabilité et d'interface (support Xft, Cairo, etc.).
Comme une image vaut mieux qu'un long discours, voici à quoi cela ressemble:
Pré-requis
- Disposer des droits d'administration.
- Disposer d'une connexion à Internet configurée et activée.
Installation
Awesome se trouve déjà dans les dépôts officiels. Il suffit d’installer les paquets awesome et awesome-extra.
le paquet awesome-extra fournit de nombreux widgets supplémentaires (l'usage de la mémoire, la vitesse bande passante, etc ).
La compilation (fastidieuse) de awesone n'est utile que pour ceux qui ont réellement besoin de la toute dernière version,
En compilant les sources
Vous pouvez aussi compiler les sources, en vous rendant sur le git de Awesome vous possèderez les dernières modifications : http://git.naquadah.org/
Décompressez l'archive, mettez vous dans le dossier obtenu puis tapez :
./configure && make && sudo make install
Si il y a une erreur lors du ./configure, installez la librairie requise.
Ou bien, notamment si vous êtes sous Hardy : http://awesome.naquadah.org/wiki/index.php?title=Ubuntu_Hardy
Configuration Version 3 (Karmic et ultérieur)
La syntaxe du fichier de configuration a complètement changé avec la version 3 d'Awesome. Celui-ci utilise désormais le langage lua, ce qui facilite grandement la personnalisation.
En effet, un des intérêts principaux d'Awesome est de se forger un environnement entièrement personnalisé et dans lequel on se sent à l'aise et productif.
Vous pouvez consulter la documentation officielle sur la configuration d'awesome 3.
Pensez aussi à regarder les notes de changements entre versions:
Configuration
Passons à la partie vraiment intéressante
Il faut commencer par créer le dossier qui contiendra les fichiers de configuration dans le home:
mkdir ~/.config/awesome
Ensuite, afin d'avoir une base, on copie de le fichier de configuration par défaut:
cp /etc/xdg/awesome/rc.lua ~/.config/awesome/rc.lua
Il est aussi possible de copier le fichier de thème afin de les personnaliser:
cp -R /usr/share/awesome/* ~/.config/awesome
Raccourcis claviers
Les principaux sont les suivants:
- Meta = Touche Windows (entre Ctrl gauche et Alt)
- Meta + Entrer ⇒ ouvre un terminal
- Meta + Fleche Droite ⇒ passer au bureau de droite
- Meta + Fleche Gauche ⇒ passer au bureau de gauche
- Meta + F1 ⇒ lanceur d'un manuel pour une application
Les raccourcis par défaut sont pensés pour un clavier QWERTY. Si vous utilisez un clavier QWERTZ, les raccourcis seront également bien adaptés mais si vous utilisez un clavier azerty, je vous recommande de modifier le fichier de configuration pour avoir quelque chose comme:
tagkeys = { '#10', '#11', '#12', '#13', '#14', '#15', '#16', '#17', '#18', '#19', '#20' } for i = 1, keynumber do keybinding({ modkey }, tagkeys[i], function () local screen = mouse.screen if tags[screen][i] then awful.tag.viewonly(tags[screen][i]) end end):add() keybinding({ modkey, "Control" }, tagkeys[i], function () local screen = mouse.screen if tags[screen][i] then tags[screen][i].selected = not tags[screen][i].selected end end):add() keybinding({ modkey, "Shift" }, tagkeys[i], function () if client.focus then if tags[client.focus.screen][i] then awful.client.movetotag(tags[client.focus.screen][i]) end end end):add() keybinding({ modkey, "Control", "Shift" }, tagkeys[i] , function () if client.focus then if tags[client.focus.screen][i] then awful.client.toggletag(tags[client.focus.screen][i]) end end end):add() end
qui vous permet d'utiliser les numéros des tags plus facilement sur un clavier en azerty. ( Mod4+guillemet pour aller au bureau n°3, par exemple)
Raccourcis claviers Perso pour lancer des applications
Il est possible de rajouter ses propres raccourcis afin de lancer des applications, un exemple:
awful.key({ modkey,"Mod1"}, "f", function () awful.util.spawn("firefox") end),
Cette ligne (a placer dans la section KeysBindings) vous permet de lancer Firefox via SUPER+ALT+f, quelques explications:
- awful.key: permet de créer le raccourci
- { modkey,"Mod1"}, "f",: combinaison de touches a maintenir
- awful.util.spawn: permet de lancer une commande
Configurer et les "layouts" par défaut et renommer les "tags"
Par défaut, les "layouts" sont en mode "float" pour tous les tags (nb: un tag correspond plus ou moins à un bureau virtuel). Cependant, il est possible de configurer chaque tag avec un layout particulier. Par exemple, j'aime bien avoir mon navigateur web en mode "float" pour ne pas avoir une fenêtre de notification qui occupe la moité de mon écran quand elle apparaît. Pour ceci, il faut repérer la partie Tags de votre rc.lua (plutôt au début) et la remplacer par celle-ci:
-- {{{ Tags -- Define a tag table which hold all screen tags. tags = { names = { "sec", "main", "dev", "web", "im", "mus" }, layout = { layouts[2], layouts[2], layouts[2], layouts[1], layouts[2], layouts[2]} } for s = 1, screen.count() do tags[s] = awful.tag(tags.names, s, tags.layout) end -- }}}
Vous pouvez noter que dans names
, on a les noms des tags (qui remplacent donc les chiffres de 1-9 par défaut). Vous pouvez en ajouter/enlever comme bon vous semble ainsi que les renommer.
Les layouts (layouts[2]
par exemple) correspondent au layouts définit dans le tableau au dessus dans votre rc.lua. Ainsi, layouts[2]
correspond au mode tile normal et layouts[1] correspond au mode float. Vous pouvez donc remplacer le numéro celui qui correspond à n'importe lequel des 12 layouts disponibles. Notez bien que les arrays names
et layout
doivent avoir la même taille!
Lancer des applications au demarrage
Pour lancer des applications au demarrage rien de plus simple, il suffit de rajouter cette ligne (en fin de fichier rc.lua) pour lancer nm-applet (applet de Network-Manager)
os.execute("nm-applet &")
ou
awful.util.spawn("nm-applet &")
Bien evidemment ceci est valable pour tout les executables que vous voudriez lancer au demarrage :D
Ajouter des widgets
La zone de notification se situe par défaut en haut à droite, à côté de l'horloge. Il est très facile d'écrire des widgets en lua afin de, par exemple, afficher des notifications à propos de l'état de la batterie ou encore créer un applet de son. J'en ai écrit quelques uns et j'en ai pompé aussi du wiki du site officiel et comme je les trouves forts bien pratique, je les partages ici. Libre à vous de les adapter/modifier comme bon vous semble et surtout, comme cela vous convient!
Pour avoir une idée du rendu, voici une capture de la zone de widget:
Il faut savoir que pour que les widgets apparaissent, il faut qu'ils soient mentionnés dans la liste des widgets (mywibox) de votre rc.lua qui ressemble à quelque chose comme ça:
-- Create the wibox mywibox[s] = awful.wibox({ position = "top", screen = s }) -- Add widgets to the wibox - order matters mywibox[s].widgets = { { mylauncher, mytaglist[s], mypromptbox[s], layout = awful.widget.layout.horizontal.leftright }, mylayoutbox[s], mymail, s == 1 and mysystray or nil, tb_volume, mytextclock, batinfo, meminfo, cputemp, cpuinfo, tb_moc, mytasklist[s], layout = awful.widget.layout.horizontal.rightleft }
Applet pour le son
L'applet suivant permet de contrôler le son. Possibilité notamment de régler le volume avec la molette de la souris quand cette dernière est au-dessus. Il indique également, en pourcentage, le volume sonore et s'il est muet ou non.
Une première chose avant de passer au code de l'applet lui-même: pour ceux qui ont des raccourcis multimédias (touches pour le son dans notre cas, qui sont très courantes sur les ordinateurs portables), il est intéressant de les faire fonctionner. Pour cela, il faut rajouter ces lignes dans la partie "keybindings" de votre rc.lua (cela ne marchera pas tout de suite: il faut encore ajouter un bout de code (voir suite)):
-- Multimedia keys awful.key({ }, "XF86AudioRaiseVolume", function () volume("up", tb_volume) end), awful.key({ }, "XF86AudioLowerVolume", function () volume("down", tb_volume) end), awful.key({ }, "XF86AudioMute", function () volume("mute", tb_volume) end)
On va maintenant s'occuper du code qui gère le son. Il vous suffit de copier/coller ce bout de code plutôt vers le début de votre rc.lua:
-- Sound Control cardid = 0 channel = "Master" function volume (mode, widget) if mode == "update" then local fd = io.popen("amixer -c " .. cardid .. " -- sget " .. channel) local status = fd:read("*all") fd:close() local volume = string.match(status, "(%d?%d?%d)%%") volume = string.format("% 3d", volume) status = string.match(status, "%[(o[^%]]*)%]") if string.find(status, "on", 1, true) then volume = "| Vol:<span color='green'>" .. volume .. "</span>% " else volume = "| Vol:<span color='red'>" .. volume .. "</span>M " end widget.text = volume elseif mode == "up" then io.popen("amixer -q -c " .. cardid .. " sset " .. channel .. " 5%+"):read("*all") volume("update", widget) elseif mode == "down" then io.popen("amixer -q -c " .. cardid .. " sset " .. channel .. " 5%-"):read("*all") volume("update", widget) else io.popen("amixer -c " .. cardid .. " sset " .. channel .. " toggle"):read("*all") volume("update", widget) end end
Maintenant que cela est fait, passons à l'applet lui-même. Copiez/collez ce bout dans code dans la section widget de votre rc.lua:
-- Create Volume Control Widget tb_volume = widget({ type = "textbox", name = "tb_volume", align = "right" }) tb_volume:buttons(awful.util.table.join( awful.button({ }, 4, function () volume("up", tb_volume) end), awful.button({ }, 5, function () volume("down", tb_volume) end), awful.button({ }, 1, function () volume("mute", tb_volume) end) )) volume("update", tb_volume) -- refresh the Volume Control Widget tb_volume_timer = timer({ timeout = 10 }) tb_volume_timer:add_signal("timeout", function () volume("update", tb_volume) end) tb_volume_timer:start()
N'oubliez pas non plus de rajouter tb_volume
dans la liste des widgets.
Applet pour mocplayer (mocp)
Maintenant que les touches son et l'applet de son fonctionne, il est intéressant d'avoir un applet pour un lecteur de musique.
Comme pour le son, il faut d'abord le bout de code qui permet de gérer mocp avant de passer au wigdet lui-même. Ceci est à placer au début de votre rc.lua:
-- Enable mocp function moc_control (action) local moc_info,moc_state if action == "next" then io.popen("mocp --next") elseif action == "previous" then io.popen("mocp --previous") elseif action == "stop" then io.popen("mocp --stop") elseif action == "play_pause" then moc_info = io.popen("mocp -i"):read("*all") moc_state = string.gsub(string.match(moc_info, "State: %a*"),"State: ","") if moc_state == "PLAY" then io.popen("mocp --pause") elseif moc_state == "PAUSE" then io.popen("mocp --unpause") elseif moc_state == "STOP" then io.popen("mocp --play") end end end
Maintenant que ceci est fait, il est aussi intéressant de rajouter des raccourcis clavier qui permettent de le contrôler facilement. Donc le bout de code suivant va dans la partie "keybindings" de votre rc.lua:
awful.key({ "Control", }, "Right", function () moc_control("next") end), awful.key({ "Control", }, "Left", function () moc_control("previous") end), awful.key({ "Control", }, "Up", function () moc_control("stop") end), awful.key({ "Control", }, "Down", function () moc_control("play_pause") end)
Passons maintenant à l'applet lui-même:
-- Moc Widget tb_moc = widget({ type = "textbox", align = "right" }) function hook_moc() moc_info = io.popen("mocp -i"):read("*all") moc_state = string.gsub(string.match(moc_info, "State: %a*"),"State: ","") if moc_state == "PLAY" or moc_state == "PAUSE" then moc_artist = string.gsub(string.match(moc_info, "Artist: %C*"), "Artist: ","") moc_title = string.gsub(string.match(moc_info, "SongTitle: %C*"), "SongTitle: ","") moc_curtime = string.gsub(string.match(moc_info, "CurrentTime: %d*:%d*"), "CurrentTime: ","") moc_totaltime = string.gsub(string.match(moc_info, "TotalTime: %d*:%d*"), "TotalTime: ","") if moc_artist == "" then moc_artist = "unknown artist" end if moc_title == "" then moc_title = "unknown title" end -- moc_title = string.format("%.5c", moc_title) moc_string = moc_artist .. " - " .. moc_title .. "(" .. moc_curtime .. "/" .. moc_totaltime .. ")" if moc_state == "PAUSE" then moc_string = "PAUSE - " .. moc_string .. "" end else moc_string = "-- not playing --" end return moc_string end -- refresh Moc widget moc_timer = timer({timeout = 1}) moc_timer:add_signal("timeout", function() tb_moc.text = '| ' .. hook_moc() .. ' ' end) moc_timer:start()
N'oubliez pas non-plus de rajouter tb_moc
dans la wibox.
Applet d'indication de l'état de la batterie
Cet applet n'est utile que pour ceux qui utilisent un ordinateur portable
Il faut d'abord vérifier le numéro de la batterie pour le remplacer dans le bout de code qui suit. Pour cela, allez faire un tour dans /proc/acpi/battery
et vérifiez si c'est dans BAT0 ou BAT1 qu'il y a les infos. Chez moi, les infos sont dans BAT0 mais si chez vous c'est dans BAT1 il faut alors remplacer en conséquence dans le bout de code qui suit:
-- Battery status Widget -- get the full capacity of the battery for line in io.lines("/proc/acpi/battery/BAT0/info") do bat_stat = string.match(line, "last full capacity:\ +(%d+)") if bat_stat then -- define stat_tot for reuse later for battery status stat_tot = bat_stat end end function activebat() local stat_actu, res for line in io.lines("/proc/acpi/battery/BAT0/state") do local present = string.match(line, "present:\ +(%a+)") if (present == "no") then return '<span color="red">not present</span>' end local status = string.match(line, "remaining capacity:\ +(%d+)") local state = string.match(line, "charging state:\ +(%a+)") if status then stat_actu = status end if state then stat_bat = state end end res = string.format("%.2f", (stat_actu/stat_tot) * 100); if ((stat_actu/stat_tot) * 100) < 10 then res = '<span color="red">' .. res .. '</span>' elseif ((stat_actu/stat_tot) * 100) < 20 then res = '<span color="orange">' .. res .. '</span>' elseif ((stat_actu/stat_tot) * 100) < 30 then res = '<span color="yellow">' .. res .. '</span>' elseif ((stat_actu/stat_tot) * 100) >= 100 then return '<span color="green">fully charged</span>' else res = '<span color="green">' .. res .. '</span>' end if (stat_bat == 'discharging') then stat_bat = '<span color="red">discharging</span>' elseif (stat_bat == 'charging') then stat_bat = '<span color = "green">charging</span>' end res = res .. '% ' .. stat_bat return res end batinfo = widget({ type = "textbox" , name = "batinfo" }) -- Assign a hook to update info -- awful.hooks.timer.register(1, function() batinfo.text = "BAT: " .. activebat() .. " |" end) activebat_timer = timer({timeout = 1}) activebat_timer:add_signal("timeout", function() batinfo.text = "BAT: " .. activebat() .. " |" end) activebat_timer:start()
Et comme d'habitude, n'oubliez pas de rajouter batinfo
dans la wibox.
Applet d'indication de l'état d'utilisation de la mémoire RAM
Comme je ne vais pas chercher la taille de votre mémoire RAM automatiquement (ce n'est pas quelque chose qui change souvent ), il faut juste indiquer le total correspondant (chez moi c'est 2056100). Pour savoir la quantité exact de RAM, utilisez cette commande:
cat /proc/meminfo | grep MemTotal
-- Create a RAM widget giving the MB used by the RAM -- declare memtot for reuse below memtot = 2056100 function activeram() local active, ramusg, res for line in io.lines("/proc/meminfo") do for key , value in string.gmatch(line, "(%w+):\ +(%d+).+") do if key == "Active" then active = tonumber(value) end end end ramusg = (active/memtot)*100 res = string.format("%.2f", (active/1024)) if ramusg < 51 then res = '<span color="green">' .. res .. '</span>MB (<span color="green">' .. string.format("%.2f",ramusg) .. '</span>%)' elseif ramusg < 71 then res = '<span color="yellow">' .. res .. '</span>MB (<span color="green">' .. string.format("%.2f",ramusg) .. '</span>%)' elseif ramusg < 86 then res = '<span color="orange">' .. res .. '</span>MB (<span color="green">' .. string.format("%.2f",ramusg) .. '</span>%)' else res = '<span color="red">' .. res .. '</span>MB (<span color="green">' .. string.format("%.2f",ramusg) .. '</span>%)' end return res end meminfo = widget({ type = "textbox", name = "meminfo" }) -- Assign a hook to update info meminfo_timer = timer({timeout = 1}) meminfo_timer:add_signal("timeout", function() meminfo.text = activeram() .. " | " end) meminfo_timer:start()
Et de nouveau, il faut ajouter meminfo
dans la wibox.
Applet du taux d'utilisation du CPU et de sa température
-- Create a CPU widget jiffies = {} function activecpu() local s, str for line in io.lines("/proc/stat") do local cpu,newjiffies = string.match(line, "(cpu)\ +(%d+)") if cpu and newjiffies then if not jiffies[cpu] then jiffies[cpu] = newjiffies end -- The string.format prevents your task list from jumping around -- When CPU usage goes above/below 10% str = string.format("%02d", newjiffies-jiffies[cpu]) if str < "31" then str = '<span color="green">' .. str .. '</span>' elseif str < "51" then str = '<span color="yellow">' .. str .. '</span>' elseif str < "70" then str = '<span color="orange">' .. str .. '</span>' else str = '<span color="red">' .. str .. '</span>' end s = '| CPU: ' .. str .. '% ' jiffies[cpu] = newjiffies end end return s end cpuinfo = widget({ type = "textbox", name = "cpuinfo" }) -- register the hook to update the display cpuinfo_timer = timer({timeout = 1}) cpuinfo_timer:add_signal("timeout", function() cpuinfo.text = activecpu() end) cpuinfo_timer:start() -- Create CPU Temp Widget function activecputemp() local temp io.input("/sys/bus/acpi/devices/LNXTHERM\:00/thermal_zone/temp") temp = io.read("*number")/1000 if temp < 46 then temp = '<span color="turquoise">' .. temp .. '</span>' elseif temp < 61 then temp = '<span color="yellow">' .. temp .. '</span>' elseif temp < 76 then temp = '<span color="orange">' .. temp .. '</span>' else temp = '<span color="red">' .. temp .. '</span>' end return temp end cputemp = widget({ type = "textbox" , name = "cputemp" }) -- Assign a hook to update temperature -- awful.hooks.timer.register(1, function() cputemp.text = "@ " .. activecputemp() .. "°C | RAM: " end) cputemp_timer = timer({timeout = 1}) cputemp_timer:add_signal("timeout", function() cputemp.text = "@ " .. activecputemp() .. "°C | RAM: " end) cputemp_timer:start()
Ajoutez encore cpuinfo
et cputemp
dans la wibox en suivant cet ordre afin que l'affichage soit correct (il s'agit de deux widgets différents).
Applet de notification des emails pour Gmail
Cet applet va vérifier s'il y a des emails non-lus sur votre compte Gmail et notifie le nombre via un numéro. Tout d'abord, il faut créer un dossier dans votre home:
mkdir ~/scripts
Dans ce dossier, créez un fichier nommé unread.py
et copiez/collez-y ce script python en prenant soin de renseigner votre adresse email ainsi que votre mot de passe.
#!/usr/bin/python import imaplib #first field is imap server, second - port (993 for gmail SSL IMAP) M=imaplib.IMAP4_SSL("imap.gmail.com", 993) #first field is imap login (gmail uses login with domain and '@' character), second - password M.login("adress@gmail.com","password") status, counts = M.status("Inbox","(MESSAGES UNSEEN)") unread = counts[0].split()[4][:-1] if unread == "0": print " 0 " else: #red bg color when you have unseen mail print unread M.logout()
Il est également nécessaire de créer un fichier qui sera utilisé comme tampon:
touch ~/tmp/gmail
Maintenant, il faut ajouter ce bout de code dans votre rc.lua pour le widget en prenant soin de remplacer le chemin du fichier tmp pour gmail par le votre:
-- GMail Widget mymail = widget({ type = "textbox", align = "right" }) mymail.text = ' <span color="red" background="white" font="bold">|V|</span>' awful.hooks.timer.register(30, function () local f = io.open("/home/VOTRE_NOM_DE_USER/tmp/gmail") local l = nil if f ~= nil then l = f:read() -- read output of command else l = "gmail" end f:close() if l ~= "0" then l = '<span font="bold" color="red">' .. l .. '</span>' else l = '' end mymail.text = ' <span color="red" background="white" font="bold">|V|</span>' .. l os.execute("~/scripts/unread.py > ~/tmp/gmail &") end)
Ajouter encore mymail
dans la wibox.
Exemple de rc.lua
Pour les flemmard qui ne veulent pas tout écrire eux-même ou pour ceux qui veulent s'en inspirer, voici mon rc.lua complet:
-- Standard awesome library require("awful") require("awful.autofocus") require("awful.rules") -- Theme handling library require("beautiful") -- Notification library require("naughty") -- Sound Widget cardid = 0 channel = "Master" function volume (mode, widget) if mode == "update" then local fd = io.popen("amixer -c " .. cardid .. " -- sget " .. channel) local status = fd:read("*all") fd:close() local volume = string.match(status, "(%d?%d?%d)%%") volume = string.format("% 3d", volume) status = string.match(status, "%[(o[^%]]*)%]") if string.find(status, "on", 1, true) then volume = "| Vol:<span color='green'>" .. volume .. "</span>% " else volume = "| Vol:<span color='red'>" .. volume .. "</span>M " end widget.text = volume elseif mode == "up" then io.popen("amixer -q -c " .. cardid .. " sset " .. channel .. " 5%+"):read("*all") volume("update", widget) elseif mode == "down" then io.popen("amixer -q -c " .. cardid .. " sset " .. channel .. " 5%-"):read("*all") volume("update", widget) else io.popen("amixer -c " .. cardid .. " sset " .. channel .. " toggle"):read("*all") volume("update", widget) end end -- Enable mocp function moc_control (action) local moc_info,moc_state if action == "next" then io.popen("mocp --next") elseif action == "previous" then io.popen("mocp --previous") elseif action == "stop" then io.popen("mocp --stop") elseif action == "play_pause" then moc_info = io.popen("mocp -i"):read("*all") moc_state = string.gsub(string.match(moc_info, "State: %a*"),"State: ","") if moc_state == "PLAY" then io.popen("mocp --pause") elseif moc_state == "PAUSE" then io.popen("mocp --unpause") elseif moc_state == "STOP" then io.popen("mocp --play") end end end -- {{{ Variable definitions -- Themes define colours, icons, and wallpapers beautiful.init("/usr/share/awesome/themes/shertheme/theme.lua") -- This is used later as the default terminal and editor to run. --terminal = "xterm" terminal = "urxvtc" editor = os.getenv("EDITOR") or "vim" editor_cmd = terminal .. " -e " .. editor -- Default modkey. -- Usually, Mod4 is the key with a logo between Control and Alt. -- If you do not like this or do not have such a key, -- I suggest you to remap Mod4 to another key using xmodmap or other tools. -- However, you can use another modifier like Mod1, but it may interact with others. modkey = "Mod4" -- Table of layouts to cover with awful.layout.inc, order matters. layouts = { awful.layout.suit.floating, awful.layout.suit.tile, awful.layout.suit.tile.left, awful.layout.suit.tile.bottom, awful.layout.suit.tile.top, awful.layout.suit.fair, awful.layout.suit.fair.horizontal, awful.layout.suit.spiral, awful.layout.suit.spiral.dwindle, awful.layout.suit.max, awful.layout.suit.max.fullscreen, awful.layout.suit.magnifier } -- }}} -- {{{ Tags -- Define a tag table which hold all screen tags. tags = { names = { "sec", "main", "dev", "web", "im", "mus" }, layout = { layouts[2], layouts[2], layouts[2], layouts[1], layouts[2], layouts[2]} } for s = 1, screen.count() do tags[s] = awful.tag(tags.names, s, tags.layout) end -- }}} -- {{{ Menu -- Create a laucher widget and a main menu myawesomemenu = { { "manual", terminal .. " -e man awesome" }, { "edit config", editor_cmd .. " " .. awful.util.getdir("config") .. "/rc.lua" }, { "restart", awesome.restart }, { "quit", awesome.quit } } mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon }, { "open terminal", terminal }, } }) mylauncher = awful.widget.launcher({ image = image(beautiful.awesome_icon), menu = mymainmenu }) -- }}} -- {{{ Wibox -- Create Volume Control Widget tb_volume = widget({ type = "textbox", name = "tb_volume", align = "right" }) tb_volume:buttons(awful.util.table.join( awful.button({ }, 4, function () volume("up", tb_volume) end), awful.button({ }, 5, function () volume("down", tb_volume) end), awful.button({ }, 1, function () volume("mute", tb_volume) end) )) volume("update", tb_volume) -- refresh the Volume Control Widget tb_volume_timer = timer({ timeout = 10 }) tb_volume_timer:add_signal("timeout", function () volume("update", tb_volume) end) tb_volume_timer:start() -- Moc Widget tb_moc = widget({ type = "textbox", align = "right" }) function hook_moc() moc_info = io.popen("mocp -i"):read("*all") moc_state = string.gsub(string.match(moc_info, "State: %a*"),"State: ","") if moc_state == "PLAY" or moc_state == "PAUSE" then moc_artist = string.gsub(string.match(moc_info, "Artist: %C*"), "Artist: ","") moc_title = string.gsub(string.match(moc_info, "SongTitle: %C*"), "SongTitle: ","") moc_curtime = string.gsub(string.match(moc_info, "CurrentTime: %d*:%d*"), "CurrentTime: ","") moc_totaltime = string.gsub(string.match(moc_info, "TotalTime: %d*:%d*"), "TotalTime: ","") if moc_artist == "" then moc_artist = "unknown artist" end if moc_title == "" then moc_title = "unknown title" end -- moc_title = string.format("%.5c", moc_title) moc_string = moc_artist .. " - " .. moc_title .. "(" .. moc_curtime .. "/" .. moc_totaltime .. ")" if moc_state == "PAUSE" then moc_string = "PAUSE - " .. moc_string .. "" end else moc_string = "-- not playing --" end return moc_string end -- refresh Moc widget --awful.hooks.timer.register(1, function() tb_moc.text = '| ' .. hook_moc() .. ' ' end) moc_timer = timer({timeout = 1}) moc_timer:add_signal("timeout", function() tb_moc.text = '| ' .. hook_moc() .. ' ' end) moc_timer:start() -- Create a CPU widget jiffies = {} function activecpu() local s, str for line in io.lines("/proc/stat") do local cpu,newjiffies = string.match(line, "(cpu)\ +(%d+)") if cpu and newjiffies then if not jiffies[cpu] then jiffies[cpu] = newjiffies end -- The string.format prevents your task list from jumping around -- When CPU usage goes above/below 10% str = string.format("%02d", newjiffies-jiffies[cpu]) if str < "31" then str = '<span color="green">' .. str .. '</span>' elseif str < "51" then str = '<span color="yellow">' .. str .. '</span>' elseif str < "70" then str = '<span color="orange">' .. str .. '</span>' else str = '<span color="red">' .. str .. '</span>' end s = '| CPU: ' .. str .. '% ' jiffies[cpu] = newjiffies end end return s end cpuinfo = widget({ type = "textbox", name = "cpuinfo" }) -- register the hook to update the display -- awful.hooks.timer.register(1, function() cpuinfo.text = activecpu() end) cpuinfo_timer = timer({timeout = 1}) cpuinfo_timer:add_signal("timeout", function() cpuinfo.text = activecpu() end) cpuinfo_timer:start() -- Create CPU Temp Widget function activecputemp() local temp io.input("/sys/bus/acpi/devices/LNXTHERM\:00/thermal_zone/temp") temp = io.read("*number")/1000 if temp < 46 then temp = '<span color="turquoise">' .. temp .. '</span>' elseif temp < 61 then temp = '<span color="yellow">' .. temp .. '</span>' elseif temp < 76 then temp = '<span color="orange">' .. temp .. '</span>' else temp = '<span color="red">' .. temp .. '</span>' end return temp end cputemp = widget({ type = "textbox" , name = "cputemp" }) -- Assign a hook to update temperature -- awful.hooks.timer.register(1, function() cputemp.text = "@ " .. activecputemp() .. "°C | RAM: " end) cputemp_timer = timer({timeout = 1}) cputemp_timer:add_signal("timeout", function() cputemp.text = "@ " .. activecputemp() .. "°C | RAM: " end) cputemp_timer:start() -- Battery status Widget -- get the full capacity of the battery for line in io.lines("/proc/acpi/battery/BAT0/info") do bat_stat = string.match(line, "last full capacity:\ +(%d+)") if bat_stat then -- define stat_tot for reuse later for battery status stat_tot = bat_stat end end function activebat() local stat_actu, res for line in io.lines("/proc/acpi/battery/BAT0/state") do local present = string.match(line, "present:\ +(%a+)") if (present == "no") then return '<span color="red">not present</span>' end local status = string.match(line, "remaining capacity:\ +(%d+)") local state = string.match(line, "charging state:\ +(%a+)") if status then stat_actu = status end if state then stat_bat = state end end res = string.format("%.2f", (stat_actu/stat_tot) * 100); if ((stat_actu/stat_tot) * 100) < 10 then res = '<span color="red">' .. res .. '</span>' elseif ((stat_actu/stat_tot) * 100) < 20 then res = '<span color="orange">' .. res .. '</span>' elseif ((stat_actu/stat_tot) * 100) < 30 then res = '<span color="yellow">' .. res .. '</span>' elseif ((stat_actu/stat_tot) * 100) >= 100 then return '<span color="green">fully charged</span>' else res = '<span color="green">' .. res .. '</span>' end if (stat_bat == 'discharging') then stat_bat = '<span color="red">discharging</span>' elseif (stat_bat == 'charging') then stat_bat = '<span color = "green">charging</span>' end res = res .. '% ' .. stat_bat return res end batinfo = widget({ type = "textbox" , name = "batinfo" }) -- Assign a hook to update info -- awful.hooks.timer.register(1, function() batinfo.text = "BAT: " .. activebat() .. " |" end) activebat_timer = timer({timeout = 1}) activebat_timer:add_signal("timeout", function() batinfo.text = "BAT: " .. activebat() .. " |" end) activebat_timer:start() -- Create a RAM widget giving the MB used by the RAM -- declare memtot for reuse below memtot = 2056100 function activeram() local active, ramusg, res for line in io.lines("/proc/meminfo") do for key , value in string.gmatch(line, "(%w+):\ +(%d+).+") do if key == "Active" then active = tonumber(value) end end end ramusg = (active/memtot)*100 res = string.format("%.2f", (active/1024)) if ramusg < 51 then res = '<span color="green">' .. res .. '</span>MB (<span color="green">' .. string.format("%.2f",ramusg) .. '</span>%)' elseif ramusg < 71 then res = '<span color="yellow">' .. res .. '</span>MB (<span color="green">' .. string.format("%.2f",ramusg) .. '</span>%)' elseif ramusg < 86 then res = '<span color="orange">' .. res .. '</span>MB (<span color="green">' .. string.format("%.2f",ramusg) .. '</span>%)' else res = '<span color="red">' .. res .. '</span>MB (<span color="green">' .. string.format("%.2f",ramusg) .. '</span>%)' end return res end meminfo = widget({ type = "textbox", name = "meminfo" }) -- Assign a hook to update info -- awful.hooks.timer.register(1, function() meminfo.text = activeram() .. " | " end) meminfo_timer = timer({timeout = 1}) meminfo_timer:add_signal("timeout", function() meminfo.text = activeram() .. " | " end) meminfo_timer:start() -- Create a textclock widget mytextclock = awful.widget.textclock({ align = "right" }) -- Create a systray mysystray = widget({ type = "systray" }) -- Create a wibox for each screen and add it mywibox = {} mypromptbox = {} mylayoutbox = {} mytaglist = {} mytaglist.buttons = awful.util.table.join( awful.button({ }, 1, awful.tag.viewonly), awful.button({ modkey }, 1, awful.client.movetotag), awful.button({ }, 3, awful.tag.viewtoggle), awful.button({ modkey }, 3, awful.client.toggletag), awful.button({ }, 4, awful.tag.viewnext), awful.button({ }, 5, awful.tag.viewprev) ) mytasklist = {} mytasklist.buttons = awful.util.table.join( awful.button({ }, 1, function (c) if not c:isvisible() then awful.tag.viewonly(c:tags()[1]) end client.focus = c c:raise() end), awful.button({ }, 3, function () if instance then instance:hide() instance = nil else instance = awful.menu.clients({ width=250 }) end end), awful.button({ }, 4, function () awful.client.focus.byidx(1) if client.focus then client.focus:raise() end end), awful.button({ }, 5, function () awful.client.focus.byidx(-1) if client.focus then client.focus:raise() end end)) for s = 1, screen.count() do -- Create a promptbox for each screen mypromptbox[s] = awful.widget.prompt({ layout = awful.widget.layout.horizontal.leftright }) -- Create an imagebox widget which will contains an icon indicating which layout we're using. -- We need one layoutbox per screen. mylayoutbox[s] = awful.widget.layoutbox(s) mylayoutbox[s]:buttons(awful.util.table.join( awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end), awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end), awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end), awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end))) -- Create a taglist widget mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.label.all, mytaglist.buttons) -- Create a tasklist widget mytasklist[s] = awful.widget.tasklist(function(c) return awful.widget.tasklist.label.currenttags(c, s) end, mytasklist.buttons) -- Create the wibox mywibox[s] = awful.wibox({ position = "top", screen = s }) -- Add widgets to the wibox - order matters mywibox[s].widgets = { { mylauncher, mytaglist[s], mypromptbox[s], layout = awful.widget.layout.horizontal.leftright }, mylayoutbox[s], mymail, s == 1 and mysystray or nil, tb_volume, mytextclock, batinfo, meminfo, cputemp, cpuinfo, tb_moc, mytasklist[s], layout = awful.widget.layout.horizontal.rightleft } end -- }}} -- {{{ Mouse bindings root.buttons(awful.util.table.join( awful.button({ }, 3, function () mymainmenu:toggle() end), awful.button({ }, 4, awful.tag.viewnext), awful.button({ }, 5, awful.tag.viewprev) )) -- }}} -- {{{ Key bindings globalkeys = awful.util.table.join( awful.key({ modkey, }, "Left", awful.tag.viewprev ), awful.key({ modkey, }, "Right", awful.tag.viewnext ), awful.key({ modkey, }, "Escape", awful.tag.history.restore), awful.key({ modkey, }, "j", function () awful.client.focus.byidx( 1) if client.focus then client.focus:raise() end end), awful.key({ modkey, }, "k", function () awful.client.focus.byidx(-1) if client.focus then client.focus:raise() end end), awful.key({ modkey, }, "w", function () mymainmenu:show(true) end), -- Multimedia keys awful.key({ }, "XF86AudioRaiseVolume", function () volume("up", tb_volume) end), awful.key({ }, "XF86AudioLowerVolume", function () volume("down", tb_volume) end), awful.key({ }, "XF86AudioMute", function () volume("mute", tb_volume) end), awful.key({ "Control", }, "Right", function () moc_control("next") end), awful.key({ "Control", }, "Left", function () moc_control("previous") end), awful.key({ "Control", }, "Up", function () moc_control("stop") end), awful.key({ "Control", }, "Down", function () moc_control("play_pause") end), -- Layout manipulation awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end), awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end), awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end), awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end), awful.key({ modkey, }, "u", awful.client.urgent.jumpto), awful.key({ modkey, }, "Tab", function () awful.client.focus.history.previous() if client.focus then client.focus:raise() end end), -- Standard program awful.key({ modkey, }, "Return", function () awful.util.spawn(terminal) end), awful.key({ modkey, "Control" }, "r", awesome.restart), awful.key({ modkey, "Shift" }, "q", awesome.quit), awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end), awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end), awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end), awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end), awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end), awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end), awful.key({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end), awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end), -- Prompt awful.key({ modkey }, "r", function () mypromptbox[mouse.screen]:run() end), awful.key({ modkey }, "x", function () awful.prompt.run({ prompt = "Run Lua code: " }, mypromptbox[mouse.screen].widget, awful.util.eval, nil, awful.util.getdir("cache") .. "/history_eval") end) ) clientkeys = awful.util.table.join( awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end), awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end), awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ), awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end), awful.key({ modkey, }, "o", awful.client.movetoscreen ), awful.key({ modkey, "Shift" }, "r", function (c) c:redraw() end), awful.key({ modkey, }, "n", function (c) c.minimized = not c.minimized end), awful.key({ modkey, }, "m", function (c) c.maximized_horizontal = not c.maximized_horizontal c.maximized_vertical = not c.maximized_vertical end) ) -- Compute the maximum number of digit we need, limited to 9 keynumber = 0 for s = 1, screen.count() do keynumber = math.min(9, math.max(#tags[s], keynumber)); end -- Bind all key numbers to tags. -- Be careful: we use keycodes to make it works on any keyboard layout. -- This should map on the top row of your keyboard, usually 1 to 9. for i = 1, keynumber do globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey }, "#" .. i + 9, function () local screen = mouse.screen if tags[screen][i] then awful.tag.viewonly(tags[screen][i]) end end), awful.key({ modkey, "Control" }, "#" .. i + 9, function () local screen = mouse.screen if tags[screen][i] then awful.tag.viewtoggle(tags[screen][i]) end end), awful.key({ modkey, "Shift" }, "#" .. i + 9, function () if client.focus and tags[client.focus.screen][i] then awful.client.movetotag(tags[client.focus.screen][i]) end end), awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9, function () if client.focus and tags[client.focus.screen][i] then awful.client.toggletag(tags[client.focus.screen][i]) end end)) end clientbuttons = awful.util.table.join( awful.button({ }, 1, function (c) client.focus = c; c:raise() end), awful.button({ modkey }, 1, awful.mouse.client.move), awful.button({ modkey }, 3, awful.mouse.client.resize)) -- Set keys root.keys(globalkeys) -- }}} -- {{{ Rules awful.rules.rules = { -- All clients will match this rule. { rule = { }, properties = { border_width = beautiful.border_width, border_color = beautiful.border_normal, focus = true, keys = clientkeysl, floating = false, buttons = clientbuttons } }, { rule = { class = "MPlayer" }, properties = { floating = true } }, { rule = { class = "pinentry" }, properties = { floating = true } }, { rule = { class = "gimp" }, properties = { floating = true} }, -- Set Firefox to always map on tags number 4 of screen 1. { rule = { class = "Firefox" }, properties = { tag = tags[1][4], switchtotag = true } }, -- Set Pidgin to always map on tags number 5 of screen 1. { rule = { class = "Pidgin" }, properties = { tag = tags[1][5], switchtotag = true } }, -- Set Opera to always map on tags number 4 of screen 1. { rule = { class = "Opera" }, properties = { tag = tags[1][4], switchtotag = true } }, -- Set Okular to always map on tags number 2 of screen 1. { rule = { class = "Okular" }, properties = { tag = tags[1][2], switchtotag = true } }, } -- }}} -- {{{ Signals -- Signal function to execute when a new client appears. client.add_signal("manage", function (c, startup) -- Add a titlebar -- awful.titlebar.add(c, { modkey = modkey }) -- Enable sloppy focus c:add_signal("mouse::enter", function(c) if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier and awful.client.focus.filter(c) then client.focus = c end end) if not startup then -- Set the windows at the slave, -- i.e. put it at the end of others instead of setting it master. -- awful.client.setslave(c) -- Put windows in a smart way, only if they does not set an initial position. if not c.size_hints.user_position and not c.size_hints.program_position then awful.placement.no_overlap(c) awful.placement.no_offscreen(c) end end end) client.add_signal("unfocus", function(c) c.border_color = beautiful.border_focus end) client.add_signal("focus", function(c) c.border_color = beautiful.border_normal end) -- }}} -- Launch the network-manager applet awful.util.spawn('nm-applet') --awful.util.spawn('conky')
Astuce permettant de tester sans risques son rc.lua
Cela vous est peut-être déjà arrivé: une erreur dans le rc.lua et hop, on se retrouve avec quelque chose d'inutilisable. Voici deux astuces à combiner qui permettent de tester son rc.lua avant de l'utiliser.
Vérifier la syntaxe
Il suffit d'oublier de fermer une parenthèse ou d'oublier une virgule pour que la configuration ne marche pas. Afin d'éviter cela, il est possible de faire une vérification syntaxique du rc.lua:
awesome -k
Utiliser Xephyr pour tester la configuration
La commande ci-dessus permet uniquement de vérifier la syntaxe mais elle ne vous permet pas de tester les changements apportés à la configuration. Une astuce, tirée du wiki d'archlinux, propose d'utiliser Xephyr. L'idée est d'enregistrer ses modifications dans un nouveau rc.lua, par exemple rc.test.lua et de lancer awesome avec cette configuration dans Xephyr au moyen de l'option -c. Pour ce faire, passez la commande suivante (vous pouvez changer la résolution à loisir ) afin de lancer Xephyr (note: s'il n'est pas déjà installé, cliquez ici sur ce lien apt xserver-xephyr):
Xephyr -ac -br -noreset -screen 1024x600 :1 &
Une fois ceci fait, lancez awesome:
DISPLAY=:1.0 awesome -c ~/.config/awesome/rc.test.lua
Et voilà, plus qu'à vérifier que les changements apportés conviennent et le cas échéant, remplacer son rc.lua par le rc.test.lua
"Astuces" en rapport avec des logiciels annexes
Conky
Si vous desirez que votre conky (ou vos conky) ne puissient pas etre recouverts par les fenetres il suffit pour cela de rajouter (ou modifier) ces lignes dans votre conkyrc:
own_window_type panel own_window_hints below,sticky,skip_taskbar,skip_pager
Screenshots
A venir, merci de ne pas envahir cette section ;) Elle aura simplement pour but de donner un apercu des possibilitées ;)
Configuration Version 2 (Hardy et Jaunty)
Pour personnaliser Awesome, il suffit de modifier le fichier ~/.awesomerc.
Voici la syntaxe :
# commentaire section { variable = valeur sous_section { variable = valeur } type widget { variable = valeur sous_section { variable = valeur } } }
Il y a plusieurs sections : screen 0 : Ecran numéro 1, rules : Pour paramétrer des règles d'affichage pour certaines fenêtres en particulier, mouse : pour paramétrer la souris, keys : pour les raccourcis clavier
Donc notre fichier de configuration doit ressembler à ceci au départ :
screen 0 { } rules { } mouse { } keys { }
La barre de status
La barre de status est en réalité la barre de tâche, on peut lui donner de nombreuses possibilités, avant tout, il faut la créer :
screen 0 { statusbar mystatusbar # vous pouvez modifier ce nom { position= "top" # bottom - left - right } }
Nous ajouterons des widgets plus tard. Pour l'instant nous allons paramétrer l'écran
Il faudra déterminer la couleur des fenêtres sélectionnées (focus), des normales (normal), et des urgentes (urgent)
screen 0 { styles { normal { font = "sans 9" # police d'écriture fg = "#dddddd" # couleur du texte bg = "#444444" # couleur de fond border = "#555555" # couleur de la bordure } focus { fg = "#ffffff" bg = "#535d6c" border = "#285577" } urgent { fg = "#111111" bg = "#ff4500" } } }
Il vous suffit de modifier les couleurs (codées en hexadécimal) pour personaliser.
Voir aussi
- (en) Site officiel