menubar: Fix API docs
[awesome.git] / lib / menubar / utils.lua.in
blob3759c59027daaa04b14df231d72fae7e067bcab5
1 ---------------------------------------------------------------------------
2 -- @author Antonio Terceiro
3 -- @copyright 2009, 2011-2012 Antonio Terceiro, Alexander Yakushev
4 -- @release @AWESOME_VERSION@
5 ---------------------------------------------------------------------------
7 -- Grab environment
8 local io = io
9 local table = table
10 local ipairs = ipairs
11 local string = string
12 local awful_util = require("awful.util")
13 local theme = require("beautiful")
15 -- Utility module for menubar
16 -- menubar.utils
17 local utils = {}
19 -- NOTE: This icons/desktop files module was written according to the
20 -- following freedesktop.org specifications:
21 -- Icons: http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-0.11.html
22 -- Desktop files: http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.0.html
24 -- Options section
26 --- Terminal which applications that need terminal would open in.
27 utils.terminal = 'xterm'
29 -- The default icon for applications that don't provide any icon in
30 -- their .desktop files.
31 local default_icon = nil
33 --- Name of the WM for the OnlyShownIn entry in the .desktop file.
34 utils.wm_name = "awesome"
36 -- Private section
38 local all_icon_sizes = {
39 '128x128' ,
40 '96x96',
41 '72x72',
42 '64x64',
43 '48x48',
44 '36x36',
45 '32x32',
46 '24x24',
47 '22x22',
48 '16x16'
51 -- List of supported icon formats. Ignore SVG because Awesome doesn't
52 -- support it.
53 local icon_formats = { "png", "xpm" }
55 -- Check whether the icon format is supported.
56 -- @param icon_file Filename of the icon.
57 -- @return true if format is supported, false otherwise.
58 local function is_format_supported(icon_file)
59 for _, f in ipairs(icon_formats) do
60 if icon_file:match('%.' .. f) then
61 return true
62 end
63 end
64 return false
65 end
67 --- Lookup an icon in different folders of the filesystem.
68 -- @param icon_file Short or full name of the icon.
69 -- @return full name of the icon.
70 function utils.lookup_icon(icon_file)
71 if not icon_file or icon_file == "" then
72 return default_icon
73 end
75 if icon_file:sub(1, 1) == '/' and is_format_supported(icon_file) then
76 -- If the path to the icon is absolute and its format is
77 -- supported, do not perform a lookup.
78 return icon_file
79 else
80 local icon_path = {}
81 local icon_theme_paths = {}
82 local icon_theme = theme.icon_theme
83 if icon_theme then
84 table.insert(icon_theme_paths, '/usr/share/icons/' .. icon_theme .. '/')
85 -- TODO also look in parent icon themes, as in freedesktop.org specification
86 end
87 table.insert(icon_theme_paths, '/usr/share/icons/hicolor/') -- fallback theme
89 for i, icon_theme_directory in ipairs(icon_theme_paths) do
90 for j, size in ipairs(all_icon_sizes) do
91 table.insert(icon_path, icon_theme_directory .. size .. '/apps/')
92 table.insert(icon_path, icon_theme_directory .. size .. '/actions/')
93 table.insert(icon_path, icon_theme_directory .. size .. '/devices/')
94 table.insert(icon_path, icon_theme_directory .. size .. '/places/')
95 table.insert(icon_path, icon_theme_directory .. size .. '/categories/')
96 table.insert(icon_path, icon_theme_directory .. size .. '/status/')
97 end
98 end
99 -- lowest priority fallbacks
100 table.insert(icon_path, '/usr/share/pixmaps/')
101 table.insert(icon_path, '/usr/share/icons/')
103 for i, directory in ipairs(icon_path) do
104 if is_format_supported(icon_file) and awful_util.file_readable(directory .. icon_file) then
105 return directory .. icon_file
106 else
107 -- Icon is probably specified without path and format,
108 -- like 'firefox'. Try to add supported extensions to
109 -- it and see if such file exists.
110 for _, format in ipairs(icon_formats) do
111 local possible_file = directory .. icon_file .. "." .. format
112 if awful_util.file_readable(possible_file) then
113 return possible_file
118 return default_icon
122 --- Parse a .desktop file.
123 -- @param file The .desktop file.
124 -- @return A table with file entries.
125 function utils.parse(file)
126 local program = { show = true, file = file }
127 local desktop_entry = false
129 -- Parse the .desktop file.
130 -- We are interested in [Desktop Entry] group only.
131 for line in io.lines(file) do
132 if not desktop_entry and line == "[Desktop Entry]" then
133 desktop_entry = true
134 else
135 if line:sub(1, 1) == "[" and line:sub(-1) == "]" then
136 -- A declaration of new group - stop parsing
137 break
140 -- Grab the values
141 for key, value in line:gmatch("(%w+)%s*=%s*(.+)") do
142 program[key] = value
147 -- In case [Desktop Entry] was not found
148 if not desktop_entry then return nil end
150 -- Don't show program if NoDisplay attribute is false
151 if program.NoDisplay and string.lower(program.NoDisplay) == "true" then
152 program.show = false
155 -- Only show the program if there is no OnlyShowIn attribute
156 -- or if it's equal to utils.wm_name
157 if program.OnlyShowIn ~= nil and not program.OnlyShowIn:match(utils.wm_name) then
158 program.show = false
161 -- Look up for a icon.
162 if program.Icon then
163 program.icon_path = utils.lookup_icon(program.Icon)
166 -- Split categories into a table. Categories are written in one
167 -- line separated by semicolon.
168 if program.Categories then
169 program.categories = {}
170 for category in program.Categories:gmatch('[^;]+') do
171 table.insert(program.categories, category)
175 if program.Exec then
176 -- Substitute Exec special codes as specified in
177 -- http://standards.freedesktop.org/desktop-entry-spec/1.1/ar01s06.html
178 local cmdline = program.Exec:gsub('%%c', program.Name)
179 cmdline = cmdline:gsub('%%[fuFU]', '')
180 cmdline = cmdline:gsub('%%k', program.file)
181 if program.icon_path then
182 cmdline = cmdline:gsub('%%i', '--icon ' .. program.icon_path)
183 else
184 cmdline = cmdline:gsub('%%i', '')
186 if program.Terminal == "true" then
187 cmdline = utils.terminal .. ' -e ' .. cmdline
189 program.cmdline = cmdline
192 return program
195 --- Parse a directory with .desktop files
196 -- @param dir The directory.
197 -- @param icons_size, The icons sizes, optional.
198 -- @return A table with all .desktop entries.
199 function utils.parse_dir(dir)
200 local programs = {}
201 local files = io.popen('find '.. dir ..' -maxdepth 1 -name "*.desktop" 2>/dev/null')
202 for file in files:lines() do
203 local program = utils.parse(file)
204 if program then
205 table.insert(programs, program)
208 return programs
211 return utils
213 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80