From 83bf4bf616c20db08906777f1c8a22616dad7342 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Wed, 11 Feb 2026 18:28:28 +0100 Subject: [PATCH 01/28] [wip] gtk4-treeview --- src/Models/TreeViewModel.vala | 62 +++++++++++-------- .../ProcessTreeView/ProcessTreeView.vala | 31 ++++++++++ src/Views/ProcessView/ProcessView.vala | 18 +++--- src/meson.build | 3 +- 4 files changed, 78 insertions(+), 36 deletions(-) create mode 100644 src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala diff --git a/src/Models/TreeViewModel.vala b/src/Models/TreeViewModel.vala index aecb1c760..59e55f6fd 100644 --- a/src/Models/TreeViewModel.vala +++ b/src/Models/TreeViewModel.vala @@ -12,7 +12,7 @@ public enum Monitor.Column { CMD } -public class Monitor.TreeViewModel : Gtk.TreeStore { +public class Monitor.TreeViewModel : GLib.ListModel, GLib.Object { public ProcessManager process_manager; private Gee.Map process_rows; public signal void added_first_row (); @@ -20,14 +20,14 @@ public class Monitor.TreeViewModel : Gtk.TreeStore { construct { process_rows = new Gee.HashMap (); - set_column_types (new Type[] { - typeof (string), - typeof (string), - typeof (double), - typeof (int64), - typeof (int), - typeof (string), - }); + // set_column_types (new Type[] { + // typeof (string), + // typeof (string), + // typeof (double), + // typeof (int64), + // typeof (int), + // typeof (string), + // }); process_manager = ProcessManager.get_default (); process_manager.process_added.connect ((process) => add_process (process)); @@ -49,24 +49,24 @@ public class Monitor.TreeViewModel : Gtk.TreeStore { if (process != null && !process_rows.has_key (process.stat.pid)) { debug ("Add process %d Parent PID: %d", process.stat.pid, process.stat.ppid); // add the process to the model - Gtk.TreeIter iter; - append (out iter, null); // null means top-level + // Gtk.TreeIter iter; + // append (out iter, null); // null means top-level // donno what is going on, but maybe just use a string instead of Icon ?? // coz it lagz // string icon_name = process.icon.to_string (); - set (iter, - Column.NAME, process.application_name, - Column.ICON, process.icon.to_string (), - Column.PID, process.stat.pid, - Column.CMD, process.command, - -1); + // set (iter, + // Column.NAME, process.application_name, + // Column.ICON, process.icon.to_string (), + // Column.PID, process.stat.pid, + // Column.CMD, process.command, + // -1); if (process_rows.size < 1) { added_first_row (); } // add the process to our cache of process_rows - process_rows.set (process.stat.pid, iter); + // process_rows.set (process.stat.pid, iter); return true; } return false; @@ -75,11 +75,11 @@ public class Monitor.TreeViewModel : Gtk.TreeStore { private void update_model () { foreach (int pid in process_rows.keys) { Process process = process_manager.get_process (pid); - Gtk.TreeIter iter = process_rows[pid]; - set (iter, - Column.CPU, process.cpu_percentage, - Column.MEMORY, process.mem_usage, - -1); + // Gtk.TreeIter iter = process_rows[pid]; + // set (iter, + // Column.CPU, process.cpu_percentage, + // Column.MEMORY, process.mem_usage, + // -1); } } @@ -87,8 +87,8 @@ public class Monitor.TreeViewModel : Gtk.TreeStore { debug ("remove process %d from model".printf (pid)); // if process rows has pid if (process_rows.has_key (pid)) { - var cached_iter = process_rows.get (pid); - remove (ref cached_iter); + // var cached_iter = process_rows.get (pid); + // remove (ref cached_iter); process_rows.unset (pid); } } @@ -109,4 +109,16 @@ public class Monitor.TreeViewModel : Gtk.TreeStore { } } + public uint get_n_items() { + return process_manager.get_process_list ().size; + } + + public GLib.Type get_item_type() { + return typeof (Process); + } + + public GLib.Object? get_item (uint position) { + return null; + } + } diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala new file mode 100644 index 000000000..82a488cb9 --- /dev/null +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -0,0 +1,31 @@ + +public class Monitor.ProcessTreeView : Granite.Bin { + private Gtk.ColumnView treeview; + + // private new TreeViewModel model; + public ProcessTreeView(TreeViewModel model) { + // Constructor implementation + + // Set up the column view + var m_model = (new Gtk.SingleSelection (model)); + + treeview = new Gtk.ColumnView (m_model) { + hexpand = true, + vexpand = true, + }; + } + + public void collapse_all() { + // Method implementation + } + + public void focus_on_child_row() { + // Method implementation + } + + public void focus_on_first_row () { + // Method implementation + } + + +} \ No newline at end of file diff --git a/src/Views/ProcessView/ProcessView.vala b/src/Views/ProcessView/ProcessView.vala index 0b7abda9d..60aec80bc 100644 --- a/src/Views/ProcessView/ProcessView.vala +++ b/src/Views/ProcessView/ProcessView.vala @@ -6,8 +6,7 @@ public class Monitor.ProcessView : Granite.Bin { public string needle = ""; - public CPUProcessTreeView process_tree_view { get; private set; } - + public ProcessTreeView process_tree_view { get; private set; } private ProcessInfoView process_info_view; private TreeViewModel treeview_model; @@ -17,14 +16,13 @@ public class Monitor.ProcessView : Granite.Bin { construct { treeview_model = new TreeViewModel (); - var filter_model = new Gtk.TreeModelFilter (treeview_model, null); - filter_model.set_visible_func (filter_func); + // var filter_model = new Gtk.FilterListModel (treeview_model, filter_func); - var sort_model = new Gtk.TreeModelSort.with_model (filter_model); + // var sort_model = new Gtk.TreeModelSort.with_model (filter_model); //SortListModel (filter_model); - process_tree_view = new CPUProcessTreeView (treeview_model); - process_tree_view.process_selected.connect ((process) => on_process_selected (process)); - process_tree_view.set_model (sort_model); + process_tree_view = new ProcessTreeView (treeview_model); + // process_tree_view.process_selected.connect ((process) => on_process_selected (process)); + // process_tree_view.set_model (sort_model); var process_tree_view_scrolled = new Gtk.ScrolledWindow () { child = process_tree_view @@ -49,7 +47,7 @@ public class Monitor.ProcessView : Granite.Bin { child = paned; - notify["needle"].connect (filter_model.refilter); + // notify["needle"].connect (filter_model.refilter); kill_action = new SimpleAction ("kill", null); kill_action.activate.connect (action_kill); @@ -189,7 +187,7 @@ public class Monitor.ProcessView : Granite.Bin { } if (child_found && needle.length > 0) { - process_tree_view.expand_all (); + // process_tree_view.expand_all (); } return found || child_found; diff --git a/src/meson.build b/src/meson.build index 41ff3c6cb..e413854b5 100644 --- a/src/meson.build +++ b/src/meson.build @@ -7,7 +7,8 @@ source_app_files = [ # Views 'Views/ProcessView/ProcessView.vala', 'Views/ProcessView/ProcessInfoView/ProcessInfoView.vala', - 'Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala', + # 'Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala', + 'Views/ProcessView/ProcessTreeView/ProcessTreeView.vala', 'Views/PreferencesView.vala', From 35e7641324293cab9f4d4576ea19f43661ef380c Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Fri, 20 Feb 2026 22:40:14 +0100 Subject: [PATCH 02/28] [wip] add signal list factory --- src/Models/TreeViewModel.vala | 50 +++++++++---- .../ProcessTreeView/ProcessTreeView.vala | 74 ++++++++++++++++--- 2 files changed, 97 insertions(+), 27 deletions(-) diff --git a/src/Models/TreeViewModel.vala b/src/Models/TreeViewModel.vala index 59e55f6fd..04dc53bbb 100644 --- a/src/Models/TreeViewModel.vala +++ b/src/Models/TreeViewModel.vala @@ -12,13 +12,22 @@ public enum Monitor.Column { CMD } -public class Monitor.TreeViewModel : GLib.ListModel, GLib.Object { +public class Monitor.ProcessRow : GLib.Object { + public string icon { get; set; } + public string name { get; set; } + public double cpu { get; set; } + public uint64 memory { get; set; } + public int pid { get; set; } + public string cmd { get; set; } +} + +public class Monitor.TreeViewModel : GLib.ListStore { public ProcessManager process_manager; - private Gee.Map process_rows; + private Gee.Map process_rows; public signal void added_first_row (); construct { - process_rows = new Gee.HashMap (); + process_rows = new Gee.HashMap (); // set_column_types (new Type[] { // typeof (string), @@ -51,6 +60,15 @@ public class Monitor.TreeViewModel : GLib.ListModel, GLib.Object { // add the process to the model // Gtk.TreeIter iter; // append (out iter, null); // null means top-level + var row = new ProcessRow (); + row.icon = process.icon.to_string (); + row.name = process.application_name; + row.cpu = process.cpu_percentage; + row.memory = process.mem_usage; + row.pid = process.stat.pid; + row.cmd = process.command; + + append (row); // donno what is going on, but maybe just use a string instead of Icon ?? // coz it lagz @@ -66,7 +84,7 @@ public class Monitor.TreeViewModel : GLib.ListModel, GLib.Object { added_first_row (); } // add the process to our cache of process_rows - // process_rows.set (process.stat.pid, iter); + process_rows.set (process.stat.pid, row); return true; } return false; @@ -75,6 +93,10 @@ public class Monitor.TreeViewModel : GLib.ListModel, GLib.Object { private void update_model () { foreach (int pid in process_rows.keys) { Process process = process_manager.get_process (pid); + var process_row = process_rows.get (pid); + process_row.cpu = process.cpu_percentage; + process_row.memory = process.mem_usage; + // Gtk.TreeIter iter = process_rows[pid]; // set (iter, // Column.CPU, process.cpu_percentage, @@ -87,8 +109,6 @@ public class Monitor.TreeViewModel : GLib.ListModel, GLib.Object { debug ("remove process %d from model".printf (pid)); // if process rows has pid if (process_rows.has_key (pid)) { - // var cached_iter = process_rows.get (pid); - // remove (ref cached_iter); process_rows.unset (pid); } } @@ -109,16 +129,16 @@ public class Monitor.TreeViewModel : GLib.ListModel, GLib.Object { } } - public uint get_n_items() { - return process_manager.get_process_list ().size; - } + // public uint get_n_items() { + // return process_manager.get_process_list ().size; + // } - public GLib.Type get_item_type() { - return typeof (Process); - } + // public GLib.Type get_item_type() { + // return typeof (Process); + // } - public GLib.Object? get_item (uint position) { - return null; - } + // public GLib.Object? get_item (uint position) { + // return process_rows.get ((int) position); + // } } diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index 82a488cb9..c1918b9b3 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -1,25 +1,76 @@ public class Monitor.ProcessTreeView : Granite.Bin { - private Gtk.ColumnView treeview; + private Gtk.ColumnView list; - // private new TreeViewModel model; - public ProcessTreeView(TreeViewModel model) { + // private new TreeViewModel model; + public ProcessTreeView (TreeViewModel model) { + + // model = new Gtk.TreeListModel(); // Constructor implementation - // Set up the column view - var m_model = (new Gtk.SingleSelection (model)); + var mmodel = new GLib.ListStore (typeof (ProcessRow)); + + var sorted_sensors = new Gtk.SortListModel (mmodel, null); + + mmodel.append (new ProcessRow () { name = "test" }); + mmodel.append (new ProcessRow () { name = "test2" }); - treeview = new Gtk.ColumnView (m_model) { - hexpand = true, - vexpand = true, + list = new Gtk.ColumnView (new Gtk.NoSelection (sorted_sensors)) { + name = "sensors", + reorderable = false, + hexpand = false, + vexpand = true }; + + var row_factory = new Gtk.SignalListItemFactory (); + + row_factory.setup.connect ((factory, obj) => { + var row = obj as Gtk.ColumnViewRow; + row.focusable = false; + row.activatable = false; + }); + + list.row_factory = row_factory; + + child = list; + + + var proc_name_factory = new Gtk.SignalListItemFactory (); + proc_name_factory.setup.connect ((factory, obj) => { + var cell = obj as Gtk.ColumnViewCell; + cell.child = new Gtk.Label ("") { + hexpand = true, + halign = Gtk.Align.START + }; + }); + + proc_name_factory.bind.connect((factory, obj) => { + var cell = obj as Gtk.ColumnViewCell; + var label = cell.child as Gtk.Label; + var item = cell.item as ProcessRow; + debug (item.name); + label.set_text (item.name); + }); + + var proc_name_column = new Gtk.ColumnViewColumn (_("Process Name"), proc_name_factory); + list.append_column (proc_name_column); + // list.append_column (new Gtk.ColumnViewColumn ("Chip", chipname_factory) { + // sorter = str_sorter ("chip_label") + // }); + // list.append_column (new Gtk.ColumnViewColumn ("Feature", feature_factory) { + // sorter = str_sorter ("feature_label") + // }); + // list.append_column (new Gtk.ColumnViewColumn ("Value", value_factory) { + // sorter = num_sorter ("value"), expand = true + // }); + // list.append_column (new Gtk.ColumnViewColumn ("", remove_factory)); } - public void collapse_all() { + public void collapse_all () { // Method implementation } - public void focus_on_child_row() { + public void focus_on_child_row () { // Method implementation } @@ -27,5 +78,4 @@ public class Monitor.ProcessTreeView : Granite.Bin { // Method implementation } - -} \ No newline at end of file +} From 236bc009a2cab5a761dd21058c75e9c670432808 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Sat, 21 Feb 2026 21:40:34 +0100 Subject: [PATCH 03/28] ProcessTreeView: Show process name and add sorting --- src/Models/TreeViewModel.vala | 29 ++++++++++-------- .../ProcessTreeView/ProcessTreeView.vala | 30 ++++++++++++------- src/Views/ProcessView/ProcessView.vala | 5 +--- 3 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/Models/TreeViewModel.vala b/src/Models/TreeViewModel.vala index 04dc53bbb..34dd56a0a 100644 --- a/src/Models/TreeViewModel.vala +++ b/src/Models/TreeViewModel.vala @@ -12,7 +12,7 @@ public enum Monitor.Column { CMD } -public class Monitor.ProcessRow : GLib.Object { +public class Monitor.ProcessRowData : GLib.Object { public string icon { get; set; } public string name { get; set; } public double cpu { get; set; } @@ -21,13 +21,15 @@ public class Monitor.ProcessRow : GLib.Object { public string cmd { get; set; } } -public class Monitor.TreeViewModel : GLib.ListStore { +public class Monitor.TreeViewModel : GLib.Object { public ProcessManager process_manager; - private Gee.Map process_rows; + public GLib.ListStore list_store; + private Gee.Map process_rows; public signal void added_first_row (); construct { - process_rows = new Gee.HashMap (); + process_rows = new Gee.HashMap (); + list_store = new GLib.ListStore (typeof (ProcessRowData)); // set_column_types (new Type[] { // typeof (string), @@ -60,15 +62,16 @@ public class Monitor.TreeViewModel : GLib.ListStore { // add the process to the model // Gtk.TreeIter iter; // append (out iter, null); // null means top-level - var row = new ProcessRow (); - row.icon = process.icon.to_string (); - row.name = process.application_name; - row.cpu = process.cpu_percentage; - row.memory = process.mem_usage; - row.pid = process.stat.pid; - row.cmd = process.command; - - append (row); + var row = new ProcessRowData () { + icon = process.icon.to_string (), + name = process.application_name, + cpu = process.cpu_percentage, + memory = process.mem_usage, + pid = process.stat.pid, + cmd = process.command + }; + + list_store.append (row); // donno what is going on, but maybe just use a string instead of Icon ?? // coz it lagz diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index c1918b9b3..c8c2930c7 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -8,15 +8,16 @@ public class Monitor.ProcessTreeView : Granite.Bin { // model = new Gtk.TreeListModel(); // Constructor implementation - var mmodel = new GLib.ListStore (typeof (ProcessRow)); - var sorted_sensors = new Gtk.SortListModel (mmodel, null); + var sorted_list = new Gtk.SortListModel (model.list_store, null); + + var selection_model = new Gtk.SingleSelection (sorted_list) { + autoselect = true + }; - mmodel.append (new ProcessRow () { name = "test" }); - mmodel.append (new ProcessRow () { name = "test2" }); - list = new Gtk.ColumnView (new Gtk.NoSelection (sorted_sensors)) { - name = "sensors", + list = new Gtk.ColumnView (selection_model) { + name = "monitor-process-column-view", reorderable = false, hexpand = false, vexpand = true @@ -32,13 +33,15 @@ public class Monitor.ProcessTreeView : Granite.Bin { list.row_factory = row_factory; - child = list; + child = new Gtk.ScrolledWindow () { + child = list + }; var proc_name_factory = new Gtk.SignalListItemFactory (); proc_name_factory.setup.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; - cell.child = new Gtk.Label ("") { + cell.child = new Gtk.Label ("-") { hexpand = true, halign = Gtk.Align.START }; @@ -47,13 +50,20 @@ public class Monitor.ProcessTreeView : Granite.Bin { proc_name_factory.bind.connect((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; var label = cell.child as Gtk.Label; - var item = cell.item as ProcessRow; + var item = cell.item as ProcessRowData; debug (item.name); label.set_text (item.name); }); - var proc_name_column = new Gtk.ColumnViewColumn (_("Process Name"), proc_name_factory); + Gee.MapFunc str_sorter = (property_name) => + new Gtk.StringSorter(new Gtk.PropertyExpression(typeof (ProcessRowData), null, property_name)); + + var proc_name_column = new Gtk.ColumnViewColumn (_("Process Name"), proc_name_factory) { + sorter = str_sorter("name") + }; list.append_column (proc_name_column); + sorted_list.sorter = list.sorter; + // list.append_column (new Gtk.ColumnViewColumn ("Chip", chipname_factory) { // sorter = str_sorter ("chip_label") // }); diff --git a/src/Views/ProcessView/ProcessView.vala b/src/Views/ProcessView/ProcessView.vala index 60aec80bc..382b0786a 100644 --- a/src/Views/ProcessView/ProcessView.vala +++ b/src/Views/ProcessView/ProcessView.vala @@ -24,9 +24,6 @@ public class Monitor.ProcessView : Granite.Bin { // process_tree_view.process_selected.connect ((process) => on_process_selected (process)); // process_tree_view.set_model (sort_model); - var process_tree_view_scrolled = new Gtk.ScrolledWindow () { - child = process_tree_view - }; process_info_view = new ProcessInfoView () { // This might be useless since first process is selected @@ -37,7 +34,7 @@ public class Monitor.ProcessView : Granite.Bin { }; var paned = new Gtk.Paned (HORIZONTAL) { - start_child = process_tree_view_scrolled, + start_child = process_tree_view, end_child = process_info_view, shrink_end_child = false, resize_end_child = false, From 21f543285ed9cbe1580cb1cc1d6aeb79be5962d8 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Sun, 22 Feb 2026 00:03:36 +0100 Subject: [PATCH 04/28] ProcessTreeView: Reintroduce cpu and memory columns --- src/Models/TreeViewModel.vala | 6 ++ .../ProcessTreeView/ProcessTreeView.vala | 96 ++++++++++++++----- 2 files changed, 77 insertions(+), 25 deletions(-) diff --git a/src/Models/TreeViewModel.vala b/src/Models/TreeViewModel.vala index 34dd56a0a..6711b8489 100644 --- a/src/Models/TreeViewModel.vala +++ b/src/Models/TreeViewModel.vala @@ -27,6 +27,12 @@ public class Monitor.TreeViewModel : GLib.Object { private Gee.Map process_rows; public signal void added_first_row (); + public Gee.MapFunc str_sorter = (property_name) => + new Gtk.StringSorter(new Gtk.PropertyExpression(typeof (ProcessRowData), null, property_name)); + + public Gee.MapFunc num_sorter = (property_name) => + new Gtk.NumericSorter(new Gtk.PropertyExpression(typeof (ProcessRowData), null, property_name)); + construct { process_rows = new Gee.HashMap (); list_store = new GLib.ListStore (typeof (ProcessRowData)); diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index c8c2930c7..a26d879af 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -5,7 +5,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { // private new TreeViewModel model; public ProcessTreeView (TreeViewModel model) { - // model = new Gtk.TreeListModel(); + // model = new Gtk.TreeListModel(); // Constructor implementation @@ -41,39 +41,85 @@ public class Monitor.ProcessTreeView : Granite.Bin { var proc_name_factory = new Gtk.SignalListItemFactory (); proc_name_factory.setup.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; - cell.child = new Gtk.Label ("-") { + cell.child = new Gtk.Label (Utils.NO_DATA) { hexpand = true, halign = Gtk.Align.START }; }); - proc_name_factory.bind.connect((factory, obj) => { - var cell = obj as Gtk.ColumnViewCell; - var label = cell.child as Gtk.Label; - var item = cell.item as ProcessRowData; - debug (item.name); - label.set_text (item.name); - }); - - Gee.MapFunc str_sorter = (property_name) => - new Gtk.StringSorter(new Gtk.PropertyExpression(typeof (ProcessRowData), null, property_name)); + proc_name_factory.bind.connect ((factory, obj) => { + var cell = obj as Gtk.ColumnViewCell; + var label = cell.child as Gtk.Label; + var item = cell.item as ProcessRowData; + label.set_text (item.name); + }); - var proc_name_column = new Gtk.ColumnViewColumn (_("Process Name"), proc_name_factory) { - sorter = str_sorter("name") + var name_column = new Gtk.ColumnViewColumn (_("Process Name"), proc_name_factory) { + sorter = model.str_sorter ("name") }; - list.append_column (proc_name_column); + list.append_column (name_column); sorted_list.sorter = list.sorter; - // list.append_column (new Gtk.ColumnViewColumn ("Chip", chipname_factory) { - // sorter = str_sorter ("chip_label") - // }); - // list.append_column (new Gtk.ColumnViewColumn ("Feature", feature_factory) { - // sorter = str_sorter ("feature_label") - // }); - // list.append_column (new Gtk.ColumnViewColumn ("Value", value_factory) { - // sorter = num_sorter ("value"), expand = true - // }); - // list.append_column (new Gtk.ColumnViewColumn ("", remove_factory)); + var proc_cpu_factory = new Gtk.SignalListItemFactory (); + proc_cpu_factory.setup.connect ((factory, obj) => { + var cell = obj as Gtk.ColumnViewCell; + cell.child = new Gtk.Label (Utils.NO_DATA) { + hexpand = true, + halign = Gtk.Align.START + }; + }); + + proc_cpu_factory.bind.connect ((factory, obj) => { + var cell = obj as Gtk.ColumnViewCell; + var label = cell.child as Gtk.Label; + var item = cell.item as ProcessRowData; + label.set_text ("%.0f%%".printf (item.cpu)); + }); + + var cpu_column = new Gtk.ColumnViewColumn (_("CPU"), proc_cpu_factory) { + sorter = model.num_sorter ("cpu"), + expand = false + }; + list.append_column (cpu_column); + + var proc_mem_factory = new Gtk.SignalListItemFactory (); + proc_mem_factory.setup.connect ((factory, obj) => { + var cell = obj as Gtk.ColumnViewCell; + cell.child = new Gtk.Label (Utils.NO_DATA) { + hexpand = true, + halign = Gtk.Align.START + }; + }); + + proc_mem_factory.bind.connect ((factory, obj) => { + var cell = obj as Gtk.ColumnViewCell; + var label = cell.child as Gtk.Label; + var item = cell.item as ProcessRowData; + + double memory_usage_double = (double) item.memory; + string units = _("KiB"); + + // convert to MiB if needed + if (memory_usage_double > 1024.0) { + memory_usage_double /= 1024.0; + units = _("MiB"); + } + + // convert to GiB if needed + if (memory_usage_double > 1024.0) { + memory_usage_double /= 1024.0; + units = _("GiB"); + } + + label.set_text ("%.1f %s".printf (memory_usage_double, units)); + }); + + var mem_column = new Gtk.ColumnViewColumn (_("Memory"), proc_mem_factory) { + sorter = model.num_sorter ("memory"), + expand = false + }; + list.append_column (mem_column); + } public void collapse_all () { From 98b801f4dd950da879ed5307a095a5ed6c520620 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Mon, 23 Feb 2026 13:34:49 +0100 Subject: [PATCH 05/28] ProcessTreeView: Reintroduce PID column --- .../ProcessTreeView/ProcessTreeView.vala | 46 ++++++++++++++----- src/Views/ProcessView/ProcessView.vala | 2 +- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index a26d879af..8d316768d 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -37,9 +37,13 @@ public class Monitor.ProcessTreeView : Granite.Bin { child = list }; + var name_item_factory = new Gtk.SignalListItemFactory (); + var cpu_item_factory = new Gtk.SignalListItemFactory (); + var memory_item_factory = new Gtk.SignalListItemFactory (); + var pid_item_factory = new Gtk.SignalListItemFactory (); - var proc_name_factory = new Gtk.SignalListItemFactory (); - proc_name_factory.setup.connect ((factory, obj) => { + + name_item_factory.setup.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; cell.child = new Gtk.Label (Utils.NO_DATA) { hexpand = true, @@ -47,21 +51,20 @@ public class Monitor.ProcessTreeView : Granite.Bin { }; }); - proc_name_factory.bind.connect ((factory, obj) => { + name_item_factory.bind.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; var label = cell.child as Gtk.Label; var item = cell.item as ProcessRowData; label.set_text (item.name); }); - var name_column = new Gtk.ColumnViewColumn (_("Process Name"), proc_name_factory) { + var name_column = new Gtk.ColumnViewColumn (_("Process Name"), name_item_factory) { sorter = model.str_sorter ("name") }; list.append_column (name_column); sorted_list.sorter = list.sorter; - var proc_cpu_factory = new Gtk.SignalListItemFactory (); - proc_cpu_factory.setup.connect ((factory, obj) => { + cpu_item_factory.setup.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; cell.child = new Gtk.Label (Utils.NO_DATA) { hexpand = true, @@ -69,21 +72,20 @@ public class Monitor.ProcessTreeView : Granite.Bin { }; }); - proc_cpu_factory.bind.connect ((factory, obj) => { + cpu_item_factory.bind.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; var label = cell.child as Gtk.Label; var item = cell.item as ProcessRowData; label.set_text ("%.0f%%".printf (item.cpu)); }); - var cpu_column = new Gtk.ColumnViewColumn (_("CPU"), proc_cpu_factory) { + var cpu_column = new Gtk.ColumnViewColumn (_("CPU"), cpu_item_factory) { sorter = model.num_sorter ("cpu"), expand = false }; list.append_column (cpu_column); - var proc_mem_factory = new Gtk.SignalListItemFactory (); - proc_mem_factory.setup.connect ((factory, obj) => { + memory_item_factory.setup.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; cell.child = new Gtk.Label (Utils.NO_DATA) { hexpand = true, @@ -91,7 +93,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { }; }); - proc_mem_factory.bind.connect ((factory, obj) => { + memory_item_factory.bind.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; var label = cell.child as Gtk.Label; var item = cell.item as ProcessRowData; @@ -114,12 +116,32 @@ public class Monitor.ProcessTreeView : Granite.Bin { label.set_text ("%.1f %s".printf (memory_usage_double, units)); }); - var mem_column = new Gtk.ColumnViewColumn (_("Memory"), proc_mem_factory) { + var mem_column = new Gtk.ColumnViewColumn (_("Memory"), memory_item_factory) { sorter = model.num_sorter ("memory"), expand = false }; list.append_column (mem_column); + pid_item_factory.setup.connect ((factory, obj) => { + var cell = obj as Gtk.ColumnViewCell; + cell.child = new Gtk.Label (Utils.NO_DATA) { + hexpand = true, + halign = Gtk.Align.START + }; + }); + + pid_item_factory.bind.connect ((factory, obj) => { + var cell = obj as Gtk.ColumnViewCell; + var label = cell.child as Gtk.Label; + var item = cell.item as ProcessRowData; + label.set_text ("%d".printf (item.pid)); + }); + + var pid_column = new Gtk.ColumnViewColumn (_("PID"), pid_item_factory) { + sorter = model.num_sorter ("pid"), + expand = false + }; + list.append_column (pid_column); } public void collapse_all () { diff --git a/src/Views/ProcessView/ProcessView.vala b/src/Views/ProcessView/ProcessView.vala index 382b0786a..16fc5d80b 100644 --- a/src/Views/ProcessView/ProcessView.vala +++ b/src/Views/ProcessView/ProcessView.vala @@ -22,7 +22,7 @@ public class Monitor.ProcessView : Granite.Bin { process_tree_view = new ProcessTreeView (treeview_model); // process_tree_view.process_selected.connect ((process) => on_process_selected (process)); - // process_tree_view.set_model (sort_model); + process_info_view = new ProcessInfoView () { From 780a157e4e2fb1bad4530dee84deb9a9f79eb66e Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Mon, 23 Feb 2026 17:01:49 +0100 Subject: [PATCH 06/28] ProcessTreeView: reintroduce process_selected signal --- .../ProcessTreeView/ProcessTreeView.vala | 19 +++++++++++-------- src/Views/ProcessView/ProcessView.vala | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index 8d316768d..fab2b6ad9 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -2,12 +2,11 @@ public class Monitor.ProcessTreeView : Granite.Bin { private Gtk.ColumnView list; - // private new TreeViewModel model; - public ProcessTreeView (TreeViewModel model) { + public signal void process_selected (Process process); - // model = new Gtk.TreeListModel(); - // Constructor implementation + // private new TreeViewModel model; + public ProcessTreeView (TreeViewModel model) { var sorted_list = new Gtk.SortListModel (model.list_store, null); @@ -15,11 +14,16 @@ public class Monitor.ProcessTreeView : Granite.Bin { autoselect = true }; + selection_model.selection_changed.connect ((position, n_items) => { + var row_data = selection_model.get_selected_item () as ProcessRowData; + Process process = model.process_manager.get_process (row_data.pid); + process_selected (process); + }); list = new Gtk.ColumnView (selection_model) { name = "monitor-process-column-view", reorderable = false, - hexpand = false, + hexpand = true, vexpand = true }; @@ -27,8 +31,6 @@ public class Monitor.ProcessTreeView : Granite.Bin { row_factory.setup.connect ((factory, obj) => { var row = obj as Gtk.ColumnViewRow; - row.focusable = false; - row.activatable = false; }); list.row_factory = row_factory; @@ -42,7 +44,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { var memory_item_factory = new Gtk.SignalListItemFactory (); var pid_item_factory = new Gtk.SignalListItemFactory (); - + name_item_factory.setup.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; cell.child = new Gtk.Label (Utils.NO_DATA) { @@ -142,6 +144,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { expand = false }; list.append_column (pid_column); + } public void collapse_all () { diff --git a/src/Views/ProcessView/ProcessView.vala b/src/Views/ProcessView/ProcessView.vala index 16fc5d80b..4e42badd7 100644 --- a/src/Views/ProcessView/ProcessView.vala +++ b/src/Views/ProcessView/ProcessView.vala @@ -21,7 +21,7 @@ public class Monitor.ProcessView : Granite.Bin { // var sort_model = new Gtk.TreeModelSort.with_model (filter_model); //SortListModel (filter_model); process_tree_view = new ProcessTreeView (treeview_model); - // process_tree_view.process_selected.connect ((process) => on_process_selected (process)); + process_tree_view.process_selected.connect ((process) => on_process_selected (process)); From 1bd04dd7a69cefd2d84cb35f6aebe35d4f3e0e59 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Tue, 24 Feb 2026 17:11:29 +0100 Subject: [PATCH 07/28] ProcessTreeView: use selected-item property to watch --- src/Models/TreeViewModel.vala | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Models/TreeViewModel.vala b/src/Models/TreeViewModel.vala index 6711b8489..c50e8c0eb 100644 --- a/src/Models/TreeViewModel.vala +++ b/src/Models/TreeViewModel.vala @@ -138,16 +138,4 @@ public class Monitor.TreeViewModel : GLib.Object { } } - // public uint get_n_items() { - // return process_manager.get_process_list ().size; - // } - - // public GLib.Type get_item_type() { - // return typeof (Process); - // } - - // public GLib.Object? get_item (uint position) { - // return process_rows.get ((int) position); - // } - } From a05b0bd104dbe0b10b891ef71b14d7d0ac646eea Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Wed, 25 Feb 2026 17:03:14 +0100 Subject: [PATCH 08/28] ProcessTreeView: update selection model connection and expand Proces Name column --- src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index fab2b6ad9..f822ca785 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -14,11 +14,11 @@ public class Monitor.ProcessTreeView : Granite.Bin { autoselect = true }; - selection_model.selection_changed.connect ((position, n_items) => { + selection_model.notify["selected-item"].connect ((sender, property) => { var row_data = selection_model.get_selected_item () as ProcessRowData; Process process = model.process_manager.get_process (row_data.pid); process_selected (process); - }); + }); list = new Gtk.ColumnView (selection_model) { name = "monitor-process-column-view", @@ -61,7 +61,8 @@ public class Monitor.ProcessTreeView : Granite.Bin { }); var name_column = new Gtk.ColumnViewColumn (_("Process Name"), name_item_factory) { - sorter = model.str_sorter ("name") + sorter = model.str_sorter ("name"), + expand = true }; list.append_column (name_column); sorted_list.sorter = list.sorter; From ade573ea943c58a2689fc9e25ad55c9085969421 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Thu, 26 Feb 2026 20:09:14 +0100 Subject: [PATCH 09/28] TreeViewModel: update values in the store --- src/Models/TreeViewModel.vala | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/Models/TreeViewModel.vala b/src/Models/TreeViewModel.vala index c50e8c0eb..3a17e36a8 100644 --- a/src/Models/TreeViewModel.vala +++ b/src/Models/TreeViewModel.vala @@ -79,16 +79,6 @@ public class Monitor.TreeViewModel : GLib.Object { list_store.append (row); - // donno what is going on, but maybe just use a string instead of Icon ?? - // coz it lagz - // string icon_name = process.icon.to_string (); - - // set (iter, - // Column.NAME, process.application_name, - // Column.ICON, process.icon.to_string (), - // Column.PID, process.stat.pid, - // Column.CMD, process.command, - // -1); if (process_rows.size < 1) { added_first_row (); } @@ -103,14 +93,16 @@ public class Monitor.TreeViewModel : GLib.Object { foreach (int pid in process_rows.keys) { Process process = process_manager.get_process (pid); var process_row = process_rows.get (pid); - process_row.cpu = process.cpu_percentage; - process_row.memory = process.mem_usage; - - // Gtk.TreeIter iter = process_rows[pid]; - // set (iter, - // Column.CPU, process.cpu_percentage, - // Column.MEMORY, process.mem_usage, - // -1); + + uint pos; + if (list_store.find (process_row, out pos)) { + var item = list_store.get_item (pos) as ProcessRowData; + item.cpu = process.cpu_percentage; + item.memory = process.mem_usage; + list_store.items_changed (pos, 1, 1); + } else { + debug ("Failed to find process row for pid %d", pid); + } } } @@ -118,6 +110,11 @@ public class Monitor.TreeViewModel : GLib.Object { debug ("remove process %d from model".printf (pid)); // if process rows has pid if (process_rows.has_key (pid)) { + uint pos; + var process_row = process_rows.get (pid); + if (list_store.find (process_row, out pos)) { + list_store.remove (pos); + } process_rows.unset (pid); } } From ee8b5e1e257e1d961a6a279b52202fbfeb566f99 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Thu, 26 Feb 2026 21:24:56 +0100 Subject: [PATCH 10/28] ProcessTreeView: introduce initial filtering by name --- src/MainWindow.vala | 2 +- .../ProcessTreeView/ProcessTreeView.vala | 13 ++- src/Views/ProcessView/ProcessView.vala | 79 +++++++++---------- 3 files changed, 51 insertions(+), 43 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index f87d7cf52..ffb623598 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -106,7 +106,7 @@ public class Monitor.MainWindow : Gtk.ApplicationWindow { process_view.process_tree_view.collapse_all (); } - process_view.needle = search_entry.text; + process_view.process_tree_view.filter.search = search_entry.text; // focus on child row to avoid the app crashes by clicking "Kill/End Process" buttons in headerbar process_view.process_tree_view.focus_on_child_row (); diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index f822ca785..574e9901e 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -4,13 +4,24 @@ public class Monitor.ProcessTreeView : Granite.Bin { public signal void process_selected (Process process); + public Gtk.StringFilter filter; // private new TreeViewModel model; public ProcessTreeView (TreeViewModel model) { var sorted_list = new Gtk.SortListModel (model.list_store, null); - var selection_model = new Gtk.SingleSelection (sorted_list) { + var expression = new Gtk.PropertyExpression (typeof (ProcessRowData), null, "name"); + filter = new Gtk.StringFilter (expression) { + ignore_case = true, + match_mode = SUBSTRING + }; + + + var filter_model = new Gtk.FilterListModel (sorted_list, filter); + + + var selection_model = new Gtk.SingleSelection (filter_model) { autoselect = true }; diff --git a/src/Views/ProcessView/ProcessView.vala b/src/Views/ProcessView/ProcessView.vala index 4e42badd7..6511e04d7 100644 --- a/src/Views/ProcessView/ProcessView.vala +++ b/src/Views/ProcessView/ProcessView.vala @@ -10,16 +10,13 @@ public class Monitor.ProcessView : Granite.Bin { private ProcessInfoView process_info_view; private TreeViewModel treeview_model; + private SimpleAction end_action; private SimpleAction kill_action; construct { treeview_model = new TreeViewModel (); - // var filter_model = new Gtk.FilterListModel (treeview_model, filter_func); - - // var sort_model = new Gtk.TreeModelSort.with_model (filter_model); //SortListModel (filter_model); - process_tree_view = new ProcessTreeView (treeview_model); process_tree_view.process_selected.connect ((process) => on_process_selected (process)); @@ -152,41 +149,41 @@ public class Monitor.ProcessView : Granite.Bin { } - private bool filter_func (Gtk.TreeModel model, Gtk.TreeIter iter) { - string name_haystack; - int pid_haystack; - string cmd_haystack; - bool found = false; - - if (needle.length == 0) { - return true; - } - - model.get (iter, Column.NAME, out name_haystack, -1); - model.get (iter, Column.PID, out pid_haystack, -1); - model.get (iter, Column.CMD, out cmd_haystack, -1); - - // sometimes name_haystack is null - if (name_haystack != null) { - bool name_found = name_haystack.casefold ().contains (needle.casefold ()) || false; - bool pid_found = pid_haystack.to_string ().casefold ().contains (needle.casefold ()) || false; - bool cmd_found = cmd_haystack.casefold ().contains (needle.casefold ()) || false; - found = name_found || pid_found || cmd_found; - } - - Gtk.TreeIter child_iter; - bool child_found = false; - - if (model.iter_children (out child_iter, iter)) { - do { - child_found = filter_func (model, child_iter); - } while (model.iter_next (ref child_iter) && !child_found); - } - - if (child_found && needle.length > 0) { - // process_tree_view.expand_all (); - } - - return found || child_found; - } + // private bool filter_func (Gtk.TreeModel model, Gtk.TreeIter iter) { + // string name_haystack; + // int pid_haystack; + // string cmd_haystack; + // bool found = false; + + // if (needle.length == 0) { + // return true; + // } + + // model.get (iter, Column.NAME, out name_haystack, -1); + // model.get (iter, Column.PID, out pid_haystack, -1); + // model.get (iter, Column.CMD, out cmd_haystack, -1); + + // // sometimes name_haystack is null + // if (name_haystack != null) { + // bool name_found = name_haystack.casefold ().contains (needle.casefold ()) || false; + // bool pid_found = pid_haystack.to_string ().casefold ().contains (needle.casefold ()) || false; + // bool cmd_found = cmd_haystack.casefold ().contains (needle.casefold ()) || false; + // found = name_found || pid_found || cmd_found; + // } + + // Gtk.TreeIter child_iter; + // bool child_found = false; + + // if (model.iter_children (out child_iter, iter)) { + // do { + // child_found = filter_func (model, child_iter); + // } while (model.iter_next (ref child_iter) && !child_found); + // } + + // if (child_found && needle.length > 0) { + // // process_tree_view.expand_all (); + // } + + // return found || child_found; + // } } From 8e6d601f0d3e675f3109a2b1f6595727d3f530c4 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Sat, 28 Feb 2026 18:20:55 +0100 Subject: [PATCH 11/28] ProcessTreeView: process filtering works --- src/MainWindow.vala | 4 ++- .../ProcessTreeView/ProcessTreeView.vala | 31 ++++++++++++++++--- src/Views/ProcessView/ProcessView.vala | 2 -- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index ffb623598..6d27b593c 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -106,7 +106,9 @@ public class Monitor.MainWindow : Gtk.ApplicationWindow { process_view.process_tree_view.collapse_all (); } - process_view.process_tree_view.filter.search = search_entry.text; + process_view.process_tree_view.name_filter.search = search_entry.text; + process_view.process_tree_view.cmd_filter.search = search_entry.text; + process_view.process_tree_view.needle = search_entry.text; // focus on child row to avoid the app crashes by clicking "Kill/End Process" buttons in headerbar process_view.process_tree_view.focus_on_child_row (); diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index 574e9901e..ebceadf99 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -4,21 +4,44 @@ public class Monitor.ProcessTreeView : Granite.Bin { public signal void process_selected (Process process); - public Gtk.StringFilter filter; + public string needle = ""; + public Gtk.StringFilter name_filter; + public Gtk.StringFilter cmd_filter; + public Gtk.CustomFilter pid_filter; // private new TreeViewModel model; public ProcessTreeView (TreeViewModel model) { var sorted_list = new Gtk.SortListModel (model.list_store, null); var expression = new Gtk.PropertyExpression (typeof (ProcessRowData), null, "name"); - filter = new Gtk.StringFilter (expression) { + name_filter = new Gtk.StringFilter (expression) { ignore_case = true, - match_mode = SUBSTRING + match_mode = SUBSTRING, + search = needle }; + cmd_filter = new Gtk.StringFilter (new Gtk.PropertyExpression (typeof (ProcessRowData), null, "cmd")) { + ignore_case = true, + match_mode = SUBSTRING, + search = needle + }; + + + pid_filter = new Gtk.CustomFilter ((obj) => { + var item = (ProcessRowData) obj; + print ("Filtering PID: %d with needle: %s\n".printf (item.pid, needle)); + bool pid_found = item.pid.to_string ().contains (needle.casefold ()) || false; + return pid_found; + }); + + var any_filter = new Gtk.AnyFilter (); + any_filter.append (name_filter); + any_filter.append (cmd_filter); + any_filter.append (pid_filter); + - var filter_model = new Gtk.FilterListModel (sorted_list, filter); + var filter_model = new Gtk.FilterListModel (sorted_list, any_filter); var selection_model = new Gtk.SingleSelection (filter_model) { diff --git a/src/Views/ProcessView/ProcessView.vala b/src/Views/ProcessView/ProcessView.vala index 6511e04d7..b8121cdcc 100644 --- a/src/Views/ProcessView/ProcessView.vala +++ b/src/Views/ProcessView/ProcessView.vala @@ -4,7 +4,6 @@ */ public class Monitor.ProcessView : Granite.Bin { - public string needle = ""; public ProcessTreeView process_tree_view { get; private set; } private ProcessInfoView process_info_view; @@ -41,7 +40,6 @@ public class Monitor.ProcessView : Granite.Bin { child = paned; - // notify["needle"].connect (filter_model.refilter); kill_action = new SimpleAction ("kill", null); kill_action.activate.connect (action_kill); From 9907a2472b0a4b1d6b1ed5e90353861751be21fe Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Wed, 4 Mar 2026 17:01:07 +0100 Subject: [PATCH 12/28] ProcessTreeView: reverse sorting for numeric values; fix process reordering if integer values do not change on the view --- src/Models/TreeViewModel.vala | 12 +++++++----- .../ProcessView/ProcessTreeView/ProcessTreeView.vala | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Models/TreeViewModel.vala b/src/Models/TreeViewModel.vala index 3a17e36a8..bec5cca62 100644 --- a/src/Models/TreeViewModel.vala +++ b/src/Models/TreeViewModel.vala @@ -15,7 +15,7 @@ public enum Monitor.Column { public class Monitor.ProcessRowData : GLib.Object { public string icon { get; set; } public string name { get; set; } - public double cpu { get; set; } + public int cpu { get; set; } public uint64 memory { get; set; } public int pid { get; set; } public string cmd { get; set; } @@ -28,10 +28,12 @@ public class Monitor.TreeViewModel : GLib.Object { public signal void added_first_row (); public Gee.MapFunc str_sorter = (property_name) => - new Gtk.StringSorter(new Gtk.PropertyExpression(typeof (ProcessRowData), null, property_name)); + new Gtk.StringSorter(new Gtk.PropertyExpression(typeof (ProcessRowData), null, property_name) ); public Gee.MapFunc num_sorter = (property_name) => - new Gtk.NumericSorter(new Gtk.PropertyExpression(typeof (ProcessRowData), null, property_name)); + new Gtk.NumericSorter(new Gtk.PropertyExpression(typeof (ProcessRowData), null, property_name) ) { + sort_order = Gtk.SortType.DESCENDING + }; construct { process_rows = new Gee.HashMap (); @@ -71,7 +73,7 @@ public class Monitor.TreeViewModel : GLib.Object { var row = new ProcessRowData () { icon = process.icon.to_string (), name = process.application_name, - cpu = process.cpu_percentage, + cpu = (int) process.cpu_percentage, memory = process.mem_usage, pid = process.stat.pid, cmd = process.command @@ -97,7 +99,7 @@ public class Monitor.TreeViewModel : GLib.Object { uint pos; if (list_store.find (process_row, out pos)) { var item = list_store.get_item (pos) as ProcessRowData; - item.cpu = process.cpu_percentage; + item.cpu = (int) process.cpu_percentage; item.memory = process.mem_usage; list_store.items_changed (pos, 1, 1); } else { diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index ebceadf99..caa46fea3 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -27,10 +27,9 @@ public class Monitor.ProcessTreeView : Granite.Bin { search = needle }; - + // since the pid property is an int, we need to use a custom filter to convert it to a string pid_filter = new Gtk.CustomFilter ((obj) => { var item = (ProcessRowData) obj; - print ("Filtering PID: %d with needle: %s\n".printf (item.pid, needle)); bool pid_found = item.pid.to_string ().contains (needle.casefold ()) || false; return pid_found; }); @@ -60,6 +59,8 @@ public class Monitor.ProcessTreeView : Granite.Bin { hexpand = true, vexpand = true }; + sorted_list.sorter = list.sorter; + var row_factory = new Gtk.SignalListItemFactory (); @@ -99,7 +100,6 @@ public class Monitor.ProcessTreeView : Granite.Bin { expand = true }; list.append_column (name_column); - sorted_list.sorter = list.sorter; cpu_item_factory.setup.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; From b6c29332cc0a5617ac33406f83ce2de7d34bb3c1 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Wed, 4 Mar 2026 17:53:21 +0100 Subject: [PATCH 13/28] ProcessTreeView: show process icons --- src/Models/TreeViewModel.vala | 4 ++-- .../ProcessTreeView/ProcessTreeView.vala | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Models/TreeViewModel.vala b/src/Models/TreeViewModel.vala index bec5cca62..bba146f65 100644 --- a/src/Models/TreeViewModel.vala +++ b/src/Models/TreeViewModel.vala @@ -13,7 +13,7 @@ public enum Monitor.Column { } public class Monitor.ProcessRowData : GLib.Object { - public string icon { get; set; } + public Icon icon { get; set; } public string name { get; set; } public int cpu { get; set; } public uint64 memory { get; set; } @@ -71,7 +71,7 @@ public class Monitor.TreeViewModel : GLib.Object { // Gtk.TreeIter iter; // append (out iter, null); // null means top-level var row = new ProcessRowData () { - icon = process.icon.to_string (), + icon = process.icon, name = process.application_name, cpu = (int) process.cpu_percentage, memory = process.mem_usage, diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index caa46fea3..23781c357 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -51,7 +51,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { var row_data = selection_model.get_selected_item () as ProcessRowData; Process process = model.process_manager.get_process (row_data.pid); process_selected (process); - }); + }); list = new Gtk.ColumnView (selection_model) { name = "monitor-process-column-view", @@ -82,17 +82,29 @@ public class Monitor.ProcessTreeView : Granite.Bin { name_item_factory.setup.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; - cell.child = new Gtk.Label (Utils.NO_DATA) { + + var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) { hexpand = true, halign = Gtk.Align.START }; + var icon = new Gtk.Image.from_icon_name ("application-x-executable") { + pixel_size = 16 + }; + + box.append (icon); + box.append (new Gtk.Label (Utils.NO_DATA)); + cell.child = box; }); name_item_factory.bind.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; - var label = cell.child as Gtk.Label; + var box = cell.child as Gtk.Box; + var label = box.get_last_child () as Gtk.Label; + var icon = box.get_first_child () as Gtk.Image; + var item = cell.item as ProcessRowData; label.set_text (item.name); + icon.gicon = item.icon; }); var name_column = new Gtk.ColumnViewColumn (_("Process Name"), name_item_factory) { From d37b1e1520950569f71746f807342cd0ab8245fe Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Wed, 4 Mar 2026 20:01:50 +0100 Subject: [PATCH 14/28] TreeViewModel: refactor --- src/MainWindow.vala | 6 +- src/Models/TreeViewModel.vala | 49 +++++++++++++++++ .../ProcessTreeView/ProcessTreeView.vala | 55 +------------------ src/Views/ProcessView/ProcessView.vala | 4 +- 4 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 6d27b593c..b7e9c839d 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -106,9 +106,9 @@ public class Monitor.MainWindow : Gtk.ApplicationWindow { process_view.process_tree_view.collapse_all (); } - process_view.process_tree_view.name_filter.search = search_entry.text; - process_view.process_tree_view.cmd_filter.search = search_entry.text; - process_view.process_tree_view.needle = search_entry.text; + process_view.treeview_model.name_filter.search = search_entry.text; + process_view.treeview_model.cmd_filter.search = search_entry.text; + process_view.treeview_model.needle = search_entry.text; // focus on child row to avoid the app crashes by clicking "Kill/End Process" buttons in headerbar process_view.process_tree_view.focus_on_child_row (); diff --git a/src/Models/TreeViewModel.vala b/src/Models/TreeViewModel.vala index bba146f65..f38025627 100644 --- a/src/Models/TreeViewModel.vala +++ b/src/Models/TreeViewModel.vala @@ -22,10 +22,20 @@ public class Monitor.ProcessRowData : GLib.Object { } public class Monitor.TreeViewModel : GLib.Object { + public string needle = ""; + public ProcessManager process_manager; public GLib.ListStore list_store; + public Gtk.SortListModel sorted_list; + public Gtk.StringFilter name_filter; + public Gtk.StringFilter cmd_filter; + public Gtk.CustomFilter pid_filter; + public Gtk.FilterListModel filtered_list; + public Gtk.SingleSelection selection_model; private Gee.Map process_rows; public signal void added_first_row (); + public signal void process_selected (Process process); + public Gee.MapFunc str_sorter = (property_name) => new Gtk.StringSorter(new Gtk.PropertyExpression(typeof (ProcessRowData), null, property_name) ); @@ -38,6 +48,45 @@ public class Monitor.TreeViewModel : GLib.Object { construct { process_rows = new Gee.HashMap (); list_store = new GLib.ListStore (typeof (ProcessRowData)); + sorted_list = new Gtk.SortListModel (list_store, null); + + + var expression = new Gtk.PropertyExpression (typeof (ProcessRowData), null, "name"); + name_filter = new Gtk.StringFilter (expression) { + ignore_case = true, + match_mode = SUBSTRING, + search = needle + }; + + cmd_filter = new Gtk.StringFilter (new Gtk.PropertyExpression (typeof (ProcessRowData), null, "cmd")) { + ignore_case = true, + match_mode = SUBSTRING, + search = needle + }; + + // since the pid property is an int, we need to use a custom filter to convert it to a string + pid_filter = new Gtk.CustomFilter ((obj) => { + var item = (ProcessRowData) obj; + bool pid_found = item.pid.to_string ().contains (needle.casefold ()) || false; + return pid_found; + }); + + var any_filter = new Gtk.AnyFilter (); + any_filter.append (name_filter); + any_filter.append (cmd_filter); + any_filter.append (pid_filter); + + filtered_list = new Gtk.FilterListModel (sorted_list, any_filter); + + selection_model = new Gtk.SingleSelection (filtered_list) { + autoselect = true + }; + + selection_model.notify["selected-item"].connect ((sender, property) => { + var row_data = selection_model.get_selected_item () as ProcessRowData; + Process process = process_manager.get_process (row_data.pid); + process_selected (process); + }); // set_column_types (new Type[] { // typeof (string), diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index 23781c357..adadde267 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -2,64 +2,15 @@ public class Monitor.ProcessTreeView : Granite.Bin { private Gtk.ColumnView list; - public signal void process_selected (Process process); - - public string needle = ""; - - public Gtk.StringFilter name_filter; - public Gtk.StringFilter cmd_filter; - public Gtk.CustomFilter pid_filter; - // private new TreeViewModel model; public ProcessTreeView (TreeViewModel model) { - var sorted_list = new Gtk.SortListModel (model.list_store, null); - - var expression = new Gtk.PropertyExpression (typeof (ProcessRowData), null, "name"); - name_filter = new Gtk.StringFilter (expression) { - ignore_case = true, - match_mode = SUBSTRING, - search = needle - }; - - cmd_filter = new Gtk.StringFilter (new Gtk.PropertyExpression (typeof (ProcessRowData), null, "cmd")) { - ignore_case = true, - match_mode = SUBSTRING, - search = needle - }; - - // since the pid property is an int, we need to use a custom filter to convert it to a string - pid_filter = new Gtk.CustomFilter ((obj) => { - var item = (ProcessRowData) obj; - bool pid_found = item.pid.to_string ().contains (needle.casefold ()) || false; - return pid_found; - }); - - var any_filter = new Gtk.AnyFilter (); - any_filter.append (name_filter); - any_filter.append (cmd_filter); - any_filter.append (pid_filter); - - - var filter_model = new Gtk.FilterListModel (sorted_list, any_filter); - - - var selection_model = new Gtk.SingleSelection (filter_model) { - autoselect = true - }; - - selection_model.notify["selected-item"].connect ((sender, property) => { - var row_data = selection_model.get_selected_item () as ProcessRowData; - Process process = model.process_manager.get_process (row_data.pid); - process_selected (process); - }); - - list = new Gtk.ColumnView (selection_model) { + list = new Gtk.ColumnView (model.selection_model) { name = "monitor-process-column-view", reorderable = false, hexpand = true, vexpand = true }; - sorted_list.sorter = list.sorter; + model.sorted_list.sorter = list.sorter; var row_factory = new Gtk.SignalListItemFactory (); @@ -83,7 +34,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { name_item_factory.setup.connect ((factory, obj) => { var cell = obj as Gtk.ColumnViewCell; - var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) { + var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 4) { hexpand = true, halign = Gtk.Align.START }; diff --git a/src/Views/ProcessView/ProcessView.vala b/src/Views/ProcessView/ProcessView.vala index b8121cdcc..e0380f29c 100644 --- a/src/Views/ProcessView/ProcessView.vala +++ b/src/Views/ProcessView/ProcessView.vala @@ -7,7 +7,7 @@ public class Monitor.ProcessView : Granite.Bin { public ProcessTreeView process_tree_view { get; private set; } private ProcessInfoView process_info_view; - private TreeViewModel treeview_model; + public TreeViewModel treeview_model { get; private set; } private SimpleAction end_action; @@ -17,7 +17,7 @@ public class Monitor.ProcessView : Granite.Bin { treeview_model = new TreeViewModel (); process_tree_view = new ProcessTreeView (treeview_model); - process_tree_view.process_selected.connect ((process) => on_process_selected (process)); + treeview_model.process_selected.connect ((process) => on_process_selected (process)); From ead83cdccd92f5cec071404ad0da4b298abc6eb4 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Wed, 4 Mar 2026 22:11:28 +0100 Subject: [PATCH 15/28] TreeViewModel: refactor --- src/MainWindow.vala | 4 +- src/Models/TreeViewModel.vala | 135 ++++++++++-------- .../ProcessTreeView/ProcessTreeView.vala | 2 +- 3 files changed, 80 insertions(+), 61 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index b7e9c839d..ab6a599ce 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -106,9 +106,7 @@ public class Monitor.MainWindow : Gtk.ApplicationWindow { process_view.process_tree_view.collapse_all (); } - process_view.treeview_model.name_filter.search = search_entry.text; - process_view.treeview_model.cmd_filter.search = search_entry.text; - process_view.treeview_model.needle = search_entry.text; + process_view.treeview_model.filtered.needle = search_entry.text; // focus on child row to avoid the app crashes by clicking "Kill/End Process" buttons in headerbar process_view.process_tree_view.focus_on_child_row (); diff --git a/src/Models/TreeViewModel.vala b/src/Models/TreeViewModel.vala index f38025627..aa1aa6195 100644 --- a/src/Models/TreeViewModel.vala +++ b/src/Models/TreeViewModel.vala @@ -21,64 +21,86 @@ public class Monitor.ProcessRowData : GLib.Object { public string cmd { get; set; } } -public class Monitor.TreeViewModel : GLib.Object { - public string needle = ""; - - public ProcessManager process_manager; - public GLib.ListStore list_store; - public Gtk.SortListModel sorted_list; +public class Monitor.TreeViewFilter : GLib.Object { + private string _needle; + public string needle { + get { + return _needle; + } + set { + name_filter.search = value; + cmd_filter.search = value; + _needle = value; + } + } + public Gtk.FilterListModel model_out; + private Gtk.AnyFilter any_filter; public Gtk.StringFilter name_filter; public Gtk.StringFilter cmd_filter; public Gtk.CustomFilter pid_filter; - public Gtk.FilterListModel filtered_list; - public Gtk.SingleSelection selection_model; - private Gee.Map process_rows; - public signal void added_first_row (); - public signal void process_selected (Process process); + public TreeViewFilter (GLib.ListModel? model) { + name_filter = build_str_filter ("name"); + cmd_filter = build_str_filter ("cmd"); - public Gee.MapFunc str_sorter = (property_name) => - new Gtk.StringSorter(new Gtk.PropertyExpression(typeof (ProcessRowData), null, property_name) ); + // since the pid property is an int, we need to use a custom filter to convert it to a string + pid_filter = new Gtk.CustomFilter ((obj) => { + var item = (ProcessRowData) obj; + bool pid_found = item.pid.to_string ().contains (needle.casefold ()) || false; + return pid_found; + }); - public Gee.MapFunc num_sorter = (property_name) => - new Gtk.NumericSorter(new Gtk.PropertyExpression(typeof (ProcessRowData), null, property_name) ) { - sort_order = Gtk.SortType.DESCENDING - }; + any_filter = new Gtk.AnyFilter (); + any_filter.append (name_filter); + any_filter.append (cmd_filter); + any_filter.append (pid_filter); - construct { - process_rows = new Gee.HashMap (); - list_store = new GLib.ListStore (typeof (ProcessRowData)); - sorted_list = new Gtk.SortListModel (list_store, null); + model_out = new Gtk.FilterListModel (model, any_filter); + } - var expression = new Gtk.PropertyExpression (typeof (ProcessRowData), null, "name"); - name_filter = new Gtk.StringFilter (expression) { + private Gtk.StringFilter build_str_filter (string column_name) { + var expression = new Gtk.PropertyExpression (typeof (ProcessRowData), null, column_name); + return new Gtk.StringFilter (expression) { ignore_case = true, match_mode = SUBSTRING, search = needle }; + } - cmd_filter = new Gtk.StringFilter (new Gtk.PropertyExpression (typeof (ProcessRowData), null, "cmd")) { - ignore_case = true, - match_mode = SUBSTRING, - search = needle - }; +} - // since the pid property is an int, we need to use a custom filter to convert it to a string - pid_filter = new Gtk.CustomFilter ((obj) => { - var item = (ProcessRowData) obj; - bool pid_found = item.pid.to_string ().contains (needle.casefold ()) || false; - return pid_found; - }); +public class Monitor.TreeViewModel : GLib.Object { - var any_filter = new Gtk.AnyFilter (); - any_filter.append (name_filter); - any_filter.append (cmd_filter); - any_filter.append (pid_filter); + public ProcessManager process_manager; + + public TreeViewFilter filtered; + public Gtk.SingleSelection selection_model; + + public signal void added_first_row (); + public signal void process_selected (Process process); - filtered_list = new Gtk.FilterListModel (sorted_list, any_filter); + public Gtk.Sorter sorter { + get { return sorted.sorter; } + set { + sorted.sorter = value; + } + } + + private GLib.ListStore store; + private Gtk.SortListModel sorted; + + private Gee.Map process_rows; + + + construct { + process_rows = new Gee.HashMap (); + store = new GLib.ListStore (typeof (ProcessRowData)); + sorted = new Gtk.SortListModel (store, null); - selection_model = new Gtk.SingleSelection (filtered_list) { + filtered = new TreeViewFilter (sorted); + + selection_model = new Gtk.SingleSelection (filtered.model_out) { autoselect = true }; @@ -88,15 +110,6 @@ public class Monitor.TreeViewModel : GLib.Object { process_selected (process); }); - // set_column_types (new Type[] { - // typeof (string), - // typeof (string), - // typeof (double), - // typeof (int64), - // typeof (int), - // typeof (string), - // }); - process_manager = ProcessManager.get_default (); process_manager.process_added.connect ((process) => add_process (process)); process_manager.process_removed.connect ((pid) => remove_process (pid)); @@ -105,6 +118,16 @@ public class Monitor.TreeViewModel : GLib.Object { Idle.add (() => { add_running_processes (); return false; }); } + public Gtk.StringSorter str_sorter (string column_name) { + return new Gtk.StringSorter (new Gtk.PropertyExpression (typeof (ProcessRowData), null, column_name)); + } + + public Gtk.NumericSorter num_sorter (string column_name) { + return new Gtk.NumericSorter (new Gtk.PropertyExpression (typeof (ProcessRowData), null, column_name)) { + sort_order = Gtk.SortType.DESCENDING + }; + } + private void add_running_processes () { debug ("add_running_processes"); var running_processes = process_manager.get_process_list (); @@ -117,8 +140,6 @@ public class Monitor.TreeViewModel : GLib.Object { if (process != null && !process_rows.has_key (process.stat.pid)) { debug ("Add process %d Parent PID: %d", process.stat.pid, process.stat.ppid); // add the process to the model - // Gtk.TreeIter iter; - // append (out iter, null); // null means top-level var row = new ProcessRowData () { icon = process.icon, name = process.application_name, @@ -128,7 +149,7 @@ public class Monitor.TreeViewModel : GLib.Object { cmd = process.command }; - list_store.append (row); + store.append (row); if (process_rows.size < 1) { added_first_row (); @@ -146,11 +167,11 @@ public class Monitor.TreeViewModel : GLib.Object { var process_row = process_rows.get (pid); uint pos; - if (list_store.find (process_row, out pos)) { - var item = list_store.get_item (pos) as ProcessRowData; + if (store.find (process_row, out pos)) { + var item = store.get_item (pos) as ProcessRowData; item.cpu = (int) process.cpu_percentage; item.memory = process.mem_usage; - list_store.items_changed (pos, 1, 1); + store.items_changed (pos, 1, 1); } else { debug ("Failed to find process row for pid %d", pid); } @@ -163,8 +184,8 @@ public class Monitor.TreeViewModel : GLib.Object { if (process_rows.has_key (pid)) { uint pos; var process_row = process_rows.get (pid); - if (list_store.find (process_row, out pos)) { - list_store.remove (pos); + if (store.find (process_row, out pos)) { + store.remove (pos); } process_rows.unset (pid); } diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index adadde267..9537e29a0 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -10,7 +10,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { hexpand = true, vexpand = true }; - model.sorted_list.sorter = list.sorter; + model.sorter = list.sorter; var row_factory = new Gtk.SignalListItemFactory (); From a0927f2f2a5d4b9ec4e98486ae4b4f61eeac90f9 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Wed, 4 Mar 2026 22:17:50 +0100 Subject: [PATCH 16/28] CPUProcessTreeView: adios! --- .../ProcessTreeView/CPUProcessTreeView.vala | 217 ------------------ 1 file changed, 217 deletions(-) delete mode 100644 src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala diff --git a/src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala deleted file mode 100644 index 51d3c2ef2..000000000 --- a/src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2025 elementary, Inc. (https://elementary.io) - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -public class Monitor.CPUProcessTreeView : Gtk.TreeView { - private new TreeViewModel model; - private Gtk.TreeViewColumn name_column; - private Gtk.TreeViewColumn pid_column; - private Gtk.TreeViewColumn cpu_column; - private Gtk.TreeViewColumn memory_column; - - public signal void process_selected (Process process); - - public CPUProcessTreeView (TreeViewModel model) { - this.model = model; - - enable_search = false; - - // setup name column - name_column = new Gtk.TreeViewColumn (); - name_column.title = _("Process Name"); - name_column.expand = true; - name_column.min_width = 250; - name_column.set_sort_column_id (Column.NAME); - - var icon_cell = new Gtk.CellRendererPixbuf (); - name_column.pack_start (icon_cell, false); - // name_column.add_attribute (icon_cell, "icon_name", Column.ICON); - name_column.set_cell_data_func (icon_cell, icon_cell_layout); - - var name_cell = new Gtk.CellRendererText (); - name_cell.ellipsize = Pango.EllipsizeMode.END; - name_cell.set_fixed_height_from_font (1); - name_column.pack_start (name_cell, false); - name_column.add_attribute (name_cell, "text", Column.NAME); - insert_column (name_column, -1); - - // setup cpu column - var cpu_cell = new Gtk.CellRendererText (); - cpu_cell.xalign = 0.5f; - - cpu_column = new Gtk.TreeViewColumn.with_attributes (_("CPU"), cpu_cell); - cpu_column.expand = false; - cpu_column.set_cell_data_func (cpu_cell, cpu_usage_cell_layout); - cpu_column.alignment = 0.5f; - cpu_column.set_sort_column_id (Column.CPU); - insert_column (cpu_column, -1); - - // setup memory column - var memory_cell = new Gtk.CellRendererText (); - memory_cell.xalign = 0.5f; - - memory_column = new Gtk.TreeViewColumn.with_attributes (_("Memory"), memory_cell); - memory_column.expand = false; - memory_column.set_cell_data_func (memory_cell, memory_usage_cell_layout); - memory_column.alignment = 0.5f; - memory_column.set_sort_column_id (Column.MEMORY); - insert_column (memory_column, -1); - - // setup PID column - var pid_cell = new Gtk.CellRendererText (); - pid_cell.xalign = 0.5f; - pid_column = new Gtk.TreeViewColumn.with_attributes (_("PID"), pid_cell); - pid_column.set_cell_data_func (pid_cell, pid_cell_layout); - pid_column.expand = false; - pid_column.alignment = 0.5f; - pid_column.set_sort_column_id (Column.PID); - pid_column.add_attribute (pid_cell, "text", Column.PID); - insert_column (pid_column, -1); - - // resize all of the columns - columns_autosize (); - - set_model (model); - - model.added_first_row.connect (() => { - focus_on_first_row (); - }); - - cursor_changed.connect (_cursor_changed); - // model.process_manager.updated.connect (_cursor_changed); - - var key_controller = new Gtk.EventControllerKey (); - add_controller (key_controller); - key_controller.key_released.connect ((keyval, keycode, state) => { - switch (keyval) { - case Gdk.Key.Left: - collapse (); - break; - case Gdk.Key.Right: - expanded (); - break; - } - }); - } - public void icon_cell_layout (Gtk.CellLayout cell_layout, Gtk.CellRenderer icon_cell, Gtk.TreeModel model, Gtk.TreeIter iter) { - Value icon_name; - model.get_value (iter, Column.ICON, out icon_name); - string path = ((string) icon_name); - - ((Gtk.CellRendererPixbuf)icon_cell).icon_name = path; - } - - public void cpu_usage_cell_layout (Gtk.CellLayout cell_layout, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter) { - // grab the value that was store in the model and convert it down to a usable format - Value cpu_usage_value; - model.get_value (iter, Column.CPU, out cpu_usage_value); - double cpu_usage = cpu_usage_value.get_double (); - - // format the double into a string - if (cpu_usage < 0.0) - ((Gtk.CellRendererText)cell).text = Utils.NO_DATA; - else - ((Gtk.CellRendererText)cell).text = "%.0f%%".printf (cpu_usage); - } - - public void memory_usage_cell_layout (Gtk.CellLayout cell_layout, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter) { - // grab the value that was store in the model and convert it down to a usable format - Value memory_usage_value; - model.get_value (iter, Column.MEMORY, out memory_usage_value); - int64 memory_usage = memory_usage_value.get_int64 (); - double memory_usage_double = (double) memory_usage; - string units = _("KiB"); - - // convert to MiB if needed - if (memory_usage_double > 1024.0) { - memory_usage_double /= 1024.0; - units = _("MiB"); - } - - // convert to GiB if needed - if (memory_usage_double > 1024.0) { - memory_usage_double /= 1024.0; - units = _("GiB"); - } - - // format the double into a string - if (memory_usage == 0) - ((Gtk.CellRendererText)cell).text = Utils.NO_DATA; - else - ((Gtk.CellRendererText)cell).text = "%.1f %s".printf (memory_usage_double, units); - } - - private void pid_cell_layout (Gtk.CellLayout cell_layout, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter) { - Value pid_value; - model.get_value (iter, Column.PID, out pid_value); - int pid = pid_value.get_int (); - // format the double into a string - if (pid == 0) { - ((Gtk.CellRendererText)cell).text = Utils.NO_DATA; - } - } - - public void focus_on_first_row () { - Gtk.TreePath tree_path = new Gtk.TreePath.from_indices (0); - this.set_cursor (tree_path, null, false); - grab_focus (); - } - - public void focus_on_child_row () { - Gtk.TreePath tree_path = new Gtk.TreePath.from_indices (0, 0); - this.set_cursor (tree_path, null, false); - grab_focus (); - } - - public int get_pid_of_selected () { - Gtk.TreeIter iter; - Gtk.TreeModel model; - int pid = 0; - var selection = this.get_selection ().get_selected_rows (out model).nth_data (0); - model.get_iter (out iter, selection); - model.get (iter, Column.PID, out pid); - return pid; - } - - // How about GtkTreeSelection ? - - public void expanded () { - Gtk.TreeModel model; - var selection = this.get_selection ().get_selected_rows (out model).nth_data (0); - this.expand_row (selection, false); - } - - public void collapse () { - Gtk.TreeModel model; - var selection = this.get_selection ().get_selected_rows (out model).nth_data (0); - this.collapse_row (selection); - } - - public void kill_process () { - int pid = get_pid_of_selected (); - model.kill_process (pid); - } - - public void end_process () { - int pid = get_pid_of_selected (); - model.end_process (pid); - } - - // when row is selected send signal to update process_info_view - public void _cursor_changed () { - Gtk.TreeModel tree_model; - Gtk.TreeIter iter; - int pid = 0; - var selection = get_selection ().get_selected_rows (out tree_model).nth_data (0); - - if (selection != null) { - tree_model.get_iter (out iter, selection); - tree_model.get (iter, Column.PID, out pid); - Process process = model.process_manager.get_process (pid); - process_selected (process); - debug ("cursor changed"); - } - } - -} From 6b66db3c2bf602ab2e005f13564cb6ec60f1cb26 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Wed, 4 Mar 2026 22:21:33 +0100 Subject: [PATCH 17/28] ProcessView: remove obsolete commented out filtering function --- src/Views/ProcessView/ProcessView.vala | 37 -------------------------- 1 file changed, 37 deletions(-) diff --git a/src/Views/ProcessView/ProcessView.vala b/src/Views/ProcessView/ProcessView.vala index e0380f29c..55ff27d6d 100644 --- a/src/Views/ProcessView/ProcessView.vala +++ b/src/Views/ProcessView/ProcessView.vala @@ -147,41 +147,4 @@ public class Monitor.ProcessView : Granite.Bin { } - // private bool filter_func (Gtk.TreeModel model, Gtk.TreeIter iter) { - // string name_haystack; - // int pid_haystack; - // string cmd_haystack; - // bool found = false; - - // if (needle.length == 0) { - // return true; - // } - - // model.get (iter, Column.NAME, out name_haystack, -1); - // model.get (iter, Column.PID, out pid_haystack, -1); - // model.get (iter, Column.CMD, out cmd_haystack, -1); - - // // sometimes name_haystack is null - // if (name_haystack != null) { - // bool name_found = name_haystack.casefold ().contains (needle.casefold ()) || false; - // bool pid_found = pid_haystack.to_string ().casefold ().contains (needle.casefold ()) || false; - // bool cmd_found = cmd_haystack.casefold ().contains (needle.casefold ()) || false; - // found = name_found || pid_found || cmd_found; - // } - - // Gtk.TreeIter child_iter; - // bool child_found = false; - - // if (model.iter_children (out child_iter, iter)) { - // do { - // child_found = filter_func (model, child_iter); - // } while (model.iter_next (ref child_iter) && !child_found); - // } - - // if (child_found && needle.length > 0) { - // // process_tree_view.expand_all (); - // } - - // return found || child_found; - // } } From 952481b057c1cb6b220b4ddbde74eb2c9f263f4c Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Thu, 5 Mar 2026 13:27:20 +0100 Subject: [PATCH 18/28] cleanup --- .../ProcessView/ProcessTreeView/ProcessTreeView.vala | 9 --------- src/Views/ProcessView/ProcessView.vala | 2 -- 2 files changed, 11 deletions(-) diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index 9537e29a0..5a671997f 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -12,15 +12,6 @@ public class Monitor.ProcessTreeView : Granite.Bin { }; model.sorter = list.sorter; - - var row_factory = new Gtk.SignalListItemFactory (); - - row_factory.setup.connect ((factory, obj) => { - var row = obj as Gtk.ColumnViewRow; - }); - - list.row_factory = row_factory; - child = new Gtk.ScrolledWindow () { child = list }; diff --git a/src/Views/ProcessView/ProcessView.vala b/src/Views/ProcessView/ProcessView.vala index 55ff27d6d..27999edfb 100644 --- a/src/Views/ProcessView/ProcessView.vala +++ b/src/Views/ProcessView/ProcessView.vala @@ -19,8 +19,6 @@ public class Monitor.ProcessView : Granite.Bin { process_tree_view = new ProcessTreeView (treeview_model); treeview_model.process_selected.connect ((process) => on_process_selected (process)); - - process_info_view = new ProcessInfoView () { // This might be useless since first process is selected // automatically and this triggers on_process_selected (). From d5b24924aeda5fe8f1a21fbd6e60e05198ed4749 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:42:33 +0100 Subject: [PATCH 19/28] Remove unused functions --- .../ProcessView/ProcessTreeView/ProcessTreeView.vala | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index 5a671997f..013000b2d 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -136,16 +136,5 @@ public class Monitor.ProcessTreeView : Granite.Bin { } - public void collapse_all () { - // Method implementation - } - - public void focus_on_child_row () { - // Method implementation - } - - public void focus_on_first_row () { - // Method implementation - } } From 336bde88198c8ef79ea4a4ac518deb7ecc04f960 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:43:04 +0100 Subject: [PATCH 20/28] Remove unneeded GTK namespaces --- .../ProcessView/ProcessTreeView/ProcessTreeView.vala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index 013000b2d..11c900bb8 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -27,7 +27,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 4) { hexpand = true, - halign = Gtk.Align.START + halign = START }; var icon = new Gtk.Image.from_icon_name ("application-x-executable") { pixel_size = 16 @@ -59,7 +59,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { var cell = obj as Gtk.ColumnViewCell; cell.child = new Gtk.Label (Utils.NO_DATA) { hexpand = true, - halign = Gtk.Align.START + halign = START }; }); @@ -80,7 +80,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { var cell = obj as Gtk.ColumnViewCell; cell.child = new Gtk.Label (Utils.NO_DATA) { hexpand = true, - halign = Gtk.Align.START + halign = START }; }); @@ -117,7 +117,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { var cell = obj as Gtk.ColumnViewCell; cell.child = new Gtk.Label (Utils.NO_DATA) { hexpand = true, - halign = Gtk.Align.START + halign = START }; }); From af1686b7c26adafee430c8d5e55c75f0857dddec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <6031763+stsdc@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:49:42 +0100 Subject: [PATCH 21/28] Use correct casting syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Danielle Foré --- .../ProcessView/ProcessTreeView/ProcessTreeView.vala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index 11c900bb8..cfa2066f9 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -64,10 +64,10 @@ public class Monitor.ProcessTreeView : Granite.Bin { }); cpu_item_factory.bind.connect ((factory, obj) => { - var cell = obj as Gtk.ColumnViewCell; - var label = cell.child as Gtk.Label; - var item = cell.item as ProcessRowData; - label.set_text ("%.0f%%".printf (item.cpu)); + var cell = (Gtk.ColumnViewCell) obj; + var label = (Gtk.Label) cell.child; + var item = (ProcessRowData) cell.item; + label.text = "%.0f%%".printf (item.cpu); }); var cpu_column = new Gtk.ColumnViewColumn (_("CPU"), cpu_item_factory) { From 63e94bae910ab55a04606667d9446682728db4c6 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:53:38 +0100 Subject: [PATCH 22/28] Remove old treeview functionality --- src/MainWindow.vala | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index ab6a599ce..646b05263 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -101,21 +101,10 @@ public class Monitor.MainWindow : Gtk.ApplicationWindow { MonitorApp.settings.bind ("opened-view", stack, "visible-child-name", DEFAULT); search_entry.search_changed.connect (() => { - // collapse tree only when search is focused and changed - if (search_entry.is_focus ()) { - process_view.process_tree_view.collapse_all (); - } - process_view.treeview_model.filtered.needle = search_entry.text; - - // focus on child row to avoid the app crashes by clicking "Kill/End Process" buttons in headerbar - process_view.process_tree_view.focus_on_child_row (); search_entry.grab_focus (); }); - search_entry.activate.connect (() => { - process_view.process_tree_view.focus_on_first_row (); - }); var search_action = new GLib.SimpleAction ("search", null); search_action.activate.connect (() => { From 6424b20013bf0175fd0f6f673f0616adcfce1bee Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Fri, 6 Mar 2026 12:07:28 +0100 Subject: [PATCH 23/28] Fix code style --- src/Monitor.vala | 1 - .../ProcessTreeView/ProcessTreeView.vala | 39 +++++++++---------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/Monitor.vala b/src/Monitor.vala index 5a71ae5f3..a0c84d1c8 100644 --- a/src/Monitor.vala +++ b/src/Monitor.vala @@ -128,7 +128,6 @@ namespace Monitor { settings.bind ("is-maximized", window, "maximized", SettingsBindFlags.SET); - window.process_view.process_tree_view.focus_on_first_row (); } public static int main (string[] args) { diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index cfa2066f9..75d4c5654 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -21,9 +21,8 @@ public class Monitor.ProcessTreeView : Granite.Bin { var memory_item_factory = new Gtk.SignalListItemFactory (); var pid_item_factory = new Gtk.SignalListItemFactory (); - name_item_factory.setup.connect ((factory, obj) => { - var cell = obj as Gtk.ColumnViewCell; + var cell = (Gtk.ColumnViewCell) obj; var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 4) { hexpand = true, @@ -39,13 +38,13 @@ public class Monitor.ProcessTreeView : Granite.Bin { }); name_item_factory.bind.connect ((factory, obj) => { - var cell = obj as Gtk.ColumnViewCell; - var box = cell.child as Gtk.Box; - var label = box.get_last_child () as Gtk.Label; - var icon = box.get_first_child () as Gtk.Image; + var cell = (Gtk.ColumnViewCell) obj; + var box = (Gtk.Box) cell.child; + var label = (Gtk.Label) box.get_last_child (); + var icon = (Gtk.Image) box.get_first_child (); - var item = cell.item as ProcessRowData; - label.set_text (item.name); + var item = (ProcessRowData) cell.item; + label.label = item.name; icon.gicon = item.icon; }); @@ -56,7 +55,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { list.append_column (name_column); cpu_item_factory.setup.connect ((factory, obj) => { - var cell = obj as Gtk.ColumnViewCell; + var cell = (Gtk.ColumnViewCell) obj; cell.child = new Gtk.Label (Utils.NO_DATA) { hexpand = true, halign = START @@ -67,7 +66,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { var cell = (Gtk.ColumnViewCell) obj; var label = (Gtk.Label) cell.child; var item = (ProcessRowData) cell.item; - label.text = "%.0f%%".printf (item.cpu); + label.label = "%.0f%%".printf (item.cpu); }); var cpu_column = new Gtk.ColumnViewColumn (_("CPU"), cpu_item_factory) { @@ -77,7 +76,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { list.append_column (cpu_column); memory_item_factory.setup.connect ((factory, obj) => { - var cell = obj as Gtk.ColumnViewCell; + var cell = (Gtk.ColumnViewCell) obj; cell.child = new Gtk.Label (Utils.NO_DATA) { hexpand = true, halign = START @@ -85,9 +84,9 @@ public class Monitor.ProcessTreeView : Granite.Bin { }); memory_item_factory.bind.connect ((factory, obj) => { - var cell = obj as Gtk.ColumnViewCell; - var label = cell.child as Gtk.Label; - var item = cell.item as ProcessRowData; + var cell = (Gtk.ColumnViewCell) obj; + var label = (Gtk.Label) cell.child; + var item = (ProcessRowData) cell.item; double memory_usage_double = (double) item.memory; string units = _("KiB"); @@ -104,7 +103,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { units = _("GiB"); } - label.set_text ("%.1f %s".printf (memory_usage_double, units)); + label.label = "%.1f %s".printf (memory_usage_double, units); }); var mem_column = new Gtk.ColumnViewColumn (_("Memory"), memory_item_factory) { @@ -114,7 +113,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { list.append_column (mem_column); pid_item_factory.setup.connect ((factory, obj) => { - var cell = obj as Gtk.ColumnViewCell; + var cell = (Gtk.ColumnViewCell) obj; cell.child = new Gtk.Label (Utils.NO_DATA) { hexpand = true, halign = START @@ -122,10 +121,10 @@ public class Monitor.ProcessTreeView : Granite.Bin { }); pid_item_factory.bind.connect ((factory, obj) => { - var cell = obj as Gtk.ColumnViewCell; - var label = cell.child as Gtk.Label; - var item = cell.item as ProcessRowData; - label.set_text ("%d".printf (item.pid)); + var cell = (Gtk.ColumnViewCell) obj; + var label = (Gtk.Label) cell.child; + var item = (ProcessRowData) cell.item; + label.label = "%d".printf (item.pid); }); var pid_column = new Gtk.ColumnViewColumn (_("PID"), pid_item_factory) { From 92d3a60ecba268325f07a485ea0a57af49f24a06 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:26:56 +0100 Subject: [PATCH 24/28] Use format_size; Move some setup factories to a separate reusable method --- .../ProcessTreeView/ProcessTreeView.vala | 48 +++++-------------- 1 file changed, 11 insertions(+), 37 deletions(-) diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index 75d4c5654..e921b4b9a 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -54,13 +54,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { }; list.append_column (name_column); - cpu_item_factory.setup.connect ((factory, obj) => { - var cell = (Gtk.ColumnViewCell) obj; - cell.child = new Gtk.Label (Utils.NO_DATA) { - hexpand = true, - halign = START - }; - }); + cpu_item_factory.setup.connect (metric_setup_factory); cpu_item_factory.bind.connect ((factory, obj) => { var cell = (Gtk.ColumnViewCell) obj; @@ -75,35 +69,14 @@ public class Monitor.ProcessTreeView : Granite.Bin { }; list.append_column (cpu_column); - memory_item_factory.setup.connect ((factory, obj) => { - var cell = (Gtk.ColumnViewCell) obj; - cell.child = new Gtk.Label (Utils.NO_DATA) { - hexpand = true, - halign = START - }; - }); + memory_item_factory.setup.connect (metric_setup_factory); memory_item_factory.bind.connect ((factory, obj) => { var cell = (Gtk.ColumnViewCell) obj; var label = (Gtk.Label) cell.child; var item = (ProcessRowData) cell.item; - double memory_usage_double = (double) item.memory; - string units = _("KiB"); - - // convert to MiB if needed - if (memory_usage_double > 1024.0) { - memory_usage_double /= 1024.0; - units = _("MiB"); - } - - // convert to GiB if needed - if (memory_usage_double > 1024.0) { - memory_usage_double /= 1024.0; - units = _("GiB"); - } - - label.label = "%.1f %s".printf (memory_usage_double, units); + label.label = format_size (item.memory, IEC_UNITS); }); var mem_column = new Gtk.ColumnViewColumn (_("Memory"), memory_item_factory) { @@ -112,13 +85,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { }; list.append_column (mem_column); - pid_item_factory.setup.connect ((factory, obj) => { - var cell = (Gtk.ColumnViewCell) obj; - cell.child = new Gtk.Label (Utils.NO_DATA) { - hexpand = true, - halign = START - }; - }); + pid_item_factory.setup.connect (metric_setup_factory); pid_item_factory.bind.connect ((factory, obj) => { var cell = (Gtk.ColumnViewCell) obj; @@ -135,5 +102,12 @@ public class Monitor.ProcessTreeView : Granite.Bin { } + private void metric_setup_factory (Object object) { + var cell = (Gtk.ColumnViewCell) object; + cell.child = new Gtk.Label (Utils.NO_DATA) { + hexpand = true, + halign = START + }; + } } From 0c921f1022d3fa453f14cf76180a759f2bb4cc3d Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:40:36 +0100 Subject: [PATCH 25/28] Convert lambdas to methods --- .../ProcessTreeView/ProcessTreeView.vala | 114 +++++++++--------- 1 file changed, 60 insertions(+), 54 deletions(-) diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index e921b4b9a..e9e094ab8 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -17,36 +17,21 @@ public class Monitor.ProcessTreeView : Granite.Bin { }; var name_item_factory = new Gtk.SignalListItemFactory (); + name_item_factory.setup.connect (name_item_setup_factory); + name_item_factory.bind.connect (name_item_bind_factory); + var cpu_item_factory = new Gtk.SignalListItemFactory (); + cpu_item_factory.setup.connect (generic_item_setup_factory); + cpu_item_factory.bind.connect (cpu_item_bind_factory); + var memory_item_factory = new Gtk.SignalListItemFactory (); + memory_item_factory.setup.connect (generic_item_setup_factory); + memory_item_factory.bind.connect (memory_item_bind_factory); + var pid_item_factory = new Gtk.SignalListItemFactory (); + pid_item_factory.setup.connect (generic_item_setup_factory); + pid_item_factory.bind.connect (pid_item_bind_factory); - name_item_factory.setup.connect ((factory, obj) => { - var cell = (Gtk.ColumnViewCell) obj; - - var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 4) { - hexpand = true, - halign = START - }; - var icon = new Gtk.Image.from_icon_name ("application-x-executable") { - pixel_size = 16 - }; - - box.append (icon); - box.append (new Gtk.Label (Utils.NO_DATA)); - cell.child = box; - }); - - name_item_factory.bind.connect ((factory, obj) => { - var cell = (Gtk.ColumnViewCell) obj; - var box = (Gtk.Box) cell.child; - var label = (Gtk.Label) box.get_last_child (); - var icon = (Gtk.Image) box.get_first_child (); - - var item = (ProcessRowData) cell.item; - label.label = item.name; - icon.gicon = item.icon; - }); var name_column = new Gtk.ColumnViewColumn (_("Process Name"), name_item_factory) { sorter = model.str_sorter ("name"), @@ -54,30 +39,12 @@ public class Monitor.ProcessTreeView : Granite.Bin { }; list.append_column (name_column); - cpu_item_factory.setup.connect (metric_setup_factory); - - cpu_item_factory.bind.connect ((factory, obj) => { - var cell = (Gtk.ColumnViewCell) obj; - var label = (Gtk.Label) cell.child; - var item = (ProcessRowData) cell.item; - label.label = "%.0f%%".printf (item.cpu); - }); - var cpu_column = new Gtk.ColumnViewColumn (_("CPU"), cpu_item_factory) { sorter = model.num_sorter ("cpu"), expand = false }; list.append_column (cpu_column); - memory_item_factory.setup.connect (metric_setup_factory); - - memory_item_factory.bind.connect ((factory, obj) => { - var cell = (Gtk.ColumnViewCell) obj; - var label = (Gtk.Label) cell.child; - var item = (ProcessRowData) cell.item; - - label.label = format_size (item.memory, IEC_UNITS); - }); var mem_column = new Gtk.ColumnViewColumn (_("Memory"), memory_item_factory) { sorter = model.num_sorter ("memory"), @@ -85,15 +52,6 @@ public class Monitor.ProcessTreeView : Granite.Bin { }; list.append_column (mem_column); - pid_item_factory.setup.connect (metric_setup_factory); - - pid_item_factory.bind.connect ((factory, obj) => { - var cell = (Gtk.ColumnViewCell) obj; - var label = (Gtk.Label) cell.child; - var item = (ProcessRowData) cell.item; - label.label = "%d".printf (item.pid); - }); - var pid_column = new Gtk.ColumnViewColumn (_("PID"), pid_item_factory) { sorter = model.num_sorter ("pid"), expand = false @@ -102,7 +60,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { } - private void metric_setup_factory (Object object) { + private void generic_item_setup_factory (Object object) { var cell = (Gtk.ColumnViewCell) object; cell.child = new Gtk.Label (Utils.NO_DATA) { hexpand = true, @@ -110,4 +68,52 @@ public class Monitor.ProcessTreeView : Granite.Bin { }; } + private void name_item_setup_factory (Object object) { + var cell = (Gtk.ColumnViewCell) object; + + var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 4) { + hexpand = true, + halign = START + }; + var icon = new Gtk.Image.from_icon_name ("application-x-executable") { + pixel_size = 16 + }; + + box.append (icon); + box.append (new Gtk.Label (Utils.NO_DATA)); + cell.child = box; + } + + private void name_item_bind_factory (Object object) { + var cell = (Gtk.ColumnViewCell) object; + var box = (Gtk.Box) cell.child; + var label = (Gtk.Label) box.get_last_child (); + var icon = (Gtk.Image) box.get_first_child (); + + var item = (ProcessRowData) cell.item; + label.label = item.name; + icon.gicon = item.icon; + } + + private void cpu_item_bind_factory (Object object) { + var cell = (Gtk.ColumnViewCell) object; + var label = (Gtk.Label) cell.child; + var item = (ProcessRowData) cell.item; + label.label = "%.0f%%".printf (item.cpu); + } + + private void memory_item_bind_factory (Object object) { + var cell = (Gtk.ColumnViewCell) object; + var label = (Gtk.Label) cell.child; + var item = (ProcessRowData) cell.item; + label.label = format_size (item.memory, IEC_UNITS); + } + + private void pid_item_bind_factory (Object object) { + var cell = (Gtk.ColumnViewCell) object; + var label = (Gtk.Label) cell.child; + var item = (ProcessRowData) cell.item; + label.label = "%d".printf (item.pid); + } + } From 932954a22f22fed154ef161647adbd0981cd2ca9 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:55:48 +0100 Subject: [PATCH 26/28] Remove a leftover comment --- src/meson.build | 1 - 1 file changed, 1 deletion(-) diff --git a/src/meson.build b/src/meson.build index e413854b5..c2146791a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -7,7 +7,6 @@ source_app_files = [ # Views 'Views/ProcessView/ProcessView.vala', 'Views/ProcessView/ProcessInfoView/ProcessInfoView.vala', - # 'Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala', 'Views/ProcessView/ProcessTreeView/ProcessTreeView.vala', 'Views/PreferencesView.vala', From 131fe8238d88ac0f3e12ffc266408c52424f7b0d Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Fri, 6 Mar 2026 15:20:42 +0100 Subject: [PATCH 27/28] Fix memory size --- src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index e9e094ab8..316c1bd0a 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -106,7 +106,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { var cell = (Gtk.ColumnViewCell) object; var label = (Gtk.Label) cell.child; var item = (ProcessRowData) cell.item; - label.label = format_size (item.memory, IEC_UNITS); + label.label = format_size (item.memory * 1024, IEC_UNITS); } private void pid_item_bind_factory (Object object) { From 74615a0f2cf98bb7a60dcd3a734ff54a1fa92062 Mon Sep 17 00:00:00 2001 From: stsdc <6031763+stsdc@users.noreply.github.com> Date: Fri, 6 Mar 2026 21:34:42 +0100 Subject: [PATCH 28/28] Localize column_view object --- .../ProcessTreeView/ProcessTreeView.vala | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index 316c1bd0a..18614a81e 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -1,19 +1,18 @@ public class Monitor.ProcessTreeView : Granite.Bin { - private Gtk.ColumnView list; public ProcessTreeView (TreeViewModel model) { - list = new Gtk.ColumnView (model.selection_model) { + var column_view = new Gtk.ColumnView (model.selection_model) { name = "monitor-process-column-view", reorderable = false, hexpand = true, vexpand = true }; - model.sorter = list.sorter; + model.sorter = column_view.sorter; child = new Gtk.ScrolledWindow () { - child = list + child = column_view }; var name_item_factory = new Gtk.SignalListItemFactory (); @@ -37,26 +36,26 @@ public class Monitor.ProcessTreeView : Granite.Bin { sorter = model.str_sorter ("name"), expand = true }; - list.append_column (name_column); + column_view.append_column (name_column); var cpu_column = new Gtk.ColumnViewColumn (_("CPU"), cpu_item_factory) { sorter = model.num_sorter ("cpu"), expand = false }; - list.append_column (cpu_column); + column_view.append_column (cpu_column); var mem_column = new Gtk.ColumnViewColumn (_("Memory"), memory_item_factory) { sorter = model.num_sorter ("memory"), expand = false }; - list.append_column (mem_column); + column_view.append_column (mem_column); var pid_column = new Gtk.ColumnViewColumn (_("PID"), pid_item_factory) { sorter = model.num_sorter ("pid"), expand = false }; - list.append_column (pid_column); + column_view.append_column (pid_column); }