-
Notifications
You must be signed in to change notification settings - Fork 0
/
fbxdgmenu.py
executable file
·94 lines (71 loc) · 2.99 KB
/
fbxdgmenu.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env python3
from xdg import Menu, IconTheme
import sys
import re
STANDALONE=False
TERMINAL_COMMAND = "gnome-terminal -- %s"
TERMINAL_PATH_COMMAND = "gnome-terminal --working-directory=%s -- %s"
ICON_THEMES = ('gnome', 'oxygen', 'hicolor')
REMOVE_FROM_EXEC = re.compile(' -caption "?%c"?| -[^ ]+ %[UuFf]| %[UuFfi]')
class FluxboxXDGMenu:
def __init__(self, standalone=False, filename=None):
menu = Menu.parse(filename)
if standalone:
self.contents = "[begin] (Fluxbox)"
self.contents.extend(self.menu(menu, depth=1))
self.contents.append("[end]")
else:
self.contents = self.menu(menu)
def __str__(self):
return "\n".join(self.contents)
# TODO: add a hack to look for more icons in /opt/something and /usr/share/app-install/icons
def _find_icon(self, icon_name):
for theme in ICON_THEMES:
icon = IconTheme.getIconPath(icon_name, theme=theme, extensions=['png', 'xpm'])
if icon:
return icon
if not icon:
return ""
def menu(self, menu, depth=0):
contents = []
indent = " " * 4 * depth
name = menu.getName()
icon = self._find_icon(menu.getIcon()) or ""
contents.append("%s[submenu] (%s) <%s>" % (indent, name, icon))
for entry in menu.getEntries():
if isinstance(entry, Menu.MenuEntry):
try:
contents.append(self.entry(entry, depth + 1))
except ValueError as e:
sys.stderr.write(str(e))
continue
elif isinstance(entry, Menu.Menu):
contents.extend(self.menu(entry, depth + 1))
elif isinstance(entry, Menu.Separator):
contents.append(self.separator(depth + 1))
contents.append("%s[end]" % indent)
return contents
def entry(self, entry, depth):
indent = " " * 4 * depth
name = entry.DesktopEntry.getName()
icon = self._find_icon(entry.DesktopEntry.getIcon()) or ""
d_exec = entry.DesktopEntry.getExec()
if not d_exec:
raise ValueError("No executable information found for entry '%s' (%s)." % (name, entry))
executable = REMOVE_FROM_EXEC.sub('', d_exec)
path = entry.DesktopEntry.getPath()
terminal = entry.DesktopEntry.getTerminal()
if path and terminal:
command = TERMINAL_PATH_COMMAND % (path, executable)
elif terminal: # and not path
command = TERMINAL_COMMAND % executable
elif path: # and not terminal
command = "cd %s; %s" % (path, executable)
else: # if neither
command = executable
return "%s[exec] (%s) {%s} <%s>" % (indent, name, command, icon)
def separator(self, depth):
indent = " " * 4 * depth
return "%s[separator]" % indent
filename = sys.argv[1] if len(sys.argv) > 1 else None
print(FluxboxXDGMenu(standalone=STANDALONE, filename=filename))