-- 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