My configuration files for Debian/Ubuntu applications
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.

преди 3 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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 io = io
  14. local ipairs = ipairs
  15. local mouse = mouse
  16. local os = os
  17. local string = string
  18. local screen = screen
  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. 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. local dcp = desktop.current_pos
  67. -- define icon dimensions and position
  68. if not dcp[s] then
  69. dcp[s] = { x = (screen[s].geometry.x + args.iconsize.width + args.margin.x), y = screen[s].geometry.y + 20 + args.margin.y }
  70. end
  71. local tot_height = (icon and args.iconsize.height or 0) + (label and args.labelsize.height or 0)
  72. if tot_height == 0 then return end
  73. if dcp[s].y + tot_height > screen[s].geometry.y + screen[s].geometry.height - 20 - args.margin.y then
  74. dcp[s].x = dcp[s].x + args.labelsize.width + args.iconsize.width + args.margin.x
  75. dcp[s].y = 20 + args.margin.y
  76. end
  77. local common = { screen = s, bg = "#00000000", visible = true, type = "desktop" }
  78. -- create icon container
  79. if icon then
  80. common.width = args.iconsize.width
  81. common.height = args.iconsize.height
  82. common.x = dcp[s].x
  83. common.y = dcp[s].y
  84. icon = wibox.widget {
  85. image = icon,
  86. resize = false,
  87. widget = wibox.widget.imagebox
  88. }
  89. icon:buttons(awful.button({ }, 1, nil, onclick))
  90. icon_container = wibox(common)
  91. icon_container:set_widget(icon)
  92. dcp[s].y = dcp[s].y + args.iconsize.height + 5
  93. end
  94. -- create label container
  95. if label then
  96. common.width = args.labelsize.width
  97. common.height = args.labelsize.height
  98. common.x = dcp[s].x - (args.labelsize.width/2) + args.iconsize.width/2
  99. common.y = dcp[s].y
  100. caption = wibox.widget {
  101. text = label,
  102. align = "center",
  103. forced_width = common.width,
  104. forced_height = common.height,
  105. ellipsize = "middle",
  106. widget = wibox.widget.textbox
  107. }
  108. caption:buttons(awful.button({ }, 1, onclick))
  109. caption_container = wibox(common)
  110. caption_container:set_widget(caption)
  111. end
  112. dcp[s].y = dcp[s].y + args.labelsize.height + args.margin.y
  113. desktop.current_pos = dcp
  114. return dcp
  115. end
  116. -- Adds base icons (This PC, Trash, etc) to desktop
  117. -- @param args settings from desktop.add_icons
  118. function desktop.add_base_icons(args)
  119. for _,base in ipairs(args.baseicons) do
  120. desktop.add_single_icon(args, base.label, utils.lookup_icon(base.icon), function()
  121. awful.spawn(string.format("%s '%s'", args.open_with, base.onclick))
  122. end)
  123. end
  124. end
  125. -- Looks up a suitable icon for filename
  126. -- @param filename string file name
  127. -- @return icon file path (string)
  128. function desktop.lookup_file_icon(filename)
  129. -- load system MIME types
  130. if #mime_types == 0 then
  131. for line in io.lines("/etc/mime.types") do
  132. if not line:find("^#") then
  133. local parsed = {}
  134. for w in line:gmatch("[^%s]+") do
  135. table.insert(parsed, w)
  136. end
  137. if #parsed > 1 then
  138. for i = 2, #parsed do
  139. mime_types[parsed[i]] = parsed[1]:gsub("/", "-")
  140. end
  141. end
  142. end
  143. end
  144. end
  145. -- try to search a possible icon among standards
  146. local extension = filename:match("%a+$")
  147. local mime = mime_types[extension] or ""
  148. local mime_family = mime:match("^%a+") or ""
  149. local possible_filenames = {
  150. mime, "gnome-mime-" .. mime,
  151. mime_family, "gnome-mime-" .. mime_family,
  152. extension
  153. }
  154. for i, filename in ipairs(possible_filenames) do
  155. local icon = utils.lookup_icon(filename)
  156. if icon then return icon end
  157. end
  158. -- if we don"t find ad icon, then pretend is a plain text file
  159. return utils.lookup_icon("text-x-generic")
  160. end
  161. -- Parse subdirectories and files list from input directory
  162. -- @input dir directory to parse (string)
  163. -- @return files table with found entries
  164. function desktop.parse_dirs_and_files(dir)
  165. local files = {}
  166. local paths = pipelines('find '..dir..' -maxdepth 1 -type d |sort|tail -n +1')
  167. for path in paths do
  168. if path:match("[^/]+$") then
  169. local file = {}
  170. file.filename = path:match("[^/]+$")
  171. file.path = path
  172. file.show = true
  173. file.icon = utils.lookup_icon("folder")
  174. table.insert(files, file)
  175. end
  176. end
  177. local paths = pipelines('find '..dir..' -maxdepth 1 -type f')
  178. for path in paths do
  179. if not path:find("%.desktop$") then
  180. local file = {}
  181. file.filename = path:match("[^/]+$")
  182. file.path = path
  183. file.show = true
  184. file.icon = desktop.lookup_file_icon(file.filename)
  185. table.insert(files, file)
  186. end
  187. end
  188. return files
  189. end
  190. -- Adds subdirectories and files icons from args.dir
  191. -- @param args settings from desktop.add_icons
  192. function desktop.add_dirs_and_files_icons(args)
  193. for _, file in ipairs(desktop.parse_dirs_and_files(args.dir)) do
  194. if file.show then
  195. local label = args.showlabels and file.filename or nil
  196. local onclick = function () awful.spawn(string.format("%s '%s'", args.open_with, file.path)) end
  197. desktop.add_single_icon(args, label, file.icon, onclick)
  198. end
  199. end
  200. end
  201. -- Main function, adds base, directory and files icons
  202. -- @param args user defined settings, with fallback on defaults
  203. function desktop.add_icons(args)
  204. args = args or {}
  205. args.screen = args.screen or mouse.screen
  206. args.dir = args.dir or os.getenv("HOME") .. "/Desktop"
  207. args.showlabels = args.showlabel or true
  208. args.open_with = args.open_with or "xdg_open"
  209. args.baseicons = args.baseicons or desktop.baseicons
  210. args.iconsize = args.iconsize or desktop.iconsize
  211. args.labelsize = args.labelsize or desktop.labelsize
  212. args.margin = args.margin or desktop.margin
  213. -- trying to fallback on Adwaita if theme.icon_theme is not defined
  214. -- if Adwaita is missing too, no icons will be shown
  215. if not theme.icon_theme then
  216. theme.icon_theme = args.icon_theme or "Adwaita"
  217. end
  218. desktop.add_base_icons(args)
  219. desktop.add_dirs_and_files_icons(args)
  220. end
  221. return desktop