pacman.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. local naughty = require("naughty")
  2. local wibox = require("wibox")
  3. local awful = require("awful")
  4. local beautiful = require("beautiful")
  5. local gears = require("gears")
  6. local HOME = os.getenv("HOME")
  7. local DIR = HOME .. "/.config/awesome/awesome-wm-widgets/pacman-widget/"
  8. local pacman_widget = {}
  9. local timer = {}
  10. -- config.interval = 10800
  11. -- config.popup_bg_color = "#222222"
  12. -- config.popup_border_width = 1
  13. -- config.popup_border_color = "#7e7e7e"
  14. -- config.popup_height = 25
  15. -- config.popup_width = 500
  16. -- -- config.polkit_agent_path = "/usr/bin/lxpolkit"
  17. --
  18. -- local function worker(user_args)
  19. -- local args, _config = user_args or {}, {}
  20. -- for prop, value in pairs(config) do
  21. -- _config[prop] = args[prop] or beautiful[prop] or value
  22. -- end
  23. local function worker(user_args)
  24. local args = user_args or {}
  25. local interval = args.interval or 10800
  26. local fg_color = args.fg_color or beautiful.fg_normal
  27. local bg_color = args.bg_color or beautiful.bg_color or "#00000000"
  28. local popup_bg_color = args.popup_bg_color or beautiful.popup_bg_color or "#222222"
  29. local popup_border_width = args.popup_border_width or beautiful.popup_border_width or 1
  30. local popup_border_color = args.popup_border_color or beautiful.popup_border_color or "#7e7e7e"
  31. local popup_height = args.popup_height or beautiful.popup_height or 25
  32. local popup_width = args.popup_width or beautiful.popup_width or 500
  33. local font_name = args.font_name or beautiful.font
  34. local icon = args.icon or ""
  35. local icon_size = args.icon_size or 11
  36. local font_name_no_size = font_name:gsub("%s%d+$", " ")
  37. local font_size_icon = font_name_no_size .. icon_size or font_name_no_size .. icon_size
  38. -- local polkit_agent_path = "/usr/bin/lxpolkit"
  39. -- awful.spawn.once(polkit_agent_path)
  40. pacman_widget = wibox.widget {
  41. {
  42. id = "txt_icon",
  43. text = icon,
  44. font = font_size_icon,
  45. widget = wibox.widget.textbox,
  46. },
  47. valign = "center",
  48. layout = wibox.layout.fixed.horizontal,
  49. -- layout = wibox.container.place,
  50. {
  51. id = "txt_updates",
  52. font = font_name,
  53. widget = wibox.widget.textbox
  54. },
  55. spacing = 3,
  56. -- spacing = 5,
  57. layout = wibox.layout.fixed.horizontal,
  58. }
  59. function pacman_widget.set(new_value)
  60. pacman_widget:get_children_by_id("txt_updates")[1]:set_text(new_value)
  61. -- pacman_widget:get_children_by_id("txt_icon")[1]:set_text(" ")
  62. end
  63. -- Popup scrolling
  64. local rows, ptr = wibox.layout.fixed.vertical(), 0
  65. rows:connect_signal("button::press", function(_,_,_,button)
  66. if button == 4 then
  67. if ptr > 0 then
  68. rows.children[ptr].visible = true
  69. ptr = ptr - 1
  70. end
  71. elseif button == 5 then
  72. if ptr < #rows.children and ((#rows.children - ptr) > popup_height) then
  73. ptr = ptr + 1
  74. rows.children[ptr].visible = false
  75. end
  76. end
  77. end)
  78. local popup = awful.popup {
  79. border_width = popup_border_width,
  80. border_color = popup_border_color,
  81. shape = gears.shape.rounded_rect,
  82. visible = false,
  83. ontop = true,
  84. offset = { y = 5 },
  85. widget = {}
  86. }
  87. popup:buttons(
  88. awful.util.table.join(
  89. awful.button({}, 3, function()
  90. popup.visible = not popup.visible
  91. end)
  92. )
  93. )
  94. pacman_widget:buttons(
  95. awful.util.table.join(
  96. awful.button({}, 1, function()
  97. if popup.visible then
  98. popup.visible = false
  99. else
  100. popup.visible = true
  101. popup:move_next_to(_G.mouse.current_widget_geometry)
  102. end
  103. end),
  104. awful.button({}, 3, function()
  105. awful.spawn(HOME.."/.config/awesome/scripts/show_updates.sh")
  106. end)
  107. )
  108. )
  109. local upgr_opacity = 0.6
  110. local upgr_btn = wibox.widget {
  111. {
  112. -- image = ICON_DIR .. "upgrade.svg",
  113. -- resize = false,
  114. -- layout = wibox.widget.imagebox
  115. text = " ",
  116. layout = wibox.widget.textbox
  117. },
  118. opacity = upgr_opacity,
  119. layout = wibox.container.background
  120. }
  121. local old_cursor, old_wibox
  122. local busy, upgrading = false, false
  123. upgr_btn:connect_signal("mouse::enter", function(c)
  124. if not busy then
  125. c:set_opacity(1)
  126. c:emit_signal("widget::redraw_needed")
  127. local wb = _G.mouse.current_wibox
  128. old_cursor, old_wibox = wb.cursor, wb
  129. wb.cursor = "hand2"
  130. end
  131. end)
  132. upgr_btn:connect_signal("mouse::leave", function(c)
  133. if not busy then
  134. c:set_opacity(upgr_opacity)
  135. c:emit_signal("widget::redraw_needed")
  136. if old_wibox then
  137. old_wibox.cursor = old_cursor
  138. old_wibox = nil
  139. end
  140. end
  141. end)
  142. upgr_btn:connect_signal("button::release", function(c)
  143. c:set_opacity(1)
  144. c:emit_signal("widget::redraw_needed")
  145. if old_wibox then
  146. old_wibox.cursor = old_cursor
  147. old_wibox = nil
  148. end
  149. if not busy then
  150. busy = true
  151. local one_shot = true
  152. awful.spawn.with_line_callback("bash -c " .. DIR .. "upgrade", {
  153. stdout = function()
  154. if one_shot then
  155. upgrading, one_shot = true, false
  156. timer:emit_signal("timeout")
  157. end
  158. end,
  159. stderr = function(line)
  160. if (line ~= nil and line ~= "") then
  161. if string.find(line, "warning") then
  162. naughty.notify({
  163. title = "Warning!",
  164. text = line,
  165. timeout = 0
  166. })
  167. else
  168. naughty.notify({
  169. preset = naughty.config.presets.critical,
  170. title = "Error!",
  171. text = line,
  172. })
  173. end
  174. end
  175. end,
  176. exit = function()
  177. upgrading, busy = false, false
  178. c:set_opacity(upgr_opacity)
  179. c:emit_signal("widget::redraw_needed")
  180. timer:emit_signal("timeout")
  181. end,
  182. })
  183. end
  184. popup.visible = false
  185. end)
  186. -- Check updates in interval
  187. timer = select(2, awful.widget.watch([[bash -c "checkupdates-with-aur 2>/dev/null"]],
  188. interval,
  189. function(widget, stdout)
  190. local upgrades_tbl = {}
  191. for value in stdout:gmatch("([^\n]+)") do
  192. upgrades_tbl[#upgrades_tbl+1] = value
  193. end
  194. widget.set(#upgrades_tbl)
  195. -- Hide widget if no updates
  196. widget.visible = (#upgrades_tbl > 0) or false
  197. -- widget.visible = (#upgrades_tbl == 0) or true
  198. -- if (#upgrades_tbl == 0) then widget.visible = false else widget.visible = true end
  199. local popup_header_height, popup_row_height = 30, 20
  200. local header = wibox.widget {
  201. {
  202. nil,
  203. {
  204. markup = "<b>" .. (upgrading and "Upgrading " .. #upgrades_tbl .. " Packages" or
  205. (#upgrades_tbl == 0 and "No" or #upgrades_tbl) .. " Available Upgrades") .. "</b>",
  206. layout = wibox.widget.textbox,
  207. },
  208. #upgrades_tbl > 0 and {
  209. upgr_btn,
  210. valign = "center",
  211. layout = wibox.container.place,
  212. },
  213. expand = "none",
  214. layout = wibox.layout.align.horizontal,
  215. },
  216. forced_height = popup_header_height,
  217. left = 20,
  218. right = 20,
  219. layout = wibox.container.margin
  220. }
  221. for k, v in ipairs(upgrades_tbl) do
  222. for i = 1, #rows.children do
  223. if v == rows.children[i].get_txt() then goto continue end
  224. end
  225. local row = wibox.widget{
  226. {
  227. id = "idx",
  228. text = tostring(k),
  229. widget = wibox.widget.textbox
  230. },
  231. {
  232. id = "txt",
  233. text = v,
  234. forced_height = popup_row_height,
  235. paddings = 1,
  236. widget = wibox.widget.textbox
  237. },
  238. layout = wibox.layout.ratio.horizontal,
  239. }
  240. function row.get_txt() return row:get_children_by_id("txt")[1].text end
  241. function row.set_idx(idx) row:get_children_by_id("idx")[1]:set_text(idx) end
  242. row:ajust_ratio(2, 0.1, 0.9, 0)
  243. rows:insert(k, row)
  244. ::continue::
  245. end
  246. -- local height = popup_header_height + math.min(#upgrades_tbl, popup_height) * popup_row_height
  247. local height = popup_header_height + math.min(#upgrades_tbl, popup_height) * (popup_row_height + 1) -- +1 corrects popup output!!!
  248. popup:setup {
  249. {
  250. {
  251. {
  252. {
  253. header,
  254. rows,
  255. forced_height = height,
  256. layout = wibox.layout.fixed.vertical
  257. },
  258. content_fill_horizontal = true,
  259. layout = wibox.container.place
  260. },
  261. margins = 10,
  262. layout = wibox.container.margin
  263. },
  264. bg = popup_bg_color,
  265. layout = wibox.container.background
  266. },
  267. forced_width = popup_width,
  268. layout = wibox.layout.fixed.horizontal
  269. }
  270. end,
  271. pacman_widget
  272. ))
  273. -- Set fg and bg colors for pacman_widget
  274. local pacman_widget_clr = wibox.widget.background()
  275. pacman_widget_clr:set_widget(pacman_widget)
  276. pacman_widget_clr:set_fg(fg_color)
  277. -- pacman_widget_clr:set_bg("#ff0000")
  278. -- return wibox.container.background(pacman_widget, "#ff0000")
  279. return pacman_widget_clr
  280. -- return pacman_widget
  281. end
  282. return setmetatable(pacman_widget, { __call = function(_, ...) return worker(...) end })