awesome/lib/menubar/menu_gen.lua
Daniel Hahler 25eff81878 menubar: look for .desktop files recursively
It was missing apps/entries from /usr/share/applications/kde4.

This patch also makes sure that entries are unique (by Exec/Name).

Closes https://github.com/awesomeWM/awesome/pull/711.
2016-02-28 22:14:08 +01:00

132 lines
5.2 KiB
Lua

---------------------------------------------------------------------------
--- Menu generation module for menubar
--
-- @author Antonio Terceiro
-- @copyright 2009, 2011-2012 Antonio Terceiro, Alexander Yakushev
-- @release @AWESOME_VERSION@
-- @module menubar.menu_gen
---------------------------------------------------------------------------
-- Grab environment
local utils = require("menubar.utils")
local icon_theme = require("menubar.icon_theme")
local pairs = pairs
local ipairs = ipairs
local string = string
local table = table
local menu_gen = {}
-- Options section
local data_dir = os.getenv("XDG_DATA_HOME")
if not data_dir then
data_dir = os.getenv("HOME") .. '/.local/share/'
end
--- Specifies all directories where menubar should look for .desktop
-- files. The search is recursive.
menu_gen.all_menu_dirs = { data_dir .. 'applications/', '/usr/share/applications/', '/usr/local/share/applications/' }
--- Specify the mapping of .desktop Categories section to the
-- categories in the menubar. If "use" flag is set to false then any of
-- the applications that fall only to this category will not be shown.
menu_gen.all_categories = {
multimedia = { app_type = "AudioVideo", name = "Multimedia",
icon_name = "applications-multimedia", use = true },
development = { app_type = "Development", name = "Development",
icon_name = "applications-development", use = true },
education = { app_type = "Education", name = "Education",
icon_name = "applications-science", use = true },
games = { app_type = "Game", name = "Games",
icon_name = "applications-games", use = true },
graphics = { app_type = "Graphics", name = "Graphics",
icon_name = "applications-graphics", use = true },
office = { app_type = "Office", name = "Office",
icon_name = "applications-office", use = true },
internet = { app_type = "Network", name = "Internet",
icon_name = "applications-internet", use = true },
settings = { app_type = "Settings", name = "Settings",
icon_name = "applications-utilities", use = true },
tools = { app_type = "System", name = "System Tools",
icon_name = "applications-system", use = true },
utility = { app_type = "Utility", name = "Accessories",
icon_name = "applications-accessories", use = true }
}
--- Find icons for category entries.
function menu_gen.lookup_category_icons()
for _, v in pairs(menu_gen.all_categories) do
v.icon = icon_theme():find_icon_path(v.icon_name)
end
end
--- Get category key name and whether it is used by its app_type.
-- @param app_type Application category as written in .desktop file.
-- @return category key name in all_categories, whether the category is used
local function get_category_name_and_usage_by_type(app_type)
for k, v in pairs(menu_gen.all_categories) do
if app_type == v.app_type then
return k, v.use
end
end
end
--- Remove CR\LF newline from the end of the string.
-- @param s string to trim
local function trim(s)
if not s then return end
if string.byte(s, #s) == 13 then
return string.sub(s, 1, #s - 1)
end
return s
end
--- Generate an array of all visible menu entries.
-- @treturn table All menu entries.
function menu_gen.generate()
-- Update icons for category entries
menu_gen.lookup_category_icons()
local result = {}
local unique_entries = {}
for _, dir in ipairs(menu_gen.all_menu_dirs) do
for _, entry in ipairs(utils.parse_dir(dir)) do
-- Check whether to include program in the menu
if entry.show and entry.Name and entry.cmdline then
local unique_key = entry.Name .. '\0' .. entry.cmdline
if not unique_entries[unique_key] then
local target_category = nil
-- Check if the program falls into at least one of the
-- usable categories. Set target_category to be the id
-- of the first category it finds.
if entry.categories then
for _, category in pairs(entry.categories) do
local cat_key, cat_use =
get_category_name_and_usage_by_type(category)
if cat_key and cat_use then
target_category = cat_key
break
end
end
end
if target_category then
local name = trim(entry.Name) or ""
local cmdline = trim(entry.cmdline) or ""
local icon = entry.icon_path or nil
table.insert(result, { name = name,
cmdline = cmdline,
icon = icon,
category = target_category })
unique_entries[unique_key] = true
end
end
end
end
end
return result
end
return menu_gen
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80