summaryrefslogtreecommitdiff
path: root/.config
diff options
context:
space:
mode:
authorMike Crute <mike@crute.us>2020-10-09 13:09:05 -0700
committerMike Crute <mike@crute.us>2020-10-09 13:09:05 -0700
commit078907053c9fd80c96bec30de47e0543ebc66843 (patch)
treeab802637cd0e9b886b0d3568815ef0d5d2a35be5 /.config
parent3659b50e8b2e1c17646b7f0be83761692924329c (diff)
downloaddotfiles-078907053c9fd80c96bec30de47e0543ebc66843.tar.bz2
dotfiles-078907053c9fd80c96bec30de47e0543ebc66843.tar.xz
dotfiles-078907053c9fd80c96bec30de47e0543ebc66843.zip
awesomewm: add CPU widget
Diffstat (limited to '.config')
-rw-r--r--.config/awesome/cpu-widget.lua287
-rw-r--r--.config/awesome/mcrute.lua12
-rw-r--r--.config/awesome/rc.lua1
-rw-r--r--.config/awesome/window-close-symbolic.svg95
4 files changed, 395 insertions, 0 deletions
diff --git a/.config/awesome/cpu-widget.lua b/.config/awesome/cpu-widget.lua
new file mode 100644
index 0000000..be91e0a
--- /dev/null
+++ b/.config/awesome/cpu-widget.lua
@@ -0,0 +1,287 @@
1-------------------------------------------------
2-- CPU Widget for Awesome Window Manager
3-- Shows the current CPU utilization
4-- More details could be found here:
5-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/cpu-widget
6
7-- @author Pavel Makhov
8-- @copyright 2020 Pavel Makhov
9-------------------------------------------------
10
11local awful = require("awful")
12local watch = require("awful.widget.watch")
13local wibox = require("wibox")
14local beautiful = require("beautiful")
15local gears = require("gears")
16
17local widget = {}
18local cpu_rows = {
19 spacing = 4,
20 layout = wibox.layout.fixed.vertical,
21}
22local is_update = true
23local process_rows = {
24 layout = wibox.layout.fixed.vertical,
25}
26
27-- Splits the string by separator
28-- @return table with separated substrings
29local function split(string_to_split, separator)
30 if separator == nil then separator = "%s" end
31 local t = {}
32
33 for str in string.gmatch(string_to_split, "([^".. separator .."]+)") do
34 table.insert(t, str)
35 end
36
37 return t
38end
39
40-- Checks if a string starts with a another string
41local function starts_with(str, start)
42 return str:sub(1, #start) == start
43end
44
45
46local function create_textbox(args)
47 return wibox.widget{
48 text = args.text,
49 align = args.align or 'left',
50 markup = args.markup,
51 forced_width = args.forced_width or 40,
52 widget = wibox.widget.textbox
53 }
54end
55
56local function create_process_header(params)
57 local res = wibox.widget{
58 create_textbox{markup = '<b>PID</b>'},
59 create_textbox{markup = '<b>Name</b>'},
60 {
61 create_textbox{markup = '<b>%CPU</b>'},
62 create_textbox{markup = '<b>%MEM</b>'},
63 params.with_action_column and create_textbox{forced_width = 20} or nil,
64 layout = wibox.layout.align.horizontal
65 },
66 layout = wibox.layout.ratio.horizontal
67 }
68 res:ajust_ratio(2, 0.2, 0.47, 0.33)
69
70 return res
71end
72
73local function create_kill_process_button()
74 return wibox.widget{
75 {
76 id = "icon",
77 image = gears.filesystem.get_dir("config") .. 'window-close-symbolic.svg',
78 resize = false,
79 opacity = 0.1,
80 widget = wibox.widget.imagebox
81 },
82 widget = wibox.container.background
83 }
84end
85
86local function worker(args)
87
88 local args = args or {}
89
90 local width = args.width or 50
91 local step_width = args.step_width or 2
92 local step_spacing = args.step_spacing or 1
93 local color = args.color or beautiful.fg_normal
94 local enable_kill_button = args.enable_kill_button or false
95 local process_info_max_length = args.process_info_max_length or -1
96 local timeout = args.timeout or 1
97
98 local cpugraph_widget = wibox.widget {
99 max_value = 100,
100 background_color = "#00000000",
101 forced_width = width,
102 step_width = step_width,
103 step_spacing = step_spacing,
104 widget = wibox.widget.graph,
105 color = "linear:0,0:0,20:0,#FF0000:0.3,#FFFF00:0.6," .. color
106 }
107
108 local popup = awful.popup{
109 ontop = true,
110 visible = false,
111 shape = gears.shape.rounded_rect,
112 border_width = 1,
113 border_color = beautiful.bg_normal,
114 maximum_width = 300,
115 offset = { y = 5 },
116 widget = {}
117 }
118
119 -- Do not update process rows when mouse cursor is over the widget
120 popup:connect_signal("mouse::enter", function(c) is_update = false end)
121 popup:connect_signal("mouse::leave", function(c) is_update = true end)
122
123 cpugraph_widget:buttons(
124 awful.util.table.join(
125 awful.button({}, 1, function()
126 if popup.visible then
127 popup.visible = not popup.visible
128 else
129 popup:move_next_to(mouse.current_widget_geometry)
130 end
131 end)
132 )
133 )
134
135 --- By default graph widget goes from left to right, so we mirror it and push up a bit
136 local cpu_widget = wibox.container.margin(wibox.container.mirror(cpugraph_widget, { horizontal = true }), 0, 0, 0, 2)
137
138 local cpus = {}
139 watch([[bash -c "grep '^cpu.' /proc/stat; ps -eo '%p|%c|%C|' -o "%mem" -o '|%a' --sort=-%cpu | head -11 | tail -n +2"]], timeout,
140 function(widget, stdout)
141 local i = 1
142 local j = 1
143 for line in stdout:gmatch("[^\r\n]+") do
144 if starts_with(line, 'cpu') then
145
146 if cpus[i] == nil then cpus[i] = {} end
147
148 local name, user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice =
149 line:match('(%w+)%s+(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)')
150
151 local total = user + nice + system + idle + iowait + irq + softirq + steal
152
153 local diff_idle = idle - tonumber(cpus[i]['idle_prev'] == nil and 0 or cpus[i]['idle_prev'])
154 local diff_total = total - tonumber(cpus[i]['total_prev'] == nil and 0 or cpus[i]['total_prev'])
155 local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10
156
157 cpus[i]['total_prev'] = total
158 cpus[i]['idle_prev'] = idle
159
160 if i == 1 then
161 widget:add_value(diff_usage)
162 end
163
164 local row = wibox.widget
165 {
166 create_textbox{text = name},
167 create_textbox{text = math.floor(diff_usage) .. '%'},
168 {
169 max_value = 100,
170 value = diff_usage,
171 forced_height = 20,
172 forced_width = 150,
173 paddings = 1,
174 margins = 4,
175 border_width = 1,
176 border_color = beautiful.bg_focus,
177 background_color = beautiful.bg_normal,
178 bar_border_width = 1,
179 bar_border_color = beautiful.bg_focus,
180 color = "linear:150,0:0,0:0,#D08770:0.3,#BF616A:0.6," .. beautiful.fg_normal,
181 widget = wibox.widget.progressbar,
182
183 },
184 layout = wibox.layout.ratio.horizontal
185 }
186 row:ajust_ratio(2, 0.15, 0.15, 0.7)
187 cpu_rows[i] = row
188 i = i + 1
189 else
190 if is_update == true then
191
192 local columns = split(line, '|')
193
194 local pid = columns[1]
195 local comm = columns[2]
196 local cpu = columns[3]
197 local mem = columns[4]
198 local cmd = columns[5]
199
200 local kill_proccess_button = enable_kill_button and create_kill_process_button() or nil
201
202 local pid_name_rest = wibox.widget{
203 create_textbox{text = pid},
204 create_textbox{text = comm},
205 {
206 create_textbox{text = cpu, align = 'center'},
207 create_textbox{text = mem, align = 'center'},
208 kill_proccess_button,
209 layout = wibox.layout.fixed.horizontal
210 },
211 layout = wibox.layout.ratio.horizontal
212 }
213 pid_name_rest:ajust_ratio(2, 0.2, 0.47, 0.33)
214
215 local row = wibox.widget {
216 {
217 pid_name_rest,
218 top = 4,
219 bottom = 4,
220 widget = wibox.container.margin
221 },
222 widget = wibox.container.background
223 }
224
225 row:connect_signal("mouse::enter", function(c) c:set_bg(beautiful.bg_focus) end)
226 row:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end)
227
228 if enable_kill_button then
229 row:connect_signal("mouse::enter", function(c) kill_proccess_button.icon.opacity = 1 end)
230 row:connect_signal("mouse::leave", function(c) kill_proccess_button.icon.opacity = 0.1 end)
231
232 kill_proccess_button:buttons(
233 awful.util.table.join( awful.button({}, 1, function()
234 row:set_bg('#ff0000')
235 awful.spawn.with_shell('kill -9 ' .. pid)
236 end) ) )
237 end
238
239 awful.tooltip {
240 objects = { row },
241 mode = 'outside',
242 preferred_positions = {'bottom'},
243 timer_function = function()
244 local text = cmd
245 if process_info_max_length > 0 and text:len() > process_info_max_length then
246 text = text:sub(0, process_info_max_length - 3) .. '...'
247 end
248
249 return text
250 :gsub('%s%-', '\n\t-') -- put arguments on a new line
251 :gsub(':/', '\n\t\t:/') -- java classpath uses : to separate jars
252 end,
253 }
254
255 process_rows[j] = row
256
257 j = j + 1
258 end
259
260 end
261 end
262 popup:setup {
263 {
264 cpu_rows,
265 {
266 orientation = 'horizontal',
267 forced_height = 15,
268 color = beautiful.bg_focus,
269 widget = wibox.widget.separator
270 },
271 create_process_header{with_action_column = enable_kill_button},
272 process_rows,
273 layout = wibox.layout.fixed.vertical,
274 },
275 margins = 8,
276 widget = wibox.container.margin
277 }
278 end,
279 cpugraph_widget
280 )
281
282 return cpu_widget
283end
284
285return setmetatable(widget, { __call = function(_, ...)
286 return worker(...)
287end })
diff --git a/.config/awesome/mcrute.lua b/.config/awesome/mcrute.lua
index 60a9d86..ffed39a 100644
--- a/.config/awesome/mcrute.lua
+++ b/.config/awesome/mcrute.lua
@@ -26,6 +26,7 @@ local pomodoro = require("pomodoro")
26-- transitively through this module. It makes our local customizations to 26-- transitively through this module. It makes our local customizations to
27-- rc.lua just a little easier to grep for. 27-- rc.lua just a little easier to grep for.
28local battery = require("battery") 28local battery = require("battery")
29local _cpu_widget = require("cpu-widget")
29 30
30local timezone = "America/Los_Angeles" 31local timezone = "America/Los_Angeles"
31local tz_file = os.getenv("HOME") .. "/.timezone" 32local tz_file = os.getenv("HOME") .. "/.timezone"
@@ -223,6 +224,16 @@ local function do_equal(p, orientation)
223 end 224 end
224end 225end
225 226
227-- cpu_widget builds a customized widget to indicate the CPU usage
228function cpu_widget()
229 return _cpu_widget({
230 width = 20,
231 step_width = 1,
232 step_spacing = 0,
233 color = '#ff0000'
234 })
235end
236
226-- set_solid_wallpaper sets the gears wallpaper to a solid color as defined in 237-- set_solid_wallpaper sets the gears wallpaper to a solid color as defined in
227-- beautiful.bg_normal 238-- beautiful.bg_normal
228function set_solid_wallpaper(s) 239function set_solid_wallpaper(s)
@@ -600,6 +611,7 @@ return {
600 get_layouts = get_layouts, 611 get_layouts = get_layouts,
601 battery = battery, 612 battery = battery,
602 pomodoro = pomodoro, 613 pomodoro = pomodoro,
614 cpu_widget = cpu_widget,
603 615
604 -- Public functions that are occasionally useful 616 -- Public functions that are occasionally useful
605 split_screen_vertical = split_screen_vertical, 617 split_screen_vertical = split_screen_vertical,
diff --git a/.config/awesome/rc.lua b/.config/awesome/rc.lua
index a827f10..75796ca 100644
--- a/.config/awesome/rc.lua
+++ b/.config/awesome/rc.lua
@@ -183,6 +183,7 @@ awful.screen.connect_for_each_screen(function(s)
183 layout = wibox.layout.fixed.horizontal, 183 layout = wibox.layout.fixed.horizontal,
184 mypomodoro, 184 mypomodoro,
185 wibox.widget.systray(), 185 wibox.widget.systray(),
186 mcrute.cpu_widget(),
186 mcrute.battery(), 187 mcrute.battery(),
187 mytextclock, 188 mytextclock,
188 s.mylayoutbox, 189 s.mylayoutbox,
diff --git a/.config/awesome/window-close-symbolic.svg b/.config/awesome/window-close-symbolic.svg
new file mode 100644
index 0000000..46ff888
--- /dev/null
+++ b/.config/awesome/window-close-symbolic.svg
@@ -0,0 +1,95 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 id="svg7384"
13 version="1.1"
14 height="16"
15 width="16"
16 inkscape:version="0.48.5 r10040"
17 sodipodi:docname="window-close-symbolic.svg">
18 <sodipodi:namedview
19 pagecolor="#ffffff"
20 bordercolor="#666666"
21 borderopacity="1"
22 objecttolerance="10"
23 gridtolerance="10"
24 guidetolerance="10"
25 inkscape:pageopacity="0"
26 inkscape:pageshadow="2"
27 inkscape:window-width="1366"
28 inkscape:window-height="723"
29 id="namedview15"
30 showgrid="true"
31 inkscape:zoom="14.75"
32 inkscape:cx="14.600061"
33 inkscape:cy="10.005214"
34 inkscape:window-x="0"
35 inkscape:window-y="23"
36 inkscape:window-maximized="1"
37 inkscape:current-layer="svg7384">
38 <inkscape:grid
39 type="xygrid"
40 id="grid2992" />
41 </sodipodi:namedview>
42 <title
43 id="title9167">Gnome Symbolic Icon Theme</title>
44 <metadata
45 id="metadata90">
46 <rdf:RDF>
47 <cc:Work
48 rdf:about="">
49 <dc:format>image/svg+xml</dc:format>
50 <dc:type
51 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
52 <dc:title>Gnome Symbolic Icon Theme</dc:title>
53 </cc:Work>
54 </rdf:RDF>
55 </metadata>
56 <defs
57 id="defs7386" />
58 <g
59 transform="translate(-60,-518)"
60 id="layer9"
61 style="display:inline" />
62 <g
63 transform="translate(-60,-518)"
64 id="layer10" />
65 <g
66 transform="translate(-60,-518)"
67 id="layer11" />
68 <g
69 id="g2996"
70 transform="matrix(0.75,0,0,0.75,2,2.0546875)">
71 <g
72 id="layer12"
73 transform="translate(-60,-518)">
74 <g
75 style="display:inline"
76 id="layer4-4-1"
77 transform="translate(19,-242)">
78 <path
79 style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#bebebe;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.78124988;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
80 id="path10839-9"
81 d="m 45,764 1,0 c 0.01037,-1.2e-4 0.02079,-4.6e-4 0.03125,0 0.254951,0.0112 0.50987,0.12858 0.6875,0.3125 L 49,766.59375 51.3125,764.3125 C 51.578125,764.082 51.759172,764.007 52,764 l 1,0 0,1 c 0,0.28647 -0.03434,0.55065 -0.25,0.75 l -2.28125,2.28125 2.25,2.25 C 52.906938,770.46942 52.999992,770.7347 53,771 l 0,1 -1,0 c -0.265301,-10e-6 -0.530586,-0.0931 -0.71875,-0.28125 L 49,769.4375 46.71875,771.71875 C 46.530586,771.90694 46.26529,772 46,772 l -1,0 0,-1 c -3e-6,-0.26529 0.09306,-0.53058 0.28125,-0.71875 l 2.28125,-2.25 L 45.28125,765.75 C 45.070508,765.55537 44.97809,765.28075 45,765 l 0,-1 z"
82 inkscape:connector-curvature="0" />
83 </g>
84 </g>
85 </g>
86 <g
87 transform="translate(-60,-518)"
88 id="layer13" />
89 <g
90 transform="translate(-60,-518)"
91 id="layer14" />
92 <g
93 transform="translate(-60,-518)"
94 id="layer15" />
95</svg>