ram-widget.lua 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. local awful = require("awful")
  2. local beautiful = require("beautiful")
  3. local gears = require("gears")
  4. local watch = require("awful.widget.watch")
  5. local wibox = require("wibox")
  6. local ram_widget = {}
  7. local CMD = [[bash -c "ps axch -o cmd:17,%mem --sort=-%mem | head -5"]]
  8. local function worker(user_args)
  9. local args = user_args or {}
  10. local TERMINAL = os.getenv("TERMINAL") or "xterm"
  11. local SHELL = os.getenv("SHELL") or "/usr/bin/sh"
  12. local timeout = args.timeout or 1
  13. local fg_color = args.fg_color or beautiful.fg_normal
  14. local bg_color = args.bg_color or beautiful.bg_color or "#00000000"
  15. local popup_bg_color = args.popup_bg_color or beautiful.popup_bg_color or "#222222"
  16. local popup_border_width = args.popup_border_width or beautiful.popup_border_width or 1
  17. local popup_border_color = args.popup_border_color or beautiful.popup_border_color or "#7e7e7e"
  18. local popup_height = args.popup_height or beautiful.popup_height or 6
  19. local popup_width = args.popup_width or beautiful.popup_width or 300
  20. local font_name = args.font_name or beautiful.font
  21. local icon = args.icon or " "
  22. local icon_size = args.icon_size or 11
  23. local font_name_no_size = font_name:gsub("%s%d+$", " ")
  24. local font_size_icon = font_name_no_size .. icon_size or font_name_no_size .. icon_size
  25. ram_widget = wibox.widget {
  26. { -- the first inner widget in ram_widget
  27. id = "txt_icon",
  28. text = icon,
  29. font = font_size_icon,
  30. widget = wibox.widget.textbox,
  31. },
  32. valign = "center",
  33. layout = wibox.layout.align.horizontal,
  34. -- layout = wibox.container.place,
  35. { -- the second (contains two widgets) inner widget in ram_widget
  36. {
  37. id = "txt_ram_usedg",
  38. font = font_name,
  39. widget = wibox.widget.textbox
  40. },
  41. {
  42. id = "txt_ram_usedp",
  43. font = font_name,
  44. widget = wibox.widget.textbox
  45. },
  46. -- spacing = 5,
  47. layout = wibox.layout.fixed.vertical,
  48. }
  49. }
  50. function ram_widget.set(usedg, usedp)
  51. ram_widget:get_children_by_id("txt_ram_usedg")[1]:set_text(usedg)
  52. ram_widget:get_children_by_id("txt_ram_usedp")[1]:set_text(usedp)
  53. end
  54. -- Popup scrolling
  55. local rows, ptr = wibox.layout.fixed.vertical(), 0
  56. rows:connect_signal("button::press", function(_,_,_,button)
  57. if button == 4 then
  58. if ptr > 0 then
  59. rows.children[ptr].visible = true
  60. ptr = ptr - 1
  61. end
  62. elseif button == 5 then
  63. if ptr < #rows.children and ((#rows.children - ptr) > popup_height) then
  64. ptr = ptr + 1
  65. rows.children[ptr].visible = false
  66. end
  67. end
  68. end)
  69. local popup = awful.popup {
  70. border_width = popup_border_width,
  71. border_color = popup_border_color,
  72. shape = gears.shape.rounded_rect,
  73. visible = false,
  74. ontop = true,
  75. offset = { y = 5 },
  76. widget = {}
  77. }
  78. popup:buttons(
  79. awful.util.table.join(
  80. awful.button({}, 3, function()
  81. popup.visible = not popup.visible
  82. end)
  83. )
  84. )
  85. ram_widget:buttons(
  86. awful.util.table.join(
  87. awful.button({}, 1, function()
  88. if popup.visible then
  89. popup.visible = false
  90. else
  91. popup.visible = true
  92. popup:move_next_to(mouse.current_widget_geometry)
  93. -- popup:move_next_to(_G.mouse.current_widget_geometry)
  94. end
  95. end),
  96. awful.button({}, 3, function()
  97. awful.spawn(TERMINAL.." -e "..SHELL.." -c htop")
  98. end)
  99. )
  100. )
  101. -- Show top 5 processes
  102. -- awful.spawn.easy_async_with_shell([[bash -c "ps axch -o cmd:17,%mem --sort=-%mem | head -5"]],
  103. awful.spawn.easy_async_with_shell(CMD,
  104. function(stdout)
  105. local top_tbl = {}
  106. for value in stdout:gmatch("([^\n]+)") do
  107. top_tbl[#top_tbl+1] = value.." %"
  108. end
  109. local popup_header_height, popup_row_height = 30, 20
  110. local header = wibox.widget {
  111. {
  112. nil,
  113. {
  114. markup = "<b> Top of MEMORY usage:</b>",
  115. layout = wibox.widget.textbox,
  116. },
  117. -- {
  118. -- upgr_btn,
  119. -- valign = "center",
  120. -- layout = wibox.container.place,
  121. -- },
  122. expand = "none",
  123. layout = wibox.layout.align.horizontal,
  124. },
  125. forced_height = popup_header_height,
  126. left = 20,
  127. right = 20,
  128. layout = wibox.container.margin
  129. }
  130. for k, v in ipairs(top_tbl) do
  131. for i = 1, #rows.children do
  132. if v == rows.children[i].get_txt() then goto continue end
  133. end
  134. local row = wibox.widget{
  135. {
  136. id = "idx",
  137. text = tostring(k),
  138. widget = wibox.widget.textbox
  139. },
  140. {
  141. id = "txt",
  142. text = v,
  143. forced_height = popup_row_height,
  144. paddings = 1,
  145. widget = wibox.widget.textbox
  146. },
  147. layout = wibox.layout.ratio.horizontal,
  148. }
  149. function row.get_txt() return row:get_children_by_id("txt")[1].text end
  150. function row.set_idx(idx) row:get_children_by_id("idx")[1]:set_text(idx) end
  151. row:ajust_ratio(2, 0.1, 0.9, 0)
  152. rows:insert(k, row)
  153. ::continue::
  154. end
  155. local height = popup_header_height + math.min(#top_tbl, popup_height) * (popup_row_height + 1) -- +1 corrects popup output!!!
  156. popup:setup {
  157. {
  158. {
  159. {
  160. {
  161. header,
  162. rows,
  163. forced_height = height,
  164. layout = wibox.layout.fixed.vertical
  165. },
  166. content_fill_horizontal = true,
  167. layout = wibox.container.place
  168. },
  169. margins = 10,
  170. layout = wibox.container.margin
  171. },
  172. bg = popup_bg_color,
  173. -- bg = beautiful.bg_focus,
  174. layout = wibox.container.background
  175. },
  176. -- forced_width = 300,
  177. forced_width = popup_width,
  178. layout = wibox.layout.fixed.horizontal
  179. }
  180. end
  181. )
  182. --luacheck:ignore 231
  183. local total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap
  184. local function getPercentage(value)
  185. return " "..math.floor(value / (total) * 100 + 0.5).."%"
  186. end
  187. local function getGiB(value)
  188. return string.format("%.1fG", value / 1024 / 1024)
  189. end
  190. watch('bash -c "LANGUAGE=en_US.UTF-8 free | grep -z Mem.*Swap.*"', timeout,
  191. function(widget, stdout)
  192. total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap =
  193. stdout:match('(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*Swap:%s*(%d+)%s*(%d+)%s*(%d+)')
  194. widget.set(getGiB(used), getPercentage(used))
  195. end,
  196. ram_widget
  197. )
  198. -- Set fg and bg colors for ram_widget_icon
  199. local ram_widget_clr = wibox.widget.background()
  200. ram_widget_clr:set_widget(ram_widget)
  201. ram_widget_clr:set_fg(fg_color)
  202. return ram_widget_clr
  203. end
  204. return setmetatable(ram_widget, { __call = function(_, ...) return worker(...) end })