[OpenBox] Menus dynamiques.
Publié : mer. 12 mars 2008, 23:46
Une petite contribution pour permettre d'avoir des menus dynamiques dans OpenBox en utilisant les informations puisées dans les fichiers .desktop.
J'ai utilisé lua et j'ai essayé de garder à l'esprit d'avoir quelque chose de rapide et simple. Comparé avec un script php faisant la même chose il n'y a pas photo sur la rapidité de lua.
Il y a besoin de l'extension luafilesystem pour que ça fonctionne (pacman -S lua luafilesystem).
Comme vous pouvez vous en rendre compte cela fonctionne aussi pour JWM (mais les images sont encore moyennement supportées car pas trop ma préocupation).
Des questions ? Écrivez les à la suite.
J'ai utilisé lua et j'ai essayé de garder à l'esprit d'avoir quelque chose de rapide et simple. Comparé avec un script php faisant la même chose il n'y a pas photo sur la rapidité de lua.
Il y a besoin de l'extension luafilesystem pour que ça fonctionne (pacman -S lua luafilesystem).
Code : Tout sélectionner
#!/usr/bin/env lua
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation version 3 (GPLv3)
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-- MA 02110-1301, USA.
require ("lfs")
-- Localisation désirée pour le nom, commentaire et nom générique.
local locale="fr"
-- Gestionnaire de fenêtres courant (utilisé pour OnlyShowIn).
local current_wm="openbox"
-- programme utilisé pour lancer les applications consoles.
local terminal="sakura -e"
-- Où sera stocké le menu.
local menu = {}
--- returnCategory
-- permet de donner un nom à une liste de catégories.
-- TODO: retourner aussi une image pour la catégorie.
function returnCategory(desktop)
if desktop["categories"] == nil then
return nil;
end
if string.find(desktop["categories"],"AudioVideo") then
return "Audio/Video"
end
if string.find(desktop["categories"],"Education") then
return "Éducation"
end
if string.find(desktop["categories"],"Development") then
return "Développement"
end
if string.find(desktop["categories"],"Game") then
return "Jeux"
end
if string.find(desktop["categories"],"Graphics") then
return "Graphiques"
end
if string.find(desktop["categories"],"Network") then
return "Réseau"
end
if string.find(desktop["categories"],"Office") then
return "Bureautique"
end
if string.find(desktop["categories"],"Settings") then
return "Réglages"
end
if string.find(desktop["categories"],"System") then
return "Système"
end
if string.find(desktop["categories"],"Utility") then
return "Utilitaires"
end
return "Autres"
end
--- loadDesktop
-- retourne une liste de propriétés pour un fichier .deskop.
-- arg: nom complet du fichier
-- ret: structure (terminal, exec, name, genericname, comment, icon,hidden)
--
-- name, genericname et comment sont localisés si possible.
-- Pour avoir la version originale mettre la variable locale à c (de préférence)
function loadDesktop(filename)
local desktop_file
local line
local pos
local program={
terminal=false,
exec,
name,
genericname,
comment,
icon,
hidden=false
}
if string.sub(filename,-7) ~= "desktop" then
return nil
end
desktop_file=io.open(filename,"r")
if desktop_file == nil then
print ("Erreur : impossible de charger fichier", filename)
return nil
end
line = desktop_file:read()
while line ~= nil do
pos = string.find(line,"=")
if pos ~= nil then
local key=string.lower(string.sub(line,1,pos-1))
local value=string.sub(line,pos+1)
if key == "type" then
program.type=string.lower(value)
elseif key == "terminal" and string.lower(value) == "true" then
program.terminal=true
elseif key == "name" and program.name == nil then
program.name=value
elseif key =="name["..locale.."]" then
program.name=value
--[[
elseif key == "genericname" and program.genericname == nil then
program.name=value
elseif key == "genericname["..locale.."]" then
program.genericname=value
elseif key == "comment" and program.comment == nil then
program.comment=value
elseif key == "comment["..locale.."]" then
program.comment=value
]]
elseif key == "icon" then
program.icon=value
elseif key == "categories" then
program.categories=value
elseif key == "exec" then
pos = string.find(value," %%[fFuUdDnNickvm]")
if pos ~= nil then
program.exec = string.sub(value,1,pos-1)
else
program.exec=value
end
elseif key=="onlyshowin" and current_wm then
if not string.find(value,current_wm) then
program.hidden=true
end
end
end
line=desktop_file:read()
end
desktop_file:close()
if program.terminal then
program.exec = terminal .." ".. program.exec
end
return program
end
--- readDirectory(appdir)
-- lit non récursivement les fichiers .desktop du répertoire appdir.
function readDirectory(appdir)
local appinfo
local category
local file
local entry
for file in lfs.dir(appdir) do
if file ~= "." and file ~= ".." then
appinfo = loadDesktop(appdir.."/"..file)
if appinfo then
if appinfo.type == "application" and not appinfo.hidden then
category = returnCategory(appinfo)
if category ~= nil then
if menu[category] == nil then menu[category] = {} end
menu[category][appinfo.name]={exec=appinfo.exec,icon=appinfo.icon}
else
menu[appinfo.name]={exec=appinfo.exec,icon=appinfo.icon}
end
end
end
end
end
end
--- generateMenuJWM
-- génère un menu dynamique pour JWM à intégrer dans .jwmrc avec
-- <Include>exec:lua /path/nomfichier.lua</Include>
function generateMenuJWM()
print ("<JWM>")
for i,k in pairs(menu) do
if k.exec == nil then
print("<Menu label=\""..i.."\">")
for name,data in pairs(k) do
print(" <Program icon=\"".. data.icon .."\" label=\"".. name .."\">".. data.exec .."</Program>")
end
print("</Menu>")
else
print("<Program icon=\"".. k.icon .."\" label=\"".. i .."\">".. k.exec .."</Program>")
print("</item>")
end
end
print("</JWM>")
end
--- generateMenuOpenBox
-- génère un menu dynamique pour OpenBox à intégrer dans menu.xml avec
-- <menu id="id" label="label" execute="lua /path/nomfichier.lua" />
-- et
-- <menu id="id" /> dans le menu "root-menu"
function generateMenuOpenBox()
print ([[<openbox_pipe_menu xmlns="http://openbox.org/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://openbox.org/
file:///usr/share/openbox/menu.xsd">]])
for i,k in pairs(menu) do
if k.exec == nil then
print("<menu id=\"gnome-menu-".. i .."\" label=\"".. i .."\">")
for name,data in pairs(k) do
print(" <item label=\"".. name .."\">")
print(" <action name=\"Execute\"><execute>".. data.exec .."</execute></action>")
print(" </item>")
end
print("</menu>")
else
print("<item label=\"".. i .."\">")
print(" <action name=\"Execute\"><execute>".. k.exec .."</execute></action>")
print("</item>")
end
end
print("</openbox_pipe_menu>")
end
readDirectory("/usr/share/applications")
-- readDirectory("/home/mimas/.local/share/applications")
-- *** Choisir generateMenuJWM() ou generateMenuOpenBox ***
generateMenuOpenBox()
Des questions ? Écrivez les à la suite.