menu.lua 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. --[[
  2. Awesome-Freedesktop
  3. Freedesktop.org compliant desktop entries and menu
  4. Menu section
  5. Licensed under GNU General Public License v2
  6. * (c) 2016, Luke Bonham
  7. * (c) 2014, Harvey Mittens
  8. --]]
  9. local Gio = require("lgi").Gio
  10. local awful_menu = require("awful.menu")
  11. local menu_gen = require("menubar.menu_gen")
  12. local menu_utils = require("menubar.utils")
  13. local io, pairs, string, table, os = io, pairs, string, table, os
  14. -- Expecting a wm_name of awesome omits too many applications and tools
  15. menu_utils.wm_name = ""
  16. -- Menu
  17. -- freedesktop.menu
  18. local menu = {}
  19. -- Check if a path is a directory.
  20. -- @tparam string path The directory path
  21. -- @treturn boolean True if path exists and is a directory
  22. function menu.is_dir(path)
  23. return Gio.File.new_for_path(path):query_file_type({}) == "DIRECTORY"
  24. end
  25. -- Remove non existent paths in order to avoid issues
  26. local existent_paths = {}
  27. for k,v in pairs(menu_gen.all_menu_dirs) do
  28. if menu.is_dir(v) then
  29. table.insert(existent_paths, v)
  30. end
  31. end
  32. menu_gen.all_menu_dirs = existent_paths
  33. -- Determines whether an table includes a certain element
  34. -- @param tab a given table
  35. -- @param val the element to search for
  36. -- @return true if the given string is found within the search table; otherwise, false if not
  37. function menu.has_value (tab, val)
  38. for index, value in pairs(tab) do
  39. if val:find(value) then
  40. return true
  41. end
  42. end
  43. return false
  44. end
  45. -- Use MenuBar parsing utils to build a menu for Awesome
  46. -- @return awful.menu
  47. function menu.build(args)
  48. local args = args or {}
  49. local before = args.before or {}
  50. local after = args.after or {}
  51. local skip_items = args.skip_items or {}
  52. local sub_menu = args.sub_menu or false
  53. local result = {}
  54. local _menu = awful_menu({ items = before })
  55. menu_gen.generate(function(entries)
  56. -- Add category icons
  57. for k, v in pairs(menu_gen.all_categories) do
  58. table.insert(result, { k, {}, v.icon })
  59. end
  60. -- Get items table
  61. for k, v in pairs(entries) do
  62. for _, cat in pairs(result) do
  63. if cat[1] == v.category then
  64. if not menu.has_value(skip_items, v.name) then
  65. table.insert(cat[2], { v.name, v.cmdline })
  66. end
  67. break
  68. end
  69. end
  70. end
  71. -- Cleanup things a bit
  72. for i = #result, 1, -1 do
  73. local v = result[i]
  74. if #v[2] == 0 then
  75. -- Remove unused categories
  76. table.remove(result, i)
  77. else
  78. --Sort entries alphabetically (by name)
  79. table.sort(v[2], function (a, b) return string.byte(a[1]) < string.byte(b[1]) end)
  80. -- Replace category name with nice name
  81. v[1] = menu_gen.all_categories[v[1]].name
  82. end
  83. end
  84. -- Sort categories alphabetically also
  85. table.sort(result, function(a, b) return string.byte(a[1]) < string.byte(b[1]) end)
  86. -- Add menu item to hold the generated menu
  87. if sub_menu then
  88. result = {{sub_menu, result}}
  89. end
  90. -- Add items to menu
  91. for _, v in pairs(result) do _menu:add(v) end
  92. for _, v in pairs(after) do _menu:add(v) end
  93. end)
  94. -- Hold the menu in the module
  95. menu.menu = _menu
  96. return _menu
  97. end
  98. return menu