Reno is the second iteration of the AWMTK-powered AwesomeWM config.
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.

143 lines
5.5 KiB

2 years ago
  1. -- This file is part of Reno desktop.
  2. --
  3. -- 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.
  4. --
  5. -- 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.
  6. --
  7. -- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>.
  8. -- Asynchronous XDG data aggregator
  9. local start_human = os.time()
  10. local start_computer = os.clock()
  11. local menu_utils = require("menubar.utils")
  12. local menu_gen = require("menubar.menu_gen")
  13. local awful = require("awful")
  14. local gears = require("gears")
  15. local json = require("dkjson")
  16. menu_utils.wm_name = ""
  17. -- Directories to scan for .desktop files
  18. local desktop_dirs = {}
  19. local desktop_dirs_complete = 0
  20. local _ = ((table.concat(gears.filesystem.get_xdg_data_dirs(),":") or
  21. "/usr/share:/usr/local/share")..":"..os.getenv("HOME").."/.local/share"):gsub("[^:]*",function(path)
  22. if gears.filesystem.dir_readable(path.."/applications") then
  23. table.insert(desktop_dirs, path.."/applications")
  24. end
  25. end)
  26. -- Global xdg data struct
  27. _G.xdg = {
  28. directory_integrity = {},
  29. directory_listings = {},
  30. apps = {},
  31. categories = {
  32. Other = {
  33. icon = "applications-other",
  34. apps = {}
  35. },
  36. Wine = {
  37. icon = "wine",
  38. apps = {}
  39. }
  40. }
  41. }
  42. -- Load cached applications
  43. local cache_file = io.open(gears.filesystem.get_xdg_cache_home()..".reno_xdg_cache.json","r")
  44. local cache
  45. if cache_file then
  46. cache = json.decode(cache_file:read("*a"))
  47. cache_file:close()
  48. end
  49. -- Add missing category entries as defined by awesome
  50. for _,v in pairs(menu_gen.all_categories) do
  51. xdg.categories[v.app_type] = {
  52. name = v.name,
  53. icon = v.icon_name,
  54. apps = {}
  55. }
  56. end
  57. -- Asynchronous scanning process
  58. for _,v in pairs(desktop_dirs) do
  59. xdg.directory_listings[v] = {}
  60. awful.spawn.with_line_callback("find "..tostring(v).." -maxdepth 1 -name *.desktop",{
  61. stdout = function(line)
  62. -- Assume the cache is valid for a listed file
  63. if cache and cache.directory_listings[v][line] then
  64. xdg.directory_listings[v][line] = true
  65. xdg.apps[line] = cache.apps[line]
  66. xdg.categories[cache.apps[line].category].apps[line] = cache.apps[line]
  67. return
  68. end
  69. local data = menu_utils.parse_desktop_file(line)
  70. if data.NoDisplay then
  71. return
  72. end
  73. local appdata = {
  74. name = data.Name,
  75. category = "Other",
  76. exec = data.Exec,
  77. icon = (data.Icon and menu_utils.lookup_icon(data.Icon)),
  78. description = data.Comment
  79. }
  80. -- Match first available cateogry for sorting
  81. for _,vv in pairs(data.Categories or {"Other"}) do
  82. if xdg.categories[vv] then
  83. appdata.category = vv
  84. break
  85. end
  86. -- Oh how do I love those Wine applications and their categories
  87. if vv:match("^Wine") then
  88. appdata.category = "Wine"
  89. break
  90. end
  91. end
  92. -- Open terminal apps in the terminal (duh)
  93. if data.Terminal then
  94. appdata.exec = global.terminal.." -e "..appdata.exec
  95. end
  96. -- Just for you, Wine - special case because you're being a shit
  97. if (appdata.exec and appdata.exec:find("%W?wine ")) then
  98. appdata.category = "Wine"
  99. end
  100. xdg.apps[line] = appdata
  101. xdg.categories[appdata.category].apps[line] = appdata
  102. -- Add the file to the listing of cached ones
  103. xdg.directory_listings[v][line] = true
  104. end,
  105. output_done = function()
  106. -- Save directory listing hash
  107. desktop_dirs_complete = desktop_dirs_complete + 1
  108. -- Call a global signal
  109. awesome.emit_signal("xdg::dir_finished",v)
  110. end
  111. })
  112. end
  113. local count = function(t)
  114. local n = 0
  115. for _,_ in pairs(t) do
  116. n = n + 1
  117. end
  118. return n
  119. end
  120. awesome.connect_signal("xdg::dir_finished",function(dir)
  121. -- We only send the all_finished signal when all directories finished processing
  122. if desktop_dirs_complete == #desktop_dirs then
  123. -- Clean up empty categories
  124. for k,v in pairs(xdg.categories) do
  125. if count(v.apps) == 0 then
  126. xdg.categories[k] = nil
  127. end
  128. end
  129. -- Save the cache if it doesn't exist yet
  130. io.open(gears.filesystem.get_xdg_cache_home()..".reno_xdg_cache.json","w"):write(json.encode(xdg)):close()
  131. require("naughty").notify({title = "Human time: "..tostring(os.time()-start_human),text = "Computer time: "..tostring(os.clock()-start_computer)})
  132. -- Finally, call the all_finished signal
  133. awesome.emit_signal("xdg::all_finished")
  134. end
  135. end)