Merge branch 'replace-popen-to-async' of https://github.com/actionless/awesome

This commit is contained in:
Uli Schlachter 2016-04-30 09:11:50 +02:00
commit a1e340d118
3 changed files with 102 additions and 50 deletions

View File

@ -236,9 +236,10 @@ local function menulist_update(query, scr)
end end
--- Create the menubar wibox and widgets. --- Create the menubar wibox and widgets.
local function initialize() -- @tparam[opt] screen scr Screen.
local function initialize(scr)
instance.wibox = wibox({}) instance.wibox = wibox({})
instance.widget = menubar.get() instance.widget = menubar.get(scr)
instance.wibox.ontop = true instance.wibox.ontop = true
instance.prompt = awful.widget.prompt() instance.prompt = awful.widget.prompt()
local layout = wibox.layout.fixed.horizontal() local layout = wibox.layout.fixed.horizontal()
@ -248,8 +249,12 @@ local function initialize()
end end
--- Refresh menubar's cache by reloading .desktop files. --- Refresh menubar's cache by reloading .desktop files.
function menubar.refresh() -- @tparam[opt] screen scr Screen.
menubar.menu_entries = menubar.menu_gen.generate() function menubar.refresh(scr)
menubar.menu_gen.generate(function(entries)
menubar.menu_entries = entries
menulist_update(nil, scr)
end)
end end
--- Awful.prompt keypressed callback to be used when the user presses a key. --- Awful.prompt keypressed callback to be used when the user presses a key.
@ -300,11 +305,11 @@ end
-- @param scr Screen. -- @param scr Screen.
function menubar.show(scr) function menubar.show(scr)
if not instance.wibox then if not instance.wibox then
initialize() initialize(scr)
elseif instance.wibox.visible then -- Menu already shown, exit elseif instance.wibox.visible then -- Menu already shown, exit
return return
elseif not menubar.cache_entries then elseif not menubar.cache_entries then
menubar.refresh() menubar.refresh(scr)
end end
-- Set position and size -- Set position and size
@ -341,9 +346,10 @@ function menubar.hide()
end end
--- Get a menubar wibox. --- Get a menubar wibox.
-- @tparam[opt] screen scr Screen.
-- @return menubar wibox. -- @return menubar wibox.
function menubar.get() function menubar.get(scr)
menubar.refresh() menubar.refresh(scr)
-- Add to each category the name of its key in all_categories -- Add to each category the name of its key in all_categories
for k, v in pairs(menubar.menu_gen.all_categories) do for k, v in pairs(menubar.menu_gen.all_categories) do
v.key = k v.key = k
@ -351,7 +357,7 @@ function menubar.get()
return common_args.w return common_args.w
end end
function menubar.mt:__call(...) function menubar.mt.__call(_, ...)
return menubar.get(...) return menubar.get(...)
end end

View File

