You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.9 KiB
96 lines
2.9 KiB
-- This widget generates menus but synchronously
|
|
-- This is done to avoid crashes when generating menus using polymenu
|
|
local menu_utils = require("menubar.utils")
|
|
local menu_gen = require("menubar.menu_gen")
|
|
local beautiful = require("beautiful")
|
|
menu_utils.wm_name = ""
|
|
local desktop_dirs = {
|
|
"/usr/local/share/applications",
|
|
"/usr/share/applications",
|
|
os.getenv("HOME").."/.local/share/applications"
|
|
}
|
|
|
|
local app_type_map = {
|
|
Other = {
|
|
name = "Other",
|
|
icon = "applications-other"
|
|
},
|
|
Wine = {
|
|
name = "Wine",
|
|
icon = "wine"
|
|
}
|
|
}
|
|
for k,v in pairs(menu_gen.all_categories) do
|
|
app_type_map[v.app_type] = v
|
|
end
|
|
|
|
local function get_files(dirs,filter)
|
|
local files = {}
|
|
for _,dir in pairs(dirs) do
|
|
local temp = io.popen("find "..tostring(dir),r)
|
|
if temp then
|
|
temp:read("*a"):gsub("[^\n]+",function(path)
|
|
if ((not filter) or filter(path)) then
|
|
files[#files+1] = path
|
|
end
|
|
end)
|
|
end
|
|
end
|
|
return files
|
|
end
|
|
|
|
return function(args)
|
|
local menu = {}
|
|
local category_index = {}
|
|
for _,entry in ipairs(args.before or {}) do
|
|
table.insert(menu,entry)
|
|
end
|
|
local filter = function(t)
|
|
return t:match(".*%.desktop$")
|
|
end
|
|
for _,file in pairs(get_files(desktop_dirs,filter)) do
|
|
local desktop_data = menu_utils.parse_desktop_file(file)
|
|
local category
|
|
for k,v in pairs(desktop_data.Categories or {"Other"}) do
|
|
if app_type_map[v] then
|
|
category = v
|
|
break
|
|
end
|
|
end
|
|
category = category or "Other"
|
|
local exec = (desktop_data.Exec or ""):gsub("(%s+)%%.(%s*)","%1%2")
|
|
--Make applications that require a terminal open in terminal
|
|
if desktop_data.Terminal then
|
|
exec = (args.terminal or global.terminal).." -e "..exec
|
|
end
|
|
--Special case for wine apps, all thanks to their inconsistency
|
|
if exec and exec:find(" wine ") then
|
|
category = "Wine"
|
|
end
|
|
local icon = desktop_data.Icon
|
|
local name = desktop_data.Name
|
|
local category_name = app_type_map[category].name
|
|
--Another speical case just for wine
|
|
if category_name:match("^Wine") then
|
|
category = "Wine"
|
|
end
|
|
if not desktop_data.NoDisplay then
|
|
if not category_index[category] then
|
|
category_index[category] = {
|
|
category_name,
|
|
{}
|
|
}
|
|
table.insert(menu,category_index[category])
|
|
end
|
|
table.insert(category_index[category][2],{
|
|
name,
|
|
exec,
|
|
(icon and menu_utils.lookup_icon(icon))
|
|
})
|
|
end
|
|
end
|
|
for _,entry in ipairs(args.after or {}) do
|
|
table.insert(menu,entry)
|
|
end
|
|
return menu
|
|
end
|