process-row.vala 8.81 KB
Newer Older
1
using Posix;
2
using Gee;
3

Petr Štětka's avatar
Petr Štětka committed
4
5
namespace Usage
{
Petr Štětka's avatar
Petr Štětka committed
6
    public class ProcessRow : Gtk.ListBoxRow
Petr Štětka's avatar
Petr Štětka committed
7
8
9
    {
        Gtk.Label load_label;
        Gtk.Revealer revealer;
Petr Štětka's avatar
Petr Štětka committed
10
        SubProcessListBox sub_process_list_box;
11
        string display_name;
12
        static GLib.List<AppInfo> apps_info;
Petr Štětka's avatar
Petr Štětka committed
13
        ProcessListBoxType type;
Petr Štětka's avatar
Petr Štětka committed
14

15
        public Process process { get; private set; }
Petr Štětka's avatar
Petr Štětka committed
16
17
18
        public bool showing_details { get; private set; }
        public bool max_usage { get; private set; }

Petr Štětka's avatar
Petr Štětka committed
19
        public ProcessRow(Process process, ProcessListBoxType type, bool opened = false)
Petr Štětka's avatar
Petr Štětka committed
20
        {
Petr Štětka's avatar
Petr Štětka committed
21
            this.type = type;
22
            showing_details = opened;
23
24
25
            if(apps_info == null)
                apps_info = AppInfo.get_all(); //Because it takes too long
            this.process = process;
Petr Štětka's avatar
Petr Štětka committed
26

27
28
29
30
            var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
            box.margin = 0;
			var row_box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
			row_box.margin = 10;
Petr Štětka's avatar
Petr Štětka committed
31
        	load_label = new Gtk.Label(null);
Petr Štětka's avatar
Petr Štětka committed
32
33
        	load_label.ellipsize = Pango.EllipsizeMode.END;
        	load_label.max_width_chars = 30;
Petr Štětka's avatar
Petr Štětka committed
34

35
36
37
38
39
40
41
            Gtk.Image icon;
            load_icon_and_name(out icon, out display_name);
            var title_label = new Gtk.Label(display_name);
            row_box.pack_start(icon, false, false, 0);
            row_box.pack_start(title_label, false, true, 5);
            row_box.pack_end(load_label, false, true, 10);
            box.pack_start(row_box, false, true, 0);
Petr Štětka's avatar
Petr Štětka committed
42

43
            update();
44

45
46
            if(process.sub_processes != null)
            {
Petr Štětka's avatar
Petr Štětka committed
47
                sub_process_list_box = new SubProcessListBox(process, type);
48
49
50
                revealer = new Gtk.Revealer();
                revealer.add(sub_process_list_box);
                box.pack_end(revealer, false, true, 0);
Petr Štětka's avatar
Petr Štětka committed
51

52
53
54
55
56
                if(opened)
                    show_details();
            }
            this.add(box);
            show_all();
Petr Štětka's avatar
Petr Štětka committed
57

58
59
60
            if(opened && process.sub_processes != null)
                show_details();
        }
Petr Štětka's avatar
Petr Štětka committed
61

62
        private void load_icon_and_name(out Gtk.Image icon, out string display_name)
63
        {
Petr Štětka's avatar
Petr Štětka committed
64
            icon = null;
65
66
67
68
69
70
            AppInfo app_info = null;
        	foreach (AppInfo info in apps_info)
        	{
        	    string commandline = info.get_commandline();
        	    for (int i = 0; i < commandline.length; i++)
                {
71
                    if(commandline[i] == ' ' && commandline[i] == '%')
72
73
                        commandline = commandline.substring(0, i);
                }
Petr Štětka's avatar
Petr Štětka committed
74

75
                commandline = Path.get_basename(commandline);
76
77
                string process_full_cmd = process.cmdline + " " + process.cmdline_parameter;
        	    if(commandline == process_full_cmd)
78
        	        app_info = info;
Petr Štětka's avatar
Petr Štětka committed
79
80
        	    else if(commandline.contains("google-" + process.cmdline + "-")) //Fix for Google Chrome naming
                    app_info = info;
81
82
83
84
85
86
87
88
89
90
91

        	    if(app_info == null)
                {
                    commandline = info.get_commandline();
                    for (int i = 0; i < commandline.length; i++)
                    {
                        if(commandline[i] == ' ')
                            commandline = commandline.substring(0, i);
                    }

                    if(info.get_commandline().has_prefix(commandline + " " + commandline + "://")) //Fix for Steam naming
Petr Štětka's avatar
Petr Štětka committed
92
                        commandline = info.get_commandline();
93
94
95
96
97

                    commandline = Path.get_basename(commandline);
                    if(commandline == process.cmdline)
                        app_info = info;
                }
98
99
100
101
102
        	}

            if(app_info != null)
            {
                display_name = app_info.get_display_name();
103

Petr Štětka's avatar
Petr Štětka committed
104
        	    if(app_info.get_icon() != null)
105
106
107
108
109
                {
                    var icon_theme = new Gtk.IconTheme();
                    var icon_info = icon_theme.lookup_by_gicon_for_scale(app_info.get_icon(), 24, 1, Gtk.IconLookupFlags.FORCE_SIZE);
                    if(icon_info != null)
                    {
Petr Štětka's avatar
Petr Štětka committed
110
111
112
113
114
115
116
117
118
                        try
                        {
                            var pixbuf = icon_info.load_icon();
                            icon = new Gtk.Image.from_pixbuf(pixbuf);
                        }
                        catch(Error e) {
                            GLib.stderr.printf ("Could not load icon for application %s: %s\n", display_name, e.message);
                        }

119
120
                    }
                }
121
122
123
        	}
        	else
        	{
124
        	    display_name = process.cmdline;
125
        	}
126

Petr Štětka's avatar
Petr Štětka committed
127
        	if(icon == null)
128
129
130
131
132
133
        	{
        	    icon = new Gtk.Image.from_icon_name("system-run-symbolic", Gtk.IconSize.BUTTON);
        	    icon.width_request = 24;
        	    icon.height_request = 24;
        	}

134
135
136
137
138
        	icon.margin_left = 10;
        	icon.margin_right = 10;

        }

Petr Štětka's avatar
Petr Štětka committed
139
140
        private void update()
        {
Petr Štětka's avatar
Petr Štětka committed
141
142
143
144
            CompareFunc<int> sort = (a, b) => {
                return (int) (a < b) - (int) (a > b);
            };

Petr Štětka's avatar
Petr Štětka committed
145
            switch(type)
Petr Štětka's avatar
Petr Štětka committed
146
            {
Petr Štětka's avatar
Petr Štětka committed
147
148
149
                case ProcessListBoxType.PROCESSOR:
                    if(process.sub_processes != null)
                    {
Petr Štětka's avatar
Petr Štětka committed
150
151
                        string values_string = "";
                        var values = new GLib.List<int>();
Petr Štětka's avatar
Petr Štětka committed
152
                        foreach(Process sub_process in process.sub_processes.get_values())
Petr Štětka's avatar
Petr Štětka committed
153
154
155
156
                            values.insert_sorted((int) sub_process.cpu_load, sort);

                        foreach(int value in values)
                            values_string += "   " + value.to_string() + " %";
Petr Štětka's avatar
Petr Štětka committed
157

Petr Štětka's avatar
Petr Štětka committed
158
                        load_label.set_label(values_string);
Petr Štětka's avatar
Petr Štětka committed
159
160
161
                    }
                    else
                        load_label.set_label(((int) process.cpu_load).to_string() + " %");
Petr Štětka's avatar
Petr Štětka committed
162

Petr Štětka's avatar
Petr Štětka committed
163
164
165
166
167
168
169
170
                    if(process.cpu_load >= 90)
                        max_usage = true;
                    else
                        max_usage = false;
                    break;
                case ProcessListBoxType.MEMORY:
                    if(process.sub_processes != null)
                    {
Petr Štětka's avatar
Petr Štětka committed
171
                        string values_string = "";
172
                        var values = new GLib.List<int>();
Petr Štětka's avatar
Petr Štětka committed
173
                        foreach(Process sub_process in process.sub_processes.get_values())
Petr Štětka's avatar
Petr Štětka committed
174
175
176
                            values.insert_sorted((int) sub_process.mem_usage, sort);

                         foreach(int value in values)
177
                            values_string += "   " + ((int) (value/1000000)).to_string() + " MB";
Petr Štětka's avatar
Petr Štětka committed
178

Petr Štětka's avatar
Petr Štětka committed
179
                        load_label.set_label(values_string);
Petr Štětka's avatar
Petr Štětka committed
180
181
                    }
                    else
182
                        load_label.set_label(((int) process.mem_usage/1000000).to_string() + " MB");
Petr Štětka's avatar
Petr Štětka committed
183
184
185
186
187
188

                    if(process.mem_usage_percentages >= 90)
                        max_usage = true;
                    else
                        max_usage = false;
                    break;
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
                case ProcessListBoxType.NETWORK:
                    if(process.sub_processes != null)
                    {
                        string values_string = "";
                        var values = new GLib.List<int>();
                        foreach(Process sub_process in process.sub_processes.get_values())
                            values.insert_sorted((int) sub_process.net_all, sort);

                         foreach(int value in values)
                            values_string += "   " + value.to_string() + " B";

                        load_label.set_label(values_string);
                    }
                    else
                    {
                        load_label.set_label(((int) process.net_all).to_string() + " B");
                    }
                    break;
Petr Štětka's avatar
Petr Štětka committed
207
            }
Petr Štětka's avatar
Petr Štětka committed
208
209

            set_styles();
Petr Štětka's avatar
Petr Štětka committed
210
211
212
213
214
215
216
        }

        private void hide_details()
        {
            showing_details = false;
            revealer.set_reveal_child(false);
            load_label.visible = true;
217
            get_style_context().remove_class("opened");
Petr Štětka's avatar
Petr Štětka committed
218
219
220
221
222
223
224
        }

        private void show_details()
        {
            showing_details = true;
            revealer.set_reveal_child(true);
            load_label.visible = false;
225
            get_style_context().add_class("opened");
Petr Štětka's avatar
Petr Štětka committed
226
227
        }

Petr Štětka's avatar
Petr Štětka committed
228
        public new void activate()
Petr Štětka's avatar
Petr Štětka committed
229
        {
230
231
232
233
234
235
            if(process.sub_processes != null)
            {
                if(showing_details)
                    hide_details();
                else
                    show_details();
236
237

                set_styles();
238
            }
Petr Štětka's avatar
Petr Štětka committed
239
            else
240
241
            {
                var dialog = new ProcessDialog(process.pid, display_name);
Petr Štětka's avatar
Petr Štětka committed
242
                dialog.show_all();
243
            }
Petr Štětka's avatar
Petr Štětka committed
244
        }
245
246
247
248
249
250
251
252

        private void set_styles()
        {
            if(max_usage == true && showing_details == false)
                get_style_context().add_class("max");
            else
                get_style_context().remove_class("max");
        }
Petr Štětka's avatar
Petr Štětka committed
253
254
    }
}