diff options
author | Mike Crute <mike@crute.us> | 2020-10-09 13:09:05 -0700 |
---|---|---|
committer | Mike Crute <mike@crute.us> | 2020-10-09 13:09:05 -0700 |
commit | 078907053c9fd80c96bec30de47e0543ebc66843 (patch) | |
tree | ab802637cd0e9b886b0d3568815ef0d5d2a35be5 /.config | |
parent | 3659b50e8b2e1c17646b7f0be83761692924329c (diff) | |
download | dotfiles-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.lua | 287 | ||||
-rw-r--r-- | .config/awesome/mcrute.lua | 12 | ||||
-rw-r--r-- | .config/awesome/rc.lua | 1 | ||||
-rw-r--r-- | .config/awesome/window-close-symbolic.svg | 95 |
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 | |||
11 | local awful = require("awful") | ||
12 | local watch = require("awful.widget.watch") | ||
13 | local wibox = require("wibox") | ||
14 | local beautiful = require("beautiful") | ||
15 | local gears = require("gears") | ||
16 | |||
17 | local widget = {} | ||
18 | local cpu_rows = { | ||
19 | spacing = 4, | ||
20 | layout = wibox.layout.fixed.vertical, | ||
21 | } | ||
22 | local is_update = true | ||
23 | local process_rows = { | ||
24 | layout = wibox.layout.fixed.vertical, | ||
25 | } | ||
26 | |||
27 | -- Splits the string by separator | ||
28 | -- @return table with separated substrings | ||
29 | local 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 | ||
38 | end | ||
39 | |||
40 | -- Checks if a string starts with a another string | ||
41 | local function starts_with(str, start) | ||
42 | return str:sub(1, #start) == start | ||
43 | end | ||
44 | |||
45 | |||
46 | local 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 | } | ||
54 | end | ||
55 | |||
56 | local 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 | ||
71 | end | ||
72 | |||
73 | local 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 | } | ||
84 | end | ||
85 | |||
86 | local 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 | ||
283 | end | ||
284 | |||
285 | return setmetatable(widget, { __call = function(_, ...) | ||
286 | return worker(...) | ||
287 | end }) | ||
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. |
28 | local battery = require("battery") | 28 | local battery = require("battery") |
29 | local _cpu_widget = require("cpu-widget") | ||
29 | 30 | ||
30 | local timezone = "America/Los_Angeles" | 31 | local timezone = "America/Los_Angeles" |
31 | local tz_file = os.getenv("HOME") .. "/.timezone" | 32 | local tz_file = os.getenv("HOME") .. "/.timezone" |
@@ -223,6 +224,16 @@ local function do_equal(p, orientation) | |||
223 | end | 224 | end |
224 | end | 225 | end |
225 | 226 | ||
227 | -- cpu_widget builds a customized widget to indicate the CPU usage | ||
228 | function cpu_widget() | ||
229 | return _cpu_widget({ | ||
230 | width = 20, | ||
231 | step_width = 1, | ||
232 | step_spacing = 0, | ||
233 | color = '#ff0000' | ||
234 | }) | ||
235 | end | ||
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 |
228 | function set_solid_wallpaper(s) | 239 | function 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> | ||