e6501c476ffc0aa162e524d175e64f1b97fe5169
[delightful.git] / delightful / widgets / cpu.lua
1 -------------------------------------------------------------------------------
2 --
3 -- CPU widget for Awesome 3.5
4 -- Copyright (C) 2011-2016 Tuomas Jormola <tj@solitudo.net>
5 --
6 -- Licensed under the terms of GNU General Public License Version 2.0.
7 --
8 -- Description:
9 --
10 -- Displays horizontal usage trend graph of all the CPUs combined.
11 -- Also displays a CPU icon next to the graph. Clicking the icon
12 -- launches an external application (if configured).
13 --
14 -- Widget extends vicious.widgets.cpu from Vicious widget framework.
15 --
16 -- Widget tries to use an icon from the package mate-sensors-applet-common
17 -- if available.
18 --
19 --
20 -- Configuration:
21 --
22 -- The load() function can be supplied with configuration.
23 -- Format of the configuration is as follows.
24 -- {
25 -- -- Width of the graph in pixels. Default is 20.
26 --            graph_width     = 50,
27 -- -- Command to execute when left-clicking the widget icon.
28 -- -- Empty by default.
29 --            command         = 'gnome-system-monitor',
30 -- -- Don't try to display any icons. Default is false (i.e. display icons).
31 --        no_icon         = true,
32 -- -- How often update the widget data. Default is 1 second.
33 --            update_interval = 2
34 -- }
35 --
36 --
37 -- Theme:
38 --
39 -- The widget uses following colors and icons if available in
40 -- the Awesome theme.
41 --
42 -- theme.bg_widget        - widget background color
43 -- theme.fg_widget        - widget foreground color
44 -- theme.fg_center_widget - widget gradient color, middle
45 -- theme.fg_end_widget    - widget gradient color, end
46 -- theme.delightful_cpu   - icon shown next to the CPU graph
47 ---
48 -------------------------------------------------------------------------------
49
50 local awful       = require('awful')
51 local wibox       = require('wibox')
52
53 local delightful  = { utils = require('delightful.utils') }
54 local vicious     = require('vicious')
55
56 local pairs  = pairs
57 local string = { format = string.format }
58
59 module('delightful.widgets.cpu')
60
61 local cpu_config
62 local fatal_error
63 local icon_tooltip
64
65 local config_description = {
66         {
67                 name     = 'graph_width',
68                 required = true,
69                 default  = 20,
70                 validate = function(value) return delightful.utils.config_int(value) end
71         },
72         {
73                 name     = 'command',
74                 validate = function(value) return delightful.utils.config_string(value) end
75         },
76         {
77                 name     = 'no_icon',
78                 validate = function(value) return delightful.utils.config_boolean(value) end
79         },
80         {
81                 name     = 'update_interval',
82                 required = true,
83                 default  = 1,
84                 validate = function(value) return delightful.utils.config_int(value) end
85         },
86 }
87
88 local icon_description = {
89         cpu = { beautiful_name = 'delightful_cpu', default_icon = 'mate-sensors-applet-cpu' },
90 }
91
92 -- Configuration handler
93 function handle_config(user_config)
94         local empty_config = delightful.utils.get_empty_config(config_description)
95         if not user_config then
96                 user_config = empty_config
97         end
98         local config_data = delightful.utils.normalize_config(user_config, config_description)
99         local validation_errors = delightful.utils.validate_config(config_data, config_description)
100         if validation_errors then
101                 fatal_error = 'Configuration errors: \n'
102                 for error_index, error_entry in pairs(validation_errors) do
103                         fatal_error = string.format('%s %s', fatal_error, error_entry)
104                         if error_index < #validation_errors then
105                                 fatal_error = string.format('%s \n', fatal_error)
106                         end
107                 end
108                 cpu_config = empty_config
109                 return
110         end
111         cpu_config = config_data
112 end
113
114 -- Initalization
115 function load(self, config)
116         handle_config(config)
117         if fatal_error then
118                 delightful.utils.print_error('cpu', fatal_error)
119                 return nil, nil
120         end
121         local icon
122         local icon_files
123         if not cpu_config.no_icon then
124                 icon_files = delightful.utils.find_icon_files(icon_description)
125         end
126         local icon_file = icon_files and icon_files.cpu
127         if icon_file then
128                 local buttons = awful.button({}, 1, function()
129                         if not fatal_error and cpu_config.command then
130                                 awful.util.spawn(cpu_config.command, true)
131                         end
132                 end)
133                 icon = wibox.widget.imagebox()
134                 icon:buttons(buttons)
135                 icon:set_image(icon_file)
136                 icon_tooltip = awful.tooltip({ objects = { icon } })
137         end
138
139         local bg_color        = delightful.utils.find_theme_color({ 'bg_widget', 'bg_normal'                     })
140         local fg_color        = delightful.utils.find_theme_color({ 'fg_widget', 'fg_normal'                     })
141         local fg_center_color = delightful.utils.find_theme_color({ 'fg_center_widget', 'fg_widget', 'fg_normal' })
142         local fg_end_color    = delightful.utils.find_theme_color({ 'fg_end_widget', 'fg_widget', 'fg_normal'    })
143
144         local cpu_widget = awful.widget.graph()
145         if bg_color then
146                 cpu_widget:set_background_color(bg_color)
147                 cpu_widget:set_border_color(bg_color)
148         end
149         local color_args = fg_color
150         local width  = cpu_config.graph_width
151         local height = 19
152         if fg_color and fg_center_color and fg_end_color then
153                 color_args = {
154                         type = 'linear',
155                         from = { width / 2, 0 },
156                         to = { width / 2, height },
157                         stops = {{ 0, fg_end_color }, { 0.5, fg_center_color }, { 1, fg_color }},
158                 }
159         end
160         cpu_widget:set_color(color_args)
161         cpu_widget:set_width(width)
162         cpu_widget:set_height(height)
163         local w = wibox.layout.fixed.horizontal()
164         w:add(cpu_widget)
165         vicious.register(cpu_widget, vicious.widgets.cpu, vicious_formatter, cpu_config.update_interval)
166
167         return { w }, { icon }
168 end
169
170 -- Vicious display formatter, also update widget tooltip
171 function vicious_formatter(widget, data)
172         if icon_tooltip then
173                 local tooltip_text = string.format(' CPU usage trend graph of all the CPUs in the system \n Current CPU usage: %d%% ', data[1])
174                 icon_tooltip:set_text(tooltip_text)
175         end
176         return data[1]
177 end