All of my important config files
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.

254 lines
7.8 KiB

  1. --[[
  2. Awesome-Freedesktop
  3. Freedesktop.org compliant desktop entries and menu
  4. Desktop section
  5. Licensed under GNU General Public License v2
  6. * (c) 2016, Luke Bonham
  7. * (c) 2009-2015, Antonio Terceiro
  8. --]]
  9. local awful = require("awful")
  10. local theme = require("beautiful")
  11. local utils = require("menubar.utils")
  12. local wibox = require("wibox")
  13. local capi = capi
  14. local io = io
  15. local ipairs = ipairs
  16. local mouse = mouse
  17. local os = os
  18. local string = string
  19. local table = table
  20. -- Desktop icons
  21. -- freedesktop.desktop
  22. local desktop = {
  23. -- Default desktop basic icons
  24. baseicons = {
  25. [1] = {
  26. label = "This PC",
  27. icon = "computer",
  28. onclick = "computer://"
  29. },
  30. [2] = {
  31. label = "Home",
  32. icon = "user-home",
  33. onclick = os.getenv("HOME")
  34. },
  35. [3] = {
  36. label = "Trash",
  37. icon = "user-trash",
  38. onclick = "trash://"
  39. }
  40. },
  41. -- Default parameters
  42. iconsize = { width = 48, height = 48 },
  43. labelsize = { width = 140, height = 20 },
  44. margin = { x = 20, y = 20 },
  45. }
  46. -- MIME types list
  47. local mime_types = {}
  48. -- Icons positioning
  49. local desktop_current_pos = {}
  50. -- @return iterator on input pipe
  51. local function pipelines(...)
  52. local f = assert(io.popen(...))
  53. return function ()
  54. local data = f:read()
  55. if data == nil then f:close() end
  56. return data
  57. end
  58. end
  59. -- Adds an icon to desktop
  60. -- @param args settings from desktop.add_icons
  61. -- @param label icon string label
  62. -- @param icon icon string file path
  63. -- @param onclick function to execute on click
  64. function desktop.add_single_icon(args, label, icon, onclick)
  65. local s = args.screen
  66. -- define icon dimensions and position
  67. if not desktop_current_pos[s] then
  68. desktop_current_pos[s] = { x = (capi.screen[s].geometry.x + args.iconsize.width + args.margin.x), y = 40 }
  69. end
  70. local totheight = (icon and args.iconsize.height or 0) + (label and args.labelsize.height or 0)
  71. if totheight == 0 then return end
  72. if desktop_current_pos[s].y + totheight > capi.screen[s].geometry.height - 40 then
  73. desktop_current_pos[s].x = desktop_current_pos[s].x + args.labelsize.width + args.iconsize.width + args.margin.x
  74. desktop_current_pos[s].y = 40
  75. end
  76. local common = { screen = s, bg = "#00000000", visible = true, type = "desktop" }
  77. -- create icon container
  78. if icon then
  79. common.width = args.iconsize.width
  80. common.height = args.iconsize.height
  81. common.x = desktop_current_pos[s].x
  82. common.y = desktop_current_pos[s].y
  83. icon = wibox.widget {
  84. image = icon,
  85. resize = false,
  86. widget = wibox.widget.imagebox
  87. }
  88. icon:buttons(awful.button({ }, 1, nil, onclick))
  89. icon_container = wibox(common)
  90. icon_container:set_widget(icon)
  91. desktop_current_pos[s].y = desktop_current_pos[s].y + args.iconsize.height + 5
  92. end
  93. -- create label container
  94. if label then
  95. common.width = args.labelsize.width
  96. common.height = args.labelsize.height
  97. common.x = desktop_current_pos[s].x - (args.labelsize.width/2) + args.iconsize.width/2
  98. common.y = desktop_current_pos[s].y
  99. caption = wibox.widget {
  100. text = label,
  101. align = "center",
  102. forced_width = common.width,
  103. forced_height = common.height,
  104. ellipsize = "middle",
  105. widget = wibox.widget.textbox
  106. }
  107. caption:buttons(awful.button({ }, 1, onclick))
  108. caption_container = wibox(common)
  109. caption_container:set_widget(caption)
  110. end
  111. desktop_current_pos[s].y = desktop_current_pos[s].y + args.labelsize.height + args.margin.y
  112. end
  113. -- Adds base icons (This PC, Trash, etc) to desktop
  114. -- @param args settings from desktop.add_icons
  115. function desktop.add_base_icons(args)
  116. for _,base in ipairs(args.baseicons) do
  117. desktop.add_single_icon(args, base.label, utils.lookup_icon(base.icon), function()
  118. awful.spawn(string.format("%s '%s'", args.open_with, base.onclick))
  119. end)
  120. end
  121. end
  122. -- Looks up a suitable icon for filename
  123. -- @param filename string file name
  124. -- @return icon file path (string)
  125. function desktop.lookup_file_icon(filename)
  126. -- load system MIME types
  127. if #mime_types == 0 then
  128. for line in io.lines("/etc/mime.types") do
  129. if not line:find("^#") then
  130. local parsed = {}
  131. for w in line:gmatch("[^%s]+") do
  132. table.insert(parsed, w)
  133. end
  134. if #parsed > 1 then
  135. for i = 2, #parsed do
  136. mime_types[parsed[i]] = parsed[1]:gsub("/", "-")
  137. end
  138. end
  139. end
  140. end
  141. end
  142. -- try to search a possible icon among standards
  143. local extension = filename:match("%a+$")
  144. local mime = mime_types[extension] or ""
  145. local mime_family = mime:match("^%a+") or ""
  146. local possible_filenames = {
  147. mime, "gnome-mime-" .. mime,
  148. mime_family, "gnome-mime-" .. mime_family,
  149. extension
  150. }
  151. for i, filename in ipairs(possible_filenames) do
  152. local icon = utils.lookup_icon(filename)
  153. if icon then return icon end
  154. end
  155. -- if we don"t find ad icon, then pretend is a plain text file
  156. return utils.lookup_icon("text-x-generic")
  157. end
  158. -- Parse subdirectories and files list from input directory
  159. -- @input dir directory to parse (string)
  160. -- @return files table with found entries
  161. function desktop.parse_dirs_and_files(dir)
  162. local files = {}
  163. local paths = pipelines('find '..dir..' -maxdepth 1 -type d | tail -1')
  164. for path in paths do
  165. if path:match("[^/]+$") then
  166. local file = {}
  167. file.filename = path:match("[^/]+$")
  168. file.path = path
  169. file.show = true
  170. file.icon = utils.lookup_icon("folder")
  171. table.insert(files, file)
  172. end
  173. end
  174. local paths = pipelines('find '..dir..' -maxdepth 1 -type f')
  175. for path in paths do
  176. if not path:find("%.desktop$") then
  177. local file = {}
  178. file.filename = path:match("[^/]+$")
  179. file.path = path
  180. file.show = true
  181. file.icon = desktop.lookup_file_icon(file.filename)
  182. table.insert(files, file)
  183. end
  184. end
  185. return files
  186. end
  187. -- Adds subdirectories and files icons from args.dir
  188. -- @param args settings from desktop.add_icons
  189. function desktop.add_dirs_and_files_icons(args)
  190. for _, file in ipairs(desktop.parse_dirs_and_files(args.dir)) do
  191. if file.show then
  192. local label = args.showlabels and file.filename or nil
  193. local onclick = function () awful.spawn(string.format("%s '%s'", args.open_with, file.path)) end
  194. desktop.add_single_icon(args, label, file.icon, onclick)
  195. end
  196. end
  197. end
  198. -- Main function, adds base, directory and files icons
  199. -- @param args user defined settings, with fallback on defaults
  200. function desktop.add_icons(args)
  201. args = args or {}
  202. args.screen = args.screen or mouse.screen
  203. args.dir = args.dir or os.getenv("HOME") .. "/Desktop"
  204. args.showlabels = args.showlabel or true
  205. args.open_with = args.open_with or "xdg_open"
  206. args.baseicons = args.baseicons or desktop.baseicons
  207. args.iconsize = args.iconsize or desktop.iconsize
  208. args.labelsize = args.labelsize or desktop.labelsize
  209. args.margin = args.margin or desktop.margin
  210. -- trying to fallback on Adwaita if theme.icon_theme is not defined
  211. -- if Adwaita is missing too, no icons will be shown
  212. if not theme.icon_theme then
  213. theme.icon_theme = args.icon_theme or "Adwaita"
  214. end
  215. desktop.add_base_icons(args)
  216. desktop.add_dirs_and_files_icons(args)
  217. end
  218. return desktop