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.
137 lines
4.8 KiB
137 lines
4.8 KiB
-- This file is part of Reno desktop.
|
|
--
|
|
-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
--
|
|
-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
--
|
|
-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>.
|
|
-- Asynchronous XDG data aggregator (library)
|
|
local menu_utils = require("menubar.utils")
|
|
local awful = require("awful")
|
|
local gears = require("gears")
|
|
local json = require("dkjson")
|
|
local lib = {}
|
|
|
|
function lib.init_xdg_struct()
|
|
-- Global xdg data struct
|
|
local xdg = {
|
|
directory_integrity = {},
|
|
directory_listings = {},
|
|
apps = {},
|
|
categories = {
|
|
Other = {
|
|
icon = "applications-other",
|
|
apps = {}
|
|
},
|
|
Wine = {
|
|
icon = "wine",
|
|
apps = {}
|
|
}
|
|
}
|
|
}
|
|
return xdg
|
|
end
|
|
|
|
function lib.load_xdg_cache()
|
|
-- Load cached applications
|
|
local cache_file = io.open(gears.filesystem.get_xdg_cache_home()..".reno_xdg_cache.json","r")
|
|
local cache
|
|
if cache_file then
|
|
cache = json.decode(cache_file:read("*a"))
|
|
cache_file:close()
|
|
end
|
|
return cache
|
|
end
|
|
|
|
function lib.add_categories(xdg, categories)
|
|
-- Add missing category entries as defined by awesome
|
|
for _,v in pairs(categories) do
|
|
xdg.categories[v.app_type] = {
|
|
name = v.name,
|
|
icon = v.icon_name,
|
|
apps = {}
|
|
}
|
|
end
|
|
end
|
|
|
|
function lib.async_process_dirs(xdg, dirs, cache, on_dir_done)
|
|
-- Asynchronous scanning process
|
|
for _,v in pairs(dirs) do
|
|
xdg.directory_listings[v] = {}
|
|
awful.spawn.with_line_callback("find "..tostring(v).." -maxdepth 1 -name *.desktop",{
|
|
stdout = function(line)
|
|
-- Assume the cache is valid for a listed file
|
|
if cache and cache.directory_listings[v][line] then
|
|
xdg.directory_listings[v][line] = true
|
|
xdg.apps[line] = cache.apps[line]
|
|
xdg.categories[cache.apps[line].category].apps[line] = cache.apps[line]
|
|
return
|
|
end
|
|
local data = menu_utils.parse_desktop_file(line)
|
|
if data.NoDisplay then
|
|
return
|
|
end
|
|
local appdata = {
|
|
name = data.Name,
|
|
category = "Other",
|
|
exec = data.Exec,
|
|
icon = (data.Icon and menu_utils.lookup_icon(data.Icon)),
|
|
description = data.Comment
|
|
}
|
|
-- Match first available cateogry for sorting
|
|
for _,vv in pairs(data.Categories or {"Other"}) do
|
|
if xdg.categories[vv] then
|
|
appdata.category = vv
|
|
break
|
|
end
|
|
-- Oh how do I love those Wine applications and their categories
|
|
if vv:match("^Wine") then
|
|
appdata.category = "Wine"
|
|
break
|
|
end
|
|
end
|
|
-- Open terminal apps in the terminal (duh)
|
|
if data.Terminal then
|
|
appdata.exec = global.terminal.." -e "..appdata.exec
|
|
end
|
|
-- Just for you, Wine - special case because you're being a shit
|
|
if (appdata.exec and appdata.exec:find("%W?wine ")) then
|
|
appdata.category = "Wine"
|
|
end
|
|
xdg.apps[line] = appdata
|
|
xdg.categories[appdata.category].apps[line] = appdata
|
|
-- Add the file to the listing of cached ones
|
|
xdg.directory_listings[v][line] = true
|
|
end,
|
|
output_done = function(...) on_dir_done(v,...) end
|
|
})
|
|
end
|
|
end
|
|
|
|
function lib.generate_meta_patch(xdg)
|
|
local patch = {apps = {}}
|
|
for k,v in pairs(xdg.apps) do
|
|
patch.apps[k] = {}
|
|
for kk,vv in pairs(v) do
|
|
patch.apps[k][kk] = vv
|
|
end
|
|
patch.apps[k].name = nil
|
|
patch.apps[k].category = nil
|
|
patch.apps[k].exec = nil
|
|
patch.apps[k].icon = nil
|
|
patch.apps[k].description = nil
|
|
end
|
|
return patch
|
|
end
|
|
|
|
function lib.apply_meta_patch(xdg,patch)
|
|
for k,v in pairs(patch.apps) do
|
|
if xdg.apps[k] then
|
|
for kk,vv in pairs(v) do
|
|
xdg.apps[k][kk] = vv
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return lib
|