diff options
author | streetturtle <streetturtle@users.noreply.github.com> | 2021-04-09 12:07:37 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-09 12:07:37 -0400 |
commit | fc0293047ba898a546901d53e6cc1ca5c02d8787 (patch) | |
tree | 71d2a338f1aa50445d8f53007be1946041665da0 | |
parent | 9ff8ef85a256145c8344256fdf4156d816e2c7a4 (diff) | |
parent | ef0c35996f28db341f943a729b810d28a32cc853 (diff) |
Merge pull request #246 from atopion/master
Improved performance of the cpu widget
-rw-r--r-- | cpu-widget/cpu-widget.lua | 281 |
1 files changed, 159 insertions, 122 deletions
diff --git a/cpu-widget/cpu-widget.lua b/cpu-widget/cpu-widget.lua index bed40fe..d804c80 100644 --- a/cpu-widget/cpu-widget.lua +++ b/cpu-widget/cpu-widget.lua @@ -17,6 +17,9 @@ local gears = require("gears") local CMD = [[sh -c "grep '^cpu.' /proc/stat; ps -eo '%p|%c|%C|' -o "%mem" -o '|%a' --sort=-%cpu ]] .. [[| head -11 | tail -n +2"]] +-- A smaller command, less resource intensive, used when popup is not shown. +local CMD_slim = [[sh -c "grep '^cpu.' /proc/stat | head -n 1" ]] + local HOME_DIR = os.getenv("HOME") local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/cpu-widget' @@ -111,6 +114,14 @@ local function worker(user_args) color = "linear:0,0:0,20:0,#FF0000:0.3,#FFFF00:0.6," .. color } + -- This timer periodically executes the heavy command while the popup is open. + -- It is stopped when the popup is closed and only the slim command is run then. + -- This greatly improves performance while the popup is closed at the small cost + -- of a slightly longer popup opening time. + local popup_timer = gears.timer { + timeout = timeout + } + local popup = awful.popup{ ontop = true, visible = false, @@ -131,8 +142,14 @@ local function worker(user_args) awful.button({}, 1, function() if popup.visible then popup.visible = not popup.visible + -- When the popup is not visible, stop the timer + popup_timer:stop() else popup:move_next_to(mouse.current_widget_geometry) + -- Restart the timer, when the popup becomes visible + -- Emit the signal to start the timer directly and not wait the timeout first + popup_timer:start() + popup_timer:emit_signal("timeout") end end) ) @@ -149,148 +166,168 @@ local function worker(user_args) widget = wibox.container.margin } - local cpus = {} - watch(CMD, timeout, function(widget, stdout) - local i = 1 - local j = 1 - for line in stdout:gmatch("[^\r\n]+") do - if starts_with(line, 'cpu') then + -- This part runs constantly, also when the popup is closed. + -- It updates the graph widget in the bar. + local maincpu = {} + watch(CMD_slim, timeout, function(widget, stdout) - if cpus[i] == nil then cpus[i] = {} end + local _, user, nice, system, idle, iowait, irq, softirq, steal, _, _ = + stdout:match('(%w+)%s+(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)') - local name, user, nice, system, idle, iowait, irq, softirq, steal, _, _ = - line:match('(%w+)%s+(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)') + local total = user + nice + system + idle + iowait + irq + softirq + steal - local total = user + nice + system + idle + iowait + irq + softirq + steal + local diff_idle = idle - tonumber(maincpu['idle_prev'] == nil and 0 or maincpu['idle_prev']) + local diff_total = total - tonumber(maincpu['total_prev'] == nil and 0 or maincpu['total_prev']) + local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10 - local diff_idle = idle - tonumber(cpus[i]['idle_prev'] == nil and 0 or cpus[i]['idle_prev']) - local diff_total = total - tonumber(cpus[i]['total_prev'] == nil and 0 or cpus[i]['total_prev']) - local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10 + maincpu['total_prev'] = total + maincpu['idle_prev'] = idle - cpus[i]['total_prev'] = total - cpus[i]['idle_prev'] = idle + widget:add_value(diff_usage) + end, + cpugraph_widget + ) - if i == 1 then - widget:add_value(diff_usage) - end + -- This part runs whenever the timer is fired. + -- It therefore only runs when the popup is open. + local cpus = {} + popup_timer:connect_signal('timeout', function() + awful.spawn.easy_async(CMD, function(stdout, _, _, _) + local i = 1 + local j = 1 + for line in stdout:gmatch("[^\r\n]+") do + if starts_with(line, 'cpu') then - local row = wibox.widget - { - create_textbox{text = name}, - create_textbox{text = math.floor(diff_usage) .. '%'}, - { - max_value = 100, - value = diff_usage, - forced_height = 20, - forced_width = 150, - paddings = 1, - margins = 4, - border_width = 1, - border_color = beautiful.bg_focus, - background_color = beautiful.bg_normal, - bar_border_width = 1, - bar_border_color = beautiful.bg_focus, - color = "linear:150,0:0,0:0,#D08770:0.3,#BF616A:0.6," .. beautiful.fg_normal, - widget = wibox.widget.progressbar, + if cpus[i] == nil then cpus[i] = {} end - }, - layout = wibox.layout.ratio.horizontal - } - row:ajust_ratio(2, 0.15, 0.15, 0.7) - cpu_rows[i] = row - i = i + 1 - else - if is_update == true then - - local columns = split(line, '|') - - local pid = columns[1] - local comm = columns[2] - local cpu = columns[3] - local mem = columns[4] - local cmd = columns[5] - - local kill_proccess_button = enable_kill_button and create_kill_process_button() or nil - - local pid_name_rest = wibox.widget{ - create_textbox{text = pid}, - create_textbox{text = comm}, - { - create_textbox{text = cpu, align = 'center'}, - create_textbox{text = mem, align = 'center'}, - kill_proccess_button, - layout = wibox.layout.fixed.horizontal - }, - layout = wibox.layout.ratio.horizontal - } - pid_name_rest:ajust_ratio(2, 0.2, 0.47, 0.33) + local name, user, nice, system, idle, iowait, irq, softirq, steal, _, _ = + line:match('(%w+)%s+(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)') - local row = wibox.widget { - { - pid_name_rest, - top = 4, - bottom = 4, - widget = wibox.container.margin - }, - widget = wibox.container.background - } + local total = user + nice + system + idle + iowait + irq + softirq + steal - row:connect_signal("mouse::enter", function(c) c:set_bg(beautiful.bg_focus) end) - row:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end) + local diff_idle = idle - tonumber(cpus[i]['idle_prev'] == nil and 0 or cpus[i]['idle_prev']) + local diff_total = total - tonumber(cpus[i]['total_prev'] == nil and 0 or cpus[i]['total_prev']) + local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10 - if enable_kill_button then - row:connect_signal("mouse::enter", function() kill_proccess_button.icon.opacity = 1 end) - row:connect_signal("mouse::leave", function() kill_proccess_button.icon.opacity = 0.1 end) + cpus[i]['total_prev'] = total + cpus[i]['idle_prev'] = idle - kill_proccess_button:buttons( - awful.util.table.join( awful.button({}, 1, function() - row:set_bg('#ff0000') - awful.spawn.with_shell('kill -9 ' .. pid) - end) ) ) - end + local row = wibox.widget + { + create_textbox{text = name}, + create_textbox{text = math.floor(diff_usage) .. '%'}, + { + max_value = 100, + value = diff_usage, + forced_height = 20, + forced_width = 150, + paddings = 1, + margins = 4, + border_width = 1, + border_color = beautiful.bg_focus, + background_color = beautiful.bg_normal, + bar_border_width = 1, + bar_border_color = beautiful.bg_focus, + color = "linear:150,0:0,0:0,#D08770:0.3,#BF616A:0.6," .. beautiful.fg_normal, + widget = wibox.widget.progressbar, - awful.tooltip { - objects = { row }, - mode = 'outside', - preferred_positions = {'bottom'}, - timer_function = function() - local text = cmd - if process_info_max_length > 0 and text:len() > process_info_max_length then - text = text:sub(0, process_info_max_length - 3) .. '...' - end - - return text - :gsub('%s%-', '\n\t-') -- put arguments on a new line - :gsub(':/', '\n\t\t:/') -- java classpath uses : to separate jars - end, + }, + layout = wibox.layout.ratio.horizontal } + row:ajust_ratio(2, 0.15, 0.15, 0.7) + cpu_rows[i] = row + i = i + 1 + else + if is_update == true then + + local columns = split(line, '|') + + local pid = columns[1] + local comm = columns[2] + local cpu = columns[3] + local mem = columns[4] + local cmd = columns[5] + + local kill_proccess_button = enable_kill_button and create_kill_process_button() or nil + + local pid_name_rest = wibox.widget{ + create_textbox{text = pid}, + create_textbox{text = comm}, + { + create_textbox{text = cpu, align = 'center'}, + create_textbox{text = mem, align = 'center'}, + kill_proccess_button, + layout = wibox.layout.fixed.horizontal + }, + layout = wibox.layout.ratio.horizontal + } + pid_name_rest:ajust_ratio(2, 0.2, 0.47, 0.33) + + local row = wibox.widget { + { + pid_name_rest, + top = 4, + bottom = 4, + widget = wibox.container.margin + }, + widget = wibox.container.background + } + + row:connect_signal("mouse::enter", function(c) c:set_bg(beautiful.bg_focus) end) + row:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end) + + if enable_kill_button then + row:connect_signal("mouse::enter", function() kill_proccess_button.icon.opacity = 1 end) + row:connect_signal("mouse::leave", function() kill_proccess_button.icon.opacity = 0.1 end) + + kill_proccess_button:buttons( + awful.util.table.join( awful.button({}, 1, function() + row:set_bg('#ff0000') + awful.spawn.with_shell('kill -9 ' .. pid) + end) ) ) + end - process_rows[j] = row + awful.tooltip { + objects = { row }, + mode = 'outside', + preferred_positions = {'bottom'}, + timer_function = function() + local text = cmd + if process_info_max_length > 0 and text:len() > process_info_max_length then + text = text:sub(0, process_info_max_length - 3) .. '...' + end + + return text + :gsub('%s%-', '\n\t-') -- put arguments on a new line + :gsub(':/', '\n\t\t:/') -- java classpath uses : to separate jars + end, + } + + process_rows[j] = row + + j = j + 1 + end - j = j + 1 end - end - end - popup:setup { - { - cpu_rows, + popup:setup { { - orientation = 'horizontal', - forced_height = 15, - color = beautiful.bg_focus, - widget = wibox.widget.separator + cpu_rows, + { + orientation = 'horizontal', + forced_height = 15, + color = beautiful.bg_focus, + widget = wibox.widget.separator + }, + create_process_header{with_action_column = enable_kill_button}, + process_rows, + layout = wibox.layout.fixed.vertical, }, - create_process_header{with_action_column = enable_kill_button}, - process_rows, - layout = wibox.layout.fixed.vertical, - }, - margins = 8, - widget = wibox.container.margin - } - end, - cpugraph_widget - ) + margins = 8, + widget = wibox.container.margin + } + end) + end) return cpu_widget end |