#1 Le 01/03/2010, à 12:00
- RegisBurin
[ajout à la doc openbox]openbox-xdgmenu - demande d'aide
Salut tous
Suite à cette demande, je me suis engagé à ajouter à la doc sur openbox, la procédure de création/rajout des menus "application" et "système" dans le menu clic-droit. Ceci pour les installations "après coup" d'openbox. On a bien un "menu Debian" au premier démarrage, mais celui-ci ne pointe vers rien sur Ubuntu...
Alors tout fier, je me lance dans la modification de la doc. Sauf qu'à la relecture des différentes sources dont je dispose, je m'aperçois que j'ai utilisé un moyen "détourné" pour réaliser mes menus Gnome.
En fait j'ai juste généré les versions xml de mes menus grace à
openbox-xdgmenu /chemin/vers/le/menu/...
que j'ai copié/collé dans mon menu.xml... Donc, pas dynamique...
Bon, la modif en question => http://doc.ubuntu-fr.org/openbox#openbox-xdgmenu
Donc ce topic à deux fonctions:
1) Tout d'abord, prévenir le staff en charge de la doc de la modification de celle-ci.
D'ailleurs, je m'excuse par avance de laisser, pour aujourd'hui, une doc incomplète/en construction (mais je l'ai clairement explicité, et je la reprendrais ce soir ou demain après essais)
2) J'aimerais comprendre et avoir confirmation de la procédure pour créer un pipemenu (donc dynamique) pour ça (grace à l'utilisation conjointe de openbox-xdgmenu et obm-xdg)
Là, j'en appelle à ceux qui ont déjà testé/compris, pour m'aider à rédiger. Nottament Thuban ("the king of pipemenus", si tu lis ces lignes... )
Mes sources:
http://forum.ubuntu-fr.org/viewtopic.php?id=366843
http://wiki.archlinux.fr/openbox:reglage
http://packages.ubuntu.com/karmic/openbox-xdgmenu
http://openbox.org/wiki/Help:Menus
http://ubuntuforums.org/archive/index.php/t-1107374.html
http://openbox.org/wiki/Openbox:Pipemenus#XDG_Application_Menus
Voilà, merci de m'avoir lu.
En attendant que je révise cette partie de la doc, je laisse la "manière détournée" que j'ai employé (pour mémoire et pour conserver la création du paragraphe associé)
Vos commentaires, explications, aides, sources supplémentaires sont les bienvenus.
@+
Config (M-AUDIO Delta44/Wacom CTH661-Phone ZTE OpenC-FFOS2.1) | BabyBox[WIP]
Moi sur le web / Moi, IRL mais sur le web / Ma maison sur le web
Hors ligne
#2 Le 01/03/2010, à 12:47
- Kookaburra
Re : [ajout à la doc openbox]openbox-xdgmenu - demande d'aide
Il suffit de suivre la procédure "officielle" décrite ici (en anglais par contre) :
http://openbox.org/wiki/Help:Menus
The Debian menu
Source installs or prepackaged .debs from openbox.org will not configure your setup to show the Debian menu. There are a few simple steps to get it working.
If you have already installed openbox with a working Debian menuAdd this line to your ~/.config/openbox/menu.xml (if it isn't there, copy it from /etc/xdg/openbox/menu.xml):
<menu id="Debian" />
You should place the line where you would like it to appear in the root menu. Location matters!
Add one of these lines to your ~/.config/openbox/rc.xml between the <menu> and </menu> tags, before the entry <file>menu.xml</file> tags:
<file>/var/lib/openbox/debian-menu.xml</file>
<file>debian-menu.xml</file>The second line allows you to copy the debian-menu.xml file from /var/lib/openbox to your local ~/.config/openbox, where it becomes static (command update-menus will not affect it). You can then edit it by hand and your changes will be permanent.
That's all you should have to do, though it's a good idea to run update-menus as root every now and then if you don't have a cron job assigned. It refreshes the list of currently installed apps.
Then choose reconfigure on your root menu and you should get a Debian submenu within the root menu.
If you haven't had a working debian menuThis is a little trickier, but no big deal.
Then there's this little humdinger: you'll need to get a copy of an executable script named "openbox" and copy it to /etc/menu-methods (The script actually creates the Debian menu when you run "update-menus.")
Method 1:
The easiest way is to install an official debian openbox using apt, aptitude or synaptic. This will normally ensure that you have all the packages required to create and use the Debian menu.
After installation copy the script (from /etc/menu-methods) in a known directory (your home directory will fine), then uninstall the offical openbox (with apt, aptitude or synaptic).
Then, copy the script back to /etc/menu-methods and finally, issue the command update-menus as root.
Method 2:
If you don't want to do that, download an official Openbox package (.deb) from debian.org, create a dummy directory in /tmp and type the commanddpkg-deb -x <officialopenbox.deb> </tmp/dummy_dir>
This will unpack a mini-filesystem that includes the script you need in /tmp/dummy_dir/etc/menu-methods. Set its execution permissions, copy the script to /etc and issue the command update-menus as root. The latter command will create the file /var/lib/openbox/debian-menu.xml.
To set the execution permissions type:chmod ug+x /tmp/dummy_dir/etc/openbox
The reason to create a dummy directory is that running the dpkg-deb -x command will change the ownership of the directory to root. These could become a bit of a problem later; putting it in a subdirectory of /tmp makes that issue, inoffensive.
Also, you should make sure you have the following packages installed before running update-menus:
* menu
* menu-xdgNow follow the instruccions in "If you have already installed openbox with a working Debian menu" above.
Sinon, j'avais décrit comment le faire ici :
http://forum.ubuntu-fr.org/viewtopic.php?id=366843
* Pour le menu Debian :
Il faut avoir le paquet 'menu' d'installer :
sudo apt-get install menu menu-xdg
Essaye ça pour voir !
=> Sinon, regardes par là :
http://icculus.org/openbox/index.php/Help:Menus#The_Debian_menu
Il faut coller ça dans ton '~/.config/openbox/menu.xml' pour avoir un menu avec toutes tes applications :
<menu id="Debian"/>
Et tu rajoutes ça à ton '~/.config/openbox/rc.xml' :
<file>/var/lib/openbox/debian-menu.xml</file> <file>debian-menu.xml</file>
( Entre les entrées <menu> et </menu>, avant l'entrée <file>menu.xml</file> )
* Pour le menu "xdg-menu" (= applications) :
Voici la procédure :
* Installes les paquets suivants :
sudo apt-get install menu menu-xdg openbox-xdgmenu extra-xdg-menus xdg-utils
Certains seront surement déjà installés chez toi. Par exemple, cher moi, il manquait seulement le paquet 'menu-xdg' pour que le pipeline fonctionne ...
* Ensuite, il faut vérifier que tu as bien ce fichier dans "/usr/bin/obm-xdg" :
#!/usr/bin/python2.5 -O ######################################################################### # Copyright 2005 Manuel Colmenero # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ######################################################################## # # a free desktop menus implementation for openbox # import xml.dom.minidom, obxml, os, sys, time class XdgMenu: def __init__(self): self.name = "" self.title = "" self.directory = "" self.directorydir = "" self.directorydirs = [] self.children = [] self.parent = None self.include = None self.exclude = None self.lang = None self.appdirs = [] self.items = [] self.onlyunallocated = False self.deleted = False self.filename = "" def _get_node_value(self, node): if node.hasChildNodes(): for n in node.childNodes: if n.nodeName == "#text" and n.nodeValue.strip() != "": return n.nodeValue.strip() def _get_root_menu(self, menu): child = menu while child.parent != None: child = child.parent return child def _find_menu(self, name): if self.name == name: return self for c in self.children: if c.name == name: return c else: b = c._find_menu(name) if b: return b def merge(self, menu): for directory in menu.directorydirs: if os.path.isdir(directory): self.directorydirs += directory self.directory = menu.directory self.children += menu.children def parseInclude(self, node, logic): for item in node.childNodes: if item.nodeType == 1: i = XdgLogic(item.nodeName.upper()) if item.nodeName.upper() in ("CATEGORY", "FILENAME"): i.setCategory(self._get_node_value(item)) else: i = XdgLogic(item.nodeName.upper()) self.parseInclude(item, i) logic.append(i) def parseXml(self, parent): root = self._get_root_menu(self) for item in parent.childNodes: nname = item.nodeName.lower() if nname == "name": self.name = self._get_node_value(item) elif nname == "directory": self.directory = self._get_node_value(item) elif nname == "directorydir": value = self._get_node_value(item) if not os.path.isabs(value): value = "%s/%s" % (os.path.dirname(self.filename), value) if os.path.isdir(value): self.directorydirs.append(value) elif nname == "defaultdirectorydirs": env = os.getenv("XDG_DATA_DIRS") if env: for item in env.split(":"): if os.path.isdir(item): self.directorydirs.append("%s/desktop-directories"%(item)) else: self.directorydirs.append("/usr/share/desktop-directories") self.directorydirs.append("/usr/local/share/desktop-directories") elif nname == "include": self.include = XdgLogic("OR") self.parseInclude(item, self.include) elif nname == "exclude": self.exclude = XdgLogic("OR") self.parseInclude(item, self.exclude) elif nname == "onlyunallocated": self.onlyunallocated = True elif nname == "notonlyunallocated": self.onlyunallocated = False elif nname == "deleted": self.deleted = True elif nname == "notdeleted": self.deleted = False elif nname == "mergefile": fn = self._get_node_value(item) if not os.path.isabs(fn): fn = "%s/%s" % (os.path.dirname(self.filename), fn) newmenu = XdgMenu() newmenu.parseFile(fn) m = root._find_menu(newmenu.name) if m: m.merge(newmenu) else: newmenu.parent = self self.children.append(newmenu) elif nname == "appdir": dr = self._get_node_value(item) if not os.path.isabs(dr): dr = "%s/%s" % (os.path.dirname(self.filename), dr) self.appdirs.append(dr) elif nname == "defaultappdirs": xdg_data_dirs = [] xdg_env = os.getenv("XDG_DATA_DIRS") if xdg_env: for item in xdg_env.split(":"): if item != "" and os.path.isdir(item): xdg_data_dirs.append(item) else: xdg_data_dirs.append("/usr/share") xdg_data_dirs.append("/usr/local/share") for xdir in xdg_data_dirs: if os.path.isdir("%s/applications"%(xdir)): self.appdirs.append("%s/applications"%(xdir)) elif nname == "menu": newmenu = XdgMenu() newmenu.appdirs += self.appdirs newmenu.directorydirs += self.directorydirs newmenu.filename = self.filename newmenu.lang = self.lang newmenu.parseXml(item) m = root._find_menu(newmenu.name) if m: m.merge(newmenu) else: newmenu.parent = self self.children.append(newmenu) def parseFile(self, filename): f = open(filename) dom = xml.dom.minidom.parseString(f.read()) f.close() self.filename = filename self.parseXml(dom.documentElement) def parseDirectoryFile(self, filename, language): title = "" accuracy = 0 if language: l = language.split(".")[0].split("_") if len(l) == 2: lang_major = l[0] lang_minor = l[1] else: lang_major = l[0] lang_minor = None else: lang_major = "en" lang_minor = None for line in open(filename): i = line.split("=")[0].lower() n = line.find("=") if i[0:4] == "name": name = line[n+1:] if "[" in line[:n]: lang = line[:n].split("[")[1].split("]")[0] else: lang = None if lang: if lang_major in lang and (title == "" or accuracy < 2): title = name accuracy = 2 if lang_minor and lang_major in lang and lang_minor in lang: title = name accuracy = 3 elif title == "": accuracy = 1 title = name return unicode(title.strip() ,"utf-8") def parseDesktopFile(self, filename, language): title = "" exe = "" cats = [] accuracy = 0 if language: l = language.split(".")[0].split("_") if len(l) == 2: lang_major = l[0] lang_minor = l[1] else: lang_major = l[0] lang_minor = None else: lang_major = "en" lang_minor = None for line in open(filename): i = line.split("=")[0].lower() n = line.find("=") if i[0:4] == "name": name = line[n+1:] if "[" in line[:n]: lang = line[:n].split("[")[1].split("]")[0] else: lang = None if lang: if lang_major in lang and (title == "" or accuracy < 2): title = name accuracy = 2 if lang_minor and lang_major in lang and lang_minor in lang: title = name accuracy = 3 elif title == "": accuracy = 1 title = name elif i == "exec": exe = "" jump = False for c in line[n+1:]: if not jump: if c == "%": jump = True else: exe += c else: jump = False elif i == "categories": cats = line[n+1:].strip().split(";") if cats[-1] == "": cats.pop(-1) item = { "name": unicode(title.strip() ,"utf-8"), "exec": exe.strip(), "categories": cats, "filename": filename, "allocated": False } return item def getAllAppdirs(self, l=[]): for item in self.children: for dr in item.appdirs: if not dr in l: l.append(dr) item.getAllAppdirs(l) return l def loadItems(self): data = {} appdirs = self.getAllAppdirs([]) for each in appdirs: data[each] = [] for f in os.listdir(each): if ".desktop" in f: i = self.parseDesktopFile("%s/%s" % (each, f), self.lang) data[each].append(i) self._allocate_items(data) self._create_items(data) self._get_menus_titles(self.lang) def _get_menus_titles(self, languaje): for item in self.directorydirs: fn = "%s/%s" % (item, self.directory) if os.path.isfile(fn): self.title = self.parseDirectoryFile(fn, languaje) if self.title == "": self.title = self.name for each in self.children: each._get_menus_titles(languaje) def _allocate_items(self, data): if self.include: for d in self.appdirs: for item in data[d]: if self.include.evaluate(item["categories"], item["filename"]): item["allocated"] = True for item in self.children: item._allocate_items(data) def _create_items(self, data): if self.include: for d in self.appdirs: for item in data[d]: if not self.onlyunallocated or self.onlyunallocated and not item["allocated"]: if self.include.evaluate(item["categories"], item["filename"]): if self.exclude: if not self.exclude.evaluate(item["categories"], item["filename"]): self.items.append(item) else: self.items.append(item) for item in self.children: item._create_items(data) def _create_obmenu(self, obmenu, root=None): if self.parent: pid = "xdg-" + self.name else: pid = root for child in self.children: if len(child.items) > 0 or len(child.children) > 0: obmenu.createMenu(pid, child.title, "xdg-" + child.name) child._create_obmenu(obmenu, root) for item in self.items: obmenu.createItem(pid, item["name"], "Execute", item["exec"]) class XdgLogic: def __init__(self, tipe): self.tipe = tipe self.items = [] self.value = False self.cat = "" def append(self, item): self.items.append(item) def evaluate(self, list, filename): if self.tipe == "CATEGORY": self.value = self.cat in list return self.value if self.tipe == "FILENAME": self.value = self.cat == filename return self.value if self.tipe == "NOT": self.value = False for i in self.items: self.value = self.value or not i.evaluate(list, filename) return self.value if self.tipe == "AND": self.value = True for i in self.items: if not i.evaluate(list, filename): self.value = False return self.value return self.value if self.tipe == "OR": self.value = False for i in self.items: self.value = self.value or i.evaluate(list, filename) return self.value if self.tipe == "ALL": self.value = True return self.value def setCategory(self, cat): self.cat = cat if __name__ == "__main__": mnu = XdgMenu() if os.getenv("LANG") != "": mnu.lang = os.getenv("LANG") home = os.getenv("HOME") xdg_cd = os.getenv("XDG_CONFIG_DIRS") xdg_ch = os.getenv("XDG_CONFIG_HOME") if not xdg_ch: xdg_ch = "%s/.config" % (home) if not xdg_cd: xdg_cd = "/etc/xdg" filename = "" role = None if os.path.isfile("%s/menus/applications.menu"%(xdg_ch)): filename = "%s/menus/applications.menu"%(xdg_ch) else: for cdir in xdg_cd.split(":"): if os.path.isfile("%s/menus/applications.menu"%(cdir)): filename = "%s/menus/applications.menu"%(cdir) break for arg in sys.argv[1:]: if arg == "--import": role = "import" elif arg == "-i": role = "import" elif arg == "--replace": role = "replace" elif arg == "-r": role = "replace" else: if os.path.isfile(sys.argv[1]): filename = sys.argv[1] mnu.parseFile(filename) if role in ("replace", "import"): mnu.loadItems() obmenu = obxml.ObMenu() obmenu.newMenu() if role == "replace": mnuid = "root-menu" mnulb = "Openbox 3" else: mnuid = "obm-xdg-menus" mnulb = "Gnome menus" obmenu.createMenu(None, mnulb, mnuid) mnu._create_obmenu(obmenu, mnuid) if role == "replace": obmenu.createMenu(mnuid, "Openbox", "Openbox-Conf-Menu") obmenu.createItem("Openbox-Conf-Menu", "Edit preferences", "Execute", "obconf") obmenu.createItem("Openbox-Conf-Menu", "Edit menus", "Execute", "obmenu") obmenu.createItem("Openbox-Conf-Menu", "Reload prefences", "Reconfigure", "") obmenu.createSep("Openbox-Conf-Menu") obmenu.createItem("Openbox-Conf-Menu", "Exit", "Exit", "") obmenu.createSep(mnuid) obmenu.createLink(mnuid, "client-list-menu") if not os.path.isdir(xdg_ch): os.mkdir(xdg_ch) if not os.path.isdir("%s/openbox"%(xdg_ch)): os.mkdir("%s/openbox"%(xdg_ch)) if os.path.isfile("%s/openbox/menu.xml"%(xdg_ch)): os.rename("%s/openbox/menu.xml"%(xdg_ch), "%s/openbox/menu.xml~"%(xdg_ch)) obmenu.saveMenu("%s/openbox/menu.xml"%(xdg_ch)) else: obmenu.saveMenu("gnome-menus.xml") else: cachefile = "%s/.obmxdg.xml" % (home) if os.path.isfile(cachefile): new = False for appdir in mnu.getAllAppdirs(): if os.path.getmtime(appdir) > os.path.getmtime(cachefile): new = True break if not new: cache = open(cachefile) print cache.read() cache.close() sys.exit() mnu.loadItems() obmenu = obxml.ObMenu() obmenu.newPipe() mnu._create_obmenu(obmenu) obmenu.saveMenu(cachefile) obmenu.printXml()
Pour être sûr d'avoir le bon fichier au bon endroit, tu peux ré-installer le paquet 'obmenu', ce qui va remettre en place ce fichier :
sudo apt-get remove obmenu && sudo apt-get install obmenu
* Tu rajoutes cette ligne dans ton 'menu.xml', tu l'enregistres et enfin tu fais "reconfigure" et "restart" :
<menu id="xdg-menu" label="Applications" execute="obm-xdg"/>
Maintenant, cela doit fonctionner ...
Portable17p : CrunchBangLinux // EeePC : ArchLinux
Openbox Addict : http://kookadimi.deviantart.com
Mes photos : http://www.fluidr.com/photos/kookadimi/sets
Votre téléphone mobile dispose de plus de puissance que l'ensemble des ordinateurs de la NASA en 1969. La NASA a lancé un homme sur la Lune. Vous lancez un oiseau sur des cochons...
Hors ligne
#3 Le 01/03/2010, à 13:15
- RegisBurin
Re : [ajout à la doc openbox]openbox-xdgmenu - demande d'aide
Yep, merci à toi
D'ailleurs les deux posts vers lesquels tu renvoies, je les avais listés comme sources pour mes recherches.
J'étudie ça de plus près ce soir
Encore merci
Config (M-AUDIO Delta44/Wacom CTH661-Phone ZTE OpenC-FFOS2.1) | BabyBox[WIP]
Moi sur le web / Moi, IRL mais sur le web / Ma maison sur le web
Hors ligne
#4 Le 27/03/2010, à 12:31
- SandraVel
Re : [ajout à la doc openbox]openbox-xdgmenu - demande d'aide
Bonjour,
Petite question : quand vous créez ainsi vos pipemenus, pouvez-vous éditez leur contenu (par Obmenu ou par terminal) ?
Chez moi, je peux éditer le pipemenu, mais pas son contenu. Si j'ai bien compris, le pipemenu va recréer à chaque fois le menu pour être toujours à jour. Il y a-t-il un fichier quelque part à manipuler pour qu'il tienne compte de certaines modifications ?
Par exemple, j'ai Nautilus dans Applications (pipemenu). Mais il va me bloquer OpenBox à chaque fois, à moins de pouvoir l'éditer et rajouter --no-desktop à sa commande.
On pourrait aussi optimiser l'affichage en enlevant les doublons : dans le Pipemenu Applications créé par la méthode que vous avez décrite ici, nous avons un autre menu debian qui reprend le menu Debian que nous avons déjà, mais avec des rectangles vides à la place des applications... Ce n'est pas vitale, mais ca ne fait pas très propre.
Merci pour vos lumières,
Sandra
Hors ligne
#5 Le 13/05/2011, à 21:41
- GnuLux
Re : [ajout à la doc openbox]openbox-xdgmenu - demande d'aide
Bonjour,
Je ne suis pas sûr que ma contribution soit utile mais sait on jamais : pour utiliser la commande openbox-xdgmenu, un simple shell suffit. Il permet de contourner le bug :
openbox-xdgmenu /etc/xdg/menus/applications.menu > /tmp/openbox.menu
sed '1,$s/&/et/g' /tmp/openbox.menu
ensuite il suffit d'appeler ce shell dans le menu.xml ....
Voilà...Dernière question que je me pose...comment francisé ce menu ?
Hors ligne
#6 Le 18/05/2011, à 22:12
- Aldian
Re : [ajout à la doc openbox]openbox-xdgmenu - demande d'aide
Salut
Tu n'auras pas de retour des gens qui s'occuppent de la doc sur ce forum. Pour demander des conseils de mise en forme ou signaler une modification, il faut écrire un email à la mailing liste de la documentation (faut accepter le certificat de sécurité pour pouvoir s'inscrire).
Par contre, pour l'aide sur les procédures openbox, le forum est effectivement un medium plus adapté.
Bon courage.
Hors ligne