diff --git a/src/process-tree-view.c b/src/process-tree-view.c index ffa2230..e91340a 100644 --- a/src/process-tree-view.c +++ b/src/process-tree-view.c @@ -33,9 +33,12 @@ enum COLUMN_PPID, COLUMN_STATE, COLUMN_VSZ, + COLUMN_GROUP_VSZ, COLUMN_RSS, + COLUMN_GROUP_RSS, COLUMN_UID, COLUMN_CPU, + COLUMN_GROUP_CPU, COLUMN_PRIORITY, N_COLUMNS, }; @@ -98,14 +101,34 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) g_object_get (treeview->settings, "show-all-processes", &treeview->show_all_processes_cached, "process-tree", &tree, NULL); /* Create tree view model */ -#ifdef HAVE_WNCK - treeview->model = gtk_list_store_new (XTM_PTV_N_COLUMNS, CAIRO_GOBJECT_TYPE_SURFACE, -#else treeview->model = gtk_list_store_new (XTM_PTV_N_COLUMNS, +#ifdef HAVE_WNCK + CAIRO_GOBJECT_TYPE_SURFACE, /* XTM_PTV_COLUMN_ICON */ #endif - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_UINT64, - G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_FLOAT, G_TYPE_STRING, G_TYPE_INT, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_LONG); + G_TYPE_STRING, /* XTM_PTV_COLUMN_COMMAND */ + G_TYPE_STRING, /* XTM_PTV_COLUMN_COMMAND_RAW */ + G_TYPE_UINT, /* XTM_PTV_COLUMN_PID */ + G_TYPE_UINT, /* XTM_PTV_COLUMN_PPID */ + G_TYPE_STRING, /* XTM_PTV_COLUMN_STATE */ + G_TYPE_UINT64, /* XTM_PTV_COLUMN_VSZ */ + G_TYPE_STRING, /* XTM_PTV_COLUMN_VSZ_STR */ + G_TYPE_UINT64, /* XTM_PTV_COLUMN_GROUP_VSZ */ + G_TYPE_STRING, /* XTM_PTV_COLUMN_GROUP_VSZ_STR */ + G_TYPE_UINT64, /* XTM_PTV_COLUMN_RSS */ + G_TYPE_STRING, /* XTM_PTV_COLUMN_RSS_STR */ + G_TYPE_UINT64, /* XTM_PTV_COLUMN_GROUP_RSS */ + G_TYPE_STRING, /* XTM_PTV_COLUMN_GROUP_RSS_STR */ + G_TYPE_UINT, /* XTM_PTV_COLUMN_UID */ + G_TYPE_STRING, /* XTM_PTV_COLUMN_UID_STR */ + G_TYPE_FLOAT, /* XTM_PTV_COLUMN_CPU */ + G_TYPE_STRING, /* XTM_PTV_COLUMN_CPU_STR */ + G_TYPE_FLOAT, /* XTM_PTV_COLUMN_GROUP_CPU */ + G_TYPE_STRING, /* XTM_PTV_COLUMN_GROUP_CPU_STR */ + G_TYPE_INT, /* XTM_PTV_COLUMN_PRIORITY */ + G_TYPE_STRING, /* XTM_PTV_COLUMN_BACKGROUND */ + G_TYPE_STRING, /* XTM_PTV_COLUMN_FOREGROUND */ + G_TYPE_LONG /* XTM_PTV_COLUMN_TIMESTAMP */ + ); treeview->model_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (treeview->model), NULL); gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (treeview->model_filter), (GtkTreeModelFilterVisibleFunc)visible_func, treeview, NULL); @@ -176,6 +199,14 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview), column, treeview->columns_positions[COLUMN_VSZ]); + g_object_get (treeview->settings, "column-group-vsz", &visible, NULL); + column = gtk_tree_view_column_new_with_attributes (_("Group VSZ"), cell_right_aligned, "text", XTM_PTV_COLUMN_GROUP_VSZ_STR, "cell-background", XTM_PTV_COLUMN_BACKGROUND, "foreground", XTM_PTV_COLUMN_FOREGROUND, NULL); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_GROUP_VSZ)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_GROUP_VSZ)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); + gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview), column, treeview->columns_positions[COLUMN_GROUP_VSZ]); + g_object_get (treeview->settings, "column-rss", &visible, NULL); column = gtk_tree_view_column_new_with_attributes (_("RSS"), cell_right_aligned, "text", XTM_PTV_COLUMN_RSS_STR, "cell-background", XTM_PTV_COLUMN_BACKGROUND, "foreground", XTM_PTV_COLUMN_FOREGROUND, NULL); g_object_set (column, COLUMN_PROPERTIES, NULL); @@ -184,6 +215,14 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview), column, treeview->columns_positions[COLUMN_RSS]); + g_object_get (treeview->settings, "column-group-rss", &visible, NULL); + column = gtk_tree_view_column_new_with_attributes (_("Group RSS"), cell_right_aligned, "text", XTM_PTV_COLUMN_GROUP_RSS_STR, "cell-background", XTM_PTV_COLUMN_BACKGROUND, "foreground", XTM_PTV_COLUMN_FOREGROUND, NULL); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_GROUP_RSS)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_GROUP_RSS)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); + gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview), column, treeview->columns_positions[COLUMN_GROUP_RSS]); + g_object_get (treeview->settings, "column-uid", &visible, NULL); column = gtk_tree_view_column_new_with_attributes (_("UID"), cell_text, "text", XTM_PTV_COLUMN_UID_STR, "cell-background", XTM_PTV_COLUMN_BACKGROUND, "foreground", XTM_PTV_COLUMN_FOREGROUND, NULL); g_object_set (column, COLUMN_PROPERTIES, NULL); @@ -200,6 +239,14 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview), column, treeview->columns_positions[COLUMN_CPU]); + g_object_get (treeview->settings, "column-group-cpu", &visible, NULL); + column = gtk_tree_view_column_new_with_attributes (_("Group CPU"), cell_right_aligned, "text", XTM_PTV_COLUMN_GROUP_CPU_STR, "cell-background", XTM_PTV_COLUMN_BACKGROUND, "foreground", XTM_PTV_COLUMN_FOREGROUND, NULL); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_GROUP_CPU)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_GROUP_CPU)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); + gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview), column, treeview->columns_positions[COLUMN_GROUP_CPU]); + g_object_get (treeview->settings, "column-priority", &visible, NULL); /* TRANSLATORS: “Prio.” is short for Priority, it appears in the tree view header. */ column = gtk_tree_view_column_new_with_attributes (_("Prio."), cell_right_aligned, "text", XTM_PTV_COLUMN_PRIORITY, "cell-background", XTM_PTV_COLUMN_BACKGROUND, "foreground", XTM_PTV_COLUMN_FOREGROUND, NULL); @@ -779,10 +826,16 @@ settings_changed (GObject *object, GParamSpec *pspec, XtmProcessTreeView *treevi column_id = COLUMN_STATE; else if (!g_strcmp0 (pspec->name, "column-vsz")) column_id = COLUMN_VSZ; + else if (!g_strcmp0 (pspec->name, "column-group-vsz")) + column_id = COLUMN_GROUP_VSZ; else if (!g_strcmp0 (pspec->name, "column-rss")) column_id = COLUMN_RSS; + else if (!g_strcmp0 (pspec->name, "column-group-rss")) + column_id = COLUMN_GROUP_RSS; else if (!g_strcmp0 (pspec->name, "column-cpu")) column_id = COLUMN_CPU; + else if (!g_strcmp0 (pspec->name, "column-group-cpu")) + column_id = COLUMN_GROUP_CPU; else if (!g_strcmp0 (pspec->name, "column-priority")) column_id = COLUMN_PRIORITY; diff --git a/src/process-tree-view.h b/src/process-tree-view.h index 4bb232d..a4b7361 100644 --- a/src/process-tree-view.h +++ b/src/process-tree-view.h @@ -30,12 +30,18 @@ enum XTM_PTV_COLUMN_STATE, XTM_PTV_COLUMN_VSZ, XTM_PTV_COLUMN_VSZ_STR, + XTM_PTV_COLUMN_GROUP_VSZ, + XTM_PTV_COLUMN_GROUP_VSZ_STR, XTM_PTV_COLUMN_RSS, XTM_PTV_COLUMN_RSS_STR, + XTM_PTV_COLUMN_GROUP_RSS, + XTM_PTV_COLUMN_GROUP_RSS_STR, XTM_PTV_COLUMN_UID, XTM_PTV_COLUMN_UID_STR, XTM_PTV_COLUMN_CPU, XTM_PTV_COLUMN_CPU_STR, + XTM_PTV_COLUMN_GROUP_CPU, + XTM_PTV_COLUMN_GROUP_CPU_STR, XTM_PTV_COLUMN_PRIORITY, XTM_PTV_COLUMN_BACKGROUND, XTM_PTV_COLUMN_FOREGROUND, diff --git a/src/settings-dialog.c b/src/settings-dialog.c index b812725..273426a 100644 --- a/src/settings-dialog.c +++ b/src/settings-dialog.c @@ -212,9 +212,12 @@ xtm_settings_dialog_new (GtkBuilder *builder, GtkWidget *parent_window) builder_bind_toggle_button (builder, "ppid", settings, "column-ppid"); builder_bind_toggle_button (builder, "state", settings, "column-state"); builder_bind_toggle_button (builder, "vbytes", settings, "column-vsz"); + builder_bind_toggle_button (builder, "group-vbytes", settings, "column-group-vsz"); builder_bind_toggle_button (builder, "rbytes", settings, "column-rss"); + builder_bind_toggle_button (builder, "group-rbytes", settings, "column-group-rss"); builder_bind_toggle_button (builder, "uid", settings, "column-uid"); builder_bind_toggle_button (builder, "cpu", settings, "column-cpu"); + builder_bind_toggle_button (builder, "group-cpu", settings, "column-group-cpu"); builder_bind_toggle_button (builder, "priority", settings, "column-priority"); diff --git a/src/settings-dialog.ui b/src/settings-dialog.ui index 5a3864a..cd5879f 100644 --- a/src/settings-dialog.ui +++ b/src/settings-dialog.ui @@ -410,6 +410,20 @@ 3 + + + Group Virtual Bytes + True + True + False + True + + + False + True + 4 + + Resident Bytes @@ -421,7 +435,21 @@ False True - 4 + 5 + + + + + Group Resident Bytes + True + True + False + True + + + False + True + 6 @@ -435,7 +463,7 @@ False True - 5 + 7 @@ -449,7 +477,21 @@ False True - 6 + 8 + + + + + Group CPU + True + True + False + True + + + False + True + 9 @@ -463,7 +505,7 @@ False True - 7 + 10 diff --git a/src/settings.c b/src/settings.c index 83cf022..3d85818 100644 --- a/src/settings.c +++ b/src/settings.c @@ -50,8 +50,11 @@ enum PROP_COLUMN_PPID, PROP_COLUMN_STATE, PROP_COLUMN_VSZ, + PROP_COLUMN_GROUP_VSZ, PROP_COLUMN_RSS, + PROP_COLUMN_GROUP_RSS, PROP_COLUMN_CPU, + PROP_COLUMN_GROUP_CPU, PROP_COLUMN_PRIORITY, PROP_SORT_COLUMN_ID, PROP_SORT_TYPE, @@ -112,10 +115,16 @@ xtm_settings_class_init (XtmSettingsClass *klass) g_param_spec_boolean ("column-state", "ColumnState", "Show column state", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (class, PROP_COLUMN_VSZ, g_param_spec_boolean ("column-vsz", "ColumnVSZ", "Show column VSZ", FALSE, G_PARAM_READWRITE)); + g_object_class_install_property (class, PROP_COLUMN_GROUP_VSZ, + g_param_spec_boolean ("column-group-vsz", "ColumnGroupVSZ", "Show column Group VSZ", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (class, PROP_COLUMN_RSS, g_param_spec_boolean ("column-rss", "ColumnRSS", "Show column RSS", TRUE, G_PARAM_READWRITE)); + g_object_class_install_property (class, PROP_COLUMN_GROUP_RSS, + g_param_spec_boolean ("column-group-rss", "ColumnGroupRSS", "Show column Group RSS", TRUE, G_PARAM_READWRITE)); g_object_class_install_property (class, PROP_COLUMN_CPU, g_param_spec_boolean ("column-cpu", "ColumnCPU", "Show column CPU", TRUE, G_PARAM_READWRITE)); + g_object_class_install_property (class, PROP_COLUMN_GROUP_CPU, + g_param_spec_boolean ("column-group-cpu", "ColumnGroupCPU", "Show column Group CPU", TRUE, G_PARAM_READWRITE)); g_object_class_install_property (class, PROP_COLUMN_PRIORITY, g_param_spec_boolean ("column-priority", "ColumnPriority", "Show column priority", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (class, PROP_SORT_COLUMN_ID, @@ -208,12 +217,18 @@ xtm_settings_bind_xfconf (XtmSettings *settings, XfconfChannel *channel) G_OBJECT (settings), "column-state"); xfconf_g_property_bind (channel, SETTING_COLUMN_VSZ, G_TYPE_BOOLEAN, G_OBJECT (settings), "column-vsz"); + xfconf_g_property_bind (channel, SETTING_COLUMN_GROUP_VSZ, G_TYPE_BOOLEAN, + G_OBJECT (settings), "column-group-vsz"); xfconf_g_property_bind (channel, SETTING_COLUMN_RSS, G_TYPE_BOOLEAN, G_OBJECT (settings), "column-rss"); + xfconf_g_property_bind (channel, SETTING_COLUMN_GROUP_RSS, G_TYPE_BOOLEAN, + G_OBJECT (settings), "column-group-rss"); xfconf_g_property_bind (channel, SETTING_COLUMN_UID, G_TYPE_BOOLEAN, G_OBJECT (settings), "column-uid"); xfconf_g_property_bind (channel, SETTING_COLUMN_CPU, G_TYPE_BOOLEAN, G_OBJECT (settings), "column-cpu"); + xfconf_g_property_bind (channel, SETTING_COLUMN_GROUP_CPU, G_TYPE_BOOLEAN, + G_OBJECT (settings), "column-group-cpu"); xfconf_g_property_bind (channel, SETTING_COLUMN_PRIORITY, G_TYPE_BOOLEAN, G_OBJECT (settings), "column-priority"); diff --git a/src/settings.h b/src/settings.h index f396ccf..80236d3 100644 --- a/src/settings.h +++ b/src/settings.h @@ -47,9 +47,12 @@ #define SETTING_COLUMN_PPID "/columns/column-ppid" #define SETTING_COLUMN_STATE "/columns/column-state" #define SETTING_COLUMN_VSZ "/columns/column-vsz" +#define SETTING_COLUMN_GROUP_VSZ "/columns/column-group-vsz" #define SETTING_COLUMN_RSS "/columns/column-rss" +#define SETTING_COLUMN_GROUP_RSS "/columns/column-group-rss" #define SETTING_COLUMN_UID "/columns/column-uid" #define SETTING_COLUMN_CPU "/columns/column-cpu" +#define SETTING_COLUMN_GROUP_CPU "/columns/column-group-cpu" #define SETTING_COLUMN_PRIORITY "/columns/column-priority" #define SETTING_COLUMN_SORT_ID "/columns/sort-id" #define SETTING_COLUMN_SORT_TYPE "/columns/sort-type" diff --git a/src/task-manager.c b/src/task-manager.c index 0549b31..fb75ba9 100644 --- a/src/task-manager.c +++ b/src/task-manager.c @@ -237,10 +237,12 @@ model_update_tree_iter (XtmTaskManager *manager, GtkTreeIter *iter, glong timest { GtkTreeModel *model = manager->model; gchar *vsz, *rss, cpu[16]; + gchar *group_vsz, *group_rss, group_cpu[16]; gchar value[14]; glong old_timestamp; - gchar *old_state; - gchar *background, *foreground; + gchar *old_state = NULL; + gchar *background = NULL; + gchar *foreground = NULL; #ifdef HAVE_WNCK App *app = manager->app_manager != NULL ? xtm_app_manager_get_app_from_pid (manager->app_manager, task->pid) : NULL; cairo_surface_t *surface = NULL; @@ -248,13 +250,21 @@ model_update_tree_iter (XtmTaskManager *manager, GtkTreeIter *iter, glong timest vsz = g_format_size_full (task->vsz, G_FORMAT_SIZE_IEC_UNITS); rss = g_format_size_full (task->rss, G_FORMAT_SIZE_IEC_UNITS); + group_vsz = g_format_size_full (task->group_vsz, G_FORMAT_SIZE_IEC_UNITS); + group_rss = g_format_size_full (task->group_rss, G_FORMAT_SIZE_IEC_UNITS); g_snprintf (value, sizeof(value), (more_precision) ? "%.2f" : "%.0f", (task->cpu_user + task->cpu_system)); g_snprintf (cpu, sizeof(cpu), _("%s%%"), value); + g_snprintf (value, sizeof(value), (more_precision) ? "%.2f" : "%.0f", (task->group_cpu_user + task->group_cpu_system)); + g_snprintf (group_cpu, sizeof(group_cpu), _("%s%%"), value); + /* Retrieve values for tweaking background/foreground color and updating content as needed */ - gtk_tree_model_get (model, iter, XTM_PTV_COLUMN_TIMESTAMP, &old_timestamp, XTM_PTV_COLUMN_STATE, &old_state, - XTM_PTV_COLUMN_BACKGROUND, &background, XTM_PTV_COLUMN_FOREGROUND, &foreground, + gtk_tree_model_get (model, iter, + XTM_PTV_COLUMN_TIMESTAMP, &old_timestamp, + XTM_PTV_COLUMN_STATE, &old_state, + XTM_PTV_COLUMN_BACKGROUND, &background, + XTM_PTV_COLUMN_FOREGROUND, &foreground, #ifdef HAVE_WNCK XTM_PTV_COLUMN_ICON, &surface, #endif @@ -313,10 +323,16 @@ model_update_tree_iter (XtmTaskManager *manager, GtkTreeIter *iter, glong timest XTM_PTV_COLUMN_STATE, task->state, XTM_PTV_COLUMN_VSZ, task->vsz, XTM_PTV_COLUMN_VSZ_STR, vsz, + XTM_PTV_COLUMN_GROUP_VSZ, task->group_vsz, + XTM_PTV_COLUMN_GROUP_VSZ_STR, group_vsz, XTM_PTV_COLUMN_RSS, task->rss, XTM_PTV_COLUMN_RSS_STR, rss, + XTM_PTV_COLUMN_GROUP_RSS, task->group_rss, + XTM_PTV_COLUMN_GROUP_RSS_STR, group_rss, XTM_PTV_COLUMN_CPU, (task->cpu_user + task->cpu_system), XTM_PTV_COLUMN_CPU_STR, cpu, + XTM_PTV_COLUMN_GROUP_CPU, (task->group_cpu_user + task->group_cpu_system), + XTM_PTV_COLUMN_GROUP_CPU_STR, group_cpu, XTM_PTV_COLUMN_PRIORITY, task->prio, XTM_PTV_COLUMN_BACKGROUND, background, XTM_PTV_COLUMN_FOREGROUND, foreground, @@ -328,6 +344,8 @@ model_update_tree_iter (XtmTaskManager *manager, GtkTreeIter *iter, glong timest g_free (old_state); g_free (vsz); g_free (rss); + g_free (group_vsz); + g_free (group_rss); } static gboolean @@ -414,6 +432,51 @@ xtm_task_manager_get_task_list (XtmTaskManager *manager) return manager->tasks; } +static void +xtm_task_manager_task_aggregate_children (Task *task, GArray *task_list) +{ + if (task->group_cpu_system != -1) + return; + + task->group_cpu_system = task->cpu_system; + task->group_cpu_user = task->cpu_user; + task->group_vsz = task->vsz; + task->group_rss = task->rss; + + for (guint i = 0; i < task_list->len; ++i) + { + Task *child_task = &g_array_index(task_list, Task, i); + if (child_task->ppid != task->pid) + continue; + + xtm_task_manager_task_aggregate_children(child_task, task_list); + + task->group_cpu_system += child_task->group_cpu_system; + task->group_cpu_user += child_task->group_cpu_user; + task->group_vsz += child_task->group_vsz; + task->group_rss += child_task->group_rss; + } +} + +static void +xtm_task_manager_aggregate_children (GArray *task_list) +{ + for (guint i = 0; i < task_list->len; ++i) + { + Task *task = &g_array_index(task_list, Task, i); + task->group_cpu_system = -1; + task->group_cpu_user = -1; + task->group_vsz = -1; + task->group_rss = -1; + } + + for (guint i = 0; i < task_list->len; ++i) + { + Task *task = &g_array_index(task_list, Task, i); + xtm_task_manager_task_aggregate_children (task, task_list); + } +} + void xtm_task_manager_update_model (XtmTaskManager *manager) { @@ -431,6 +494,7 @@ xtm_task_manager_update_model (XtmTaskManager *manager) /* Retrieve new task list */ array = g_array_new (FALSE, FALSE, sizeof (Task)); get_task_list (array); + xtm_task_manager_aggregate_children (array); /* Remove terminated tasks, mark to remove, update existing. */ valid = gtk_tree_model_get_iter_first (manager->model, &iter); diff --git a/src/task-manager.h b/src/task-manager.h index fa01ac2..fe866f3 100644 --- a/src/task-manager.h +++ b/src/task-manager.h @@ -43,6 +43,12 @@ struct _Task guint64 vsz; guint64 rss; gint prio; + + // Aggregated values + gfloat group_cpu_user; + gfloat group_cpu_system; + guint64 group_vsz; + guint64 group_rss; }; /**