@ -83,48 +83,58 @@ local function trim(s)
end end
--- Generate an array of all visible menu entries. --- Generate an array of all visible menu entries.
-- @treturn table All menu entries. -- @tparam function callback Will be fired when all menu entries were parsed
function menu_gen.generate() -- with the resulting list of menu entries as argument.
-- @tparam table callback.entries All menu entries.
function menu_gen.generate(callback)
-- Update icons for category entries -- Update icons for category entries
menu_gen.lookup_category_icons() menu_gen.lookup_category_icons()
local result = {} local result = {}
local unique_entries = {} local unique_entries = {}
local dirs_parsed = 0
for _, dir in ipairs(menu_gen.all_menu_dirs) do for _, dir in ipairs(menu_gen.all_menu_dirs) do
for _, entry in ipairs(utils.parse_dir(dir)) do utils.parse_dir(dir, function(entries)
-- Check whether to include program in the menu entries = entries or {}
if entry.show and entry.Name and entry.cmdline then for _, entry in ipairs(entries) do
local unique_key = entry.Name .. '\0' .. entry.cmdline -- Check whether to include program in the menu
if not unique_entries[unique_key] then if entry.show and entry.Name and entry.cmdline then
local target_category = nil local unique_key = entry.Name .. '\0' .. entry.cmdline
-- Check if the program falls into at least one of the if not unique_entries[unique_key] then
-- usable categories. Set target_category to be the id local target_category = nil
-- of the first category it finds. -- Check if the program falls into at least one of the
if entry.categories then -- usable categories. Set target_category to be the id
for _, category in pairs(entry.categories) do -- of the first category it finds.
local cat_key, cat_use = if entry.categories then
get_category_name_and_usage_by_type(category) for _, category in pairs(entry.categories) do
if cat_key and cat_use then local cat_key, cat_use =
target_category = cat_key get_category_name_and_usage_by_type(category)
break if cat_key and cat_use then
target_category = cat_key
break
end
end end
end end
end if target_category then
if target_category then local name = trim(entry.Name) or ""
local name = trim(entry.Name) or "" local cmdline = trim(entry.cmdline) or ""
local cmdline = trim(entry.cmdline) or "" local icon = entry.icon_path or nil
local icon = entry.icon_path or nil table.insert(result, { name = name,
table.insert(result, { name = name, cmdline = cmdline,
cmdline = cmdline, icon = icon,
icon = icon, category = target_category })
category = target_category }) unique_entries[unique_key] = true
unique_entries[unique_key] = true end
end end
end end
end end
end dirs_parsed = dirs_parsed + 1
if dirs_parsed == #menu_gen.all_menu_dirs then
callback(result)
end
end)
end end
return result
end end
return menu_gen return menu_gen

View File

@ -15,8 +15,11 @@ local string = string
local screen = screen local screen = screen
local awful_util = require("awful.util") local awful_util = require("awful.util")
local theme = require("beautiful") local theme = require("beautiful")
local glib = require("lgi").GLib local lgi = require("lgi")
local gio = lgi.Gio
local glib = lgi.GLib
local wibox = require("wibox") local wibox = require("wibox")
local debug = require("gears.debug")
local utils = {} local utils = {}
@ -242,18 +245,51 @@ function utils.parse_desktop_file(file)
end end
--- Parse a directory with .desktop files recursively. --- Parse a directory with .desktop files recursively.
-- @tparam string dir The directory. -- @tparam string dir_path The directory path.
-- @treturn table Paths of found .desktop files. -- @tparam function callback Will be fired when all the files were parsed
function utils.parse_dir(dir) -- with the resulting list of menu entries as argument.
local programs = {} -- @tparam table callback.programs Paths of found .desktop files.
local files = io.popen('find '.. dir .." -name '*.desktop' 2>/dev/null") function utils.parse_dir(dir_path, callback)
for file in files:lines() do
local program = utils.parse_desktop_file(file) local function parser(dir, programs)
if program then local f = gio.File.new_for_path(dir)
table.insert(programs, program) -- Except for "NONE" there is also NOFOLLOW_SYMLINKS
local enum, err = f:async_enumerate_children("standard::name", gio.FileQueryInfoFlags.NONE)
if not enum then
debug.print_error(err)
return
end end
local files_per_call = 100 -- Actual value is not that important
while true do
local list, enum_err = enum:async_next_files(files_per_call)
if enum_err then
debug.print_error(enum_err)
return
end
for _, info in ipairs(list) do
local file_type = info:get_file_type()
local file_path = enum:get_child(info):get_path()
if file_type == 'REGULAR' then
local program = utils.parse_desktop_file(file_path)
if program then
table.insert(programs, program)
end
elseif file_type == 'DIRECTORY' then
parser(file_path, programs)
end
end
if #list == 0 then
break
end
end
enum:async_close()
end end
return programs
gio.Async.start(function()
local result = {}
parser(dir_path, result)
callback(result)
end)()
end end
--- Compute textbox width. --- Compute textbox width.