diff --git a/src/process-tree-view.c b/src/process-tree-view.c index 22a5fa5..8e1dc19 100644 --- a/src/process-tree-view.c +++ b/src/process-tree-view.c @@ -86,7 +86,8 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) /* Create tree view model */ treeview->model = gtk_list_store_new (XTM_PTV_N_COLUMNS, 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_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); 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); @@ -104,7 +105,7 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) /* Create tree view columns */ #define COLUMN_PROPERTIES "expand", TRUE, "clickable", TRUE, "reorderable", FALSE, "resizable", TRUE, "visible", TRUE - column = gtk_tree_view_column_new_with_attributes (_("Task"), cell_cmdline, "text", XTM_PTV_COLUMN_COMMAND, NULL); + column = gtk_tree_view_column_new_with_attributes (_("Task"), cell_cmdline, "text", XTM_PTV_COLUMN_COMMAND, "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_COMMAND)); g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_COMMAND)); @@ -114,7 +115,7 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) #undef COLUMN_PROPERTIES #define COLUMN_PROPERTIES "expand", FALSE, "clickable", TRUE, "reorderable", FALSE, "resizable", TRUE, "visible", visible g_object_get (treeview->settings, "column-pid", &visible, NULL); - column = gtk_tree_view_column_new_with_attributes (_("PID"), cell_right_aligned, "text", XTM_PTV_COLUMN_PID, NULL); + column = gtk_tree_view_column_new_with_attributes (_("PID"), cell_right_aligned, "text", XTM_PTV_COLUMN_PID, "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_PID)); g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_PID)); @@ -122,7 +123,7 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); g_object_get (treeview->settings, "column-ppid", &visible, NULL); - column = gtk_tree_view_column_new_with_attributes (_("PPID"), cell_right_aligned, "text", XTM_PTV_COLUMN_PPID, NULL); + column = gtk_tree_view_column_new_with_attributes (_("PPID"), cell_right_aligned, "text", XTM_PTV_COLUMN_PPID, "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_PPID)); g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_PPID)); @@ -130,7 +131,7 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); g_object_get (treeview->settings, "column-state", &visible, NULL); - column = gtk_tree_view_column_new_with_attributes (_("State"), cell_text, "text", XTM_PTV_COLUMN_STATE, NULL); + column = gtk_tree_view_column_new_with_attributes (_("State"), cell_text, "text", XTM_PTV_COLUMN_STATE, "cell-background", XTM_PTV_COLUMN_BACKGROUND, "foreground", XTM_PTV_COLUMN_FOREGROUND, NULL); gtk_tree_view_column_set_min_width (GTK_TREE_VIEW_COLUMN (column), 32); g_object_set (column, COLUMN_PROPERTIES, NULL); g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_STATE)); @@ -139,7 +140,7 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); g_object_get (treeview->settings, "column-vsz", &visible, NULL); - column = gtk_tree_view_column_new_with_attributes (_("VSZ"), cell_right_aligned, "text", XTM_PTV_COLUMN_VSZ_STR, NULL); + column = gtk_tree_view_column_new_with_attributes (_("VSZ"), cell_right_aligned, "text", XTM_PTV_COLUMN_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_VSZ)); g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_VSZ)); @@ -147,7 +148,7 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); 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, 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); g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_RSS)); g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_RSS)); @@ -155,7 +156,7 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); 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, 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); g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_UID)); g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_UID)); @@ -163,7 +164,7 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); g_object_get (treeview->settings, "column-cpu", &visible, NULL); - column = gtk_tree_view_column_new_with_attributes (_("CPU"), cell_right_aligned, "text", XTM_PTV_COLUMN_CPU_STR, NULL); + column = gtk_tree_view_column_new_with_attributes (_("CPU"), cell_right_aligned, "text", XTM_PTV_COLUMN_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_CPU)); g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_CPU)); @@ -172,7 +173,7 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) 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, NULL); + 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); g_object_set (column, COLUMN_PROPERTIES, NULL); g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_PRIORITY)); g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_PRIORITY)); diff --git a/src/process-tree-view.h b/src/process-tree-view.h index c357766..2ab6da5 100644 --- a/src/process-tree-view.h +++ b/src/process-tree-view.h @@ -31,6 +31,9 @@ enum XTM_PTV_COLUMN_CPU, XTM_PTV_COLUMN_CPU_STR, XTM_PTV_COLUMN_PRIORITY, + XTM_PTV_COLUMN_BACKGROUND, + XTM_PTV_COLUMN_FOREGROUND, + XTM_PTV_COLUMN_TIMESTAMP, XTM_PTV_N_COLUMNS, }; diff --git a/src/task-manager.c b/src/task-manager.c index bb55af9..41c13c7 100644 --- a/src/task-manager.c +++ b/src/task-manager.c @@ -25,6 +25,8 @@ #include "process-tree-view.h" /* for the columns of the model */ #include "settings.h" +#define TIMESTAMP_DELTA 4 + static XtmSettings *settings = NULL; @@ -63,10 +65,12 @@ G_DEFINE_TYPE (XtmTaskManager, xtm_task_manager, G_TYPE_OBJECT) static void xtm_task_manager_finalize (GObject *object); static void setting_changed (GObject *object, GParamSpec *pspec, XtmTaskManager *manager); -static void model_add_task (GtkTreeModel *model, Task *task); +static void model_add_task (GtkTreeModel *model, Task *task, glong timestamp); +static void model_remove_task (GtkTreeModel *model, Task *task); static void model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task); static void model_update_task (GtkTreeModel *model, Task *task); -static void model_remove_task (GtkTreeModel *model, Task *task); +static void model_find_tree_iter_for_pid (GtkTreeModel *model, guint pid, GtkTreeIter *iter); +static glong __current_timestamp (); @@ -138,7 +142,7 @@ _xtm_task_manager_set_model (XtmTaskManager *manager, GtkTreeModel *model) } static void -model_add_task (GtkTreeModel *model, Task *task) +model_add_task (GtkTreeModel *model, Task *task, glong timestamp) { GtkTreeIter iter; gchar *cmdline = pretty_cmdline (task->cmdline, task->name); @@ -149,11 +153,22 @@ model_add_task (GtkTreeModel *model, Task *task) XTM_PTV_COLUMN_STATE, task->state, XTM_PTV_COLUMN_UID, task->uid, XTM_PTV_COLUMN_UID_STR, task->uid_name, + XTM_PTV_COLUMN_BACKGROUND, NULL, + XTM_PTV_COLUMN_FOREGROUND, NULL, + XTM_PTV_COLUMN_TIMESTAMP, timestamp, -1); model_update_tree_iter (model, &iter, task); g_free (cmdline); } +static void +model_remove_task (GtkTreeModel *model, Task *task) +{ + GtkTreeIter iter; + model_find_tree_iter_for_pid (model, task->pid, &iter); + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); +} + static void memory_human_size (guint64 mem, gchar *mem_str) { @@ -181,6 +196,8 @@ model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task) { gchar vsz[64], rss[64], cpu[16]; gchar value[14]; + gchar *background = NULL, *foreground = NULL; + glong old_timestamp; memory_human_size (task->vsz, vsz); memory_human_size (task->rss, rss); @@ -195,6 +212,13 @@ model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task) g_free (cmdline); } + gtk_tree_model_get (model, iter, XTM_PTV_COLUMN_TIMESTAMP, &old_timestamp, -1); + if (__current_timestamp () - old_timestamp <= TIMESTAMP_DELTA) + { + background = "#73d216"; + foreground = "#000000"; + } + gtk_list_store_set (GTK_LIST_STORE (model), iter, XTM_PTV_COLUMN_PPID, task->ppid, XTM_PTV_COLUMN_STATE, task->state, @@ -205,9 +229,19 @@ model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task) XTM_PTV_COLUMN_CPU, task->cpu_user + task->cpu_system, XTM_PTV_COLUMN_CPU_STR, cpu, XTM_PTV_COLUMN_PRIORITY, task->prio, + XTM_PTV_COLUMN_BACKGROUND, background, + XTM_PTV_COLUMN_FOREGROUND, foreground, -1); } +static void +model_update_task (GtkTreeModel *model, Task *task) +{ + GtkTreeIter iter; + model_find_tree_iter_for_pid (model, task->pid, &iter); + model_update_tree_iter (model, &iter, task); +} + static void model_find_tree_iter_for_pid (GtkTreeModel *model, guint pid, GtkTreeIter *iter) { @@ -224,20 +258,12 @@ model_find_tree_iter_for_pid (GtkTreeModel *model, guint pid, GtkTreeIter *iter) } } -static void -model_update_task (GtkTreeModel *model, Task *task) +static glong +__current_timestamp () { - GtkTreeIter iter; - model_find_tree_iter_for_pid (model, task->pid, &iter); - model_update_tree_iter (model, &iter, task); -} - -static void -model_remove_task (GtkTreeModel *model, Task *task) -{ - GtkTreeIter iter; - model_find_tree_iter_for_pid (model, task->pid, &iter); - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + GTimeVal time; + g_get_current_time (&time); + return time.tv_sec; } @@ -320,7 +346,7 @@ xtm_task_manager_update_model (XtmTaskManager *manager) for (i = 0; i < manager->tasks->len; i++) { Task *task = &g_array_index (manager->tasks, Task, i); - model_add_task (manager->model, task); + model_add_task (manager->model, task, 0); #if DEBUG g_print ("%5d %5s %15s %.50s\n", task->pid, task->uid_name, task->name, task->cmdline); #endif @@ -394,6 +420,23 @@ xtm_task_manager_update_model (XtmTaskManager *manager) model_update_task (manager->model, tasktmp); } + /* Update colors when timestamp is overlapped but the iter wasn't updated because of previous condition */ + { + GtkTreeIter iter; + glong old_timestamp; + gchar *color = NULL; + model_find_tree_iter_for_pid (manager->model, task->pid, &iter); + gtk_tree_model_get (manager->model, &iter, XTM_PTV_COLUMN_TIMESTAMP, &old_timestamp, XTM_PTV_COLUMN_BACKGROUND, &color, -1); + if (__current_timestamp () - old_timestamp > TIMESTAMP_DELTA && color != NULL) + { +#if DEBUG + g_debug ("Remove color from running PID %d", task->pid); +#endif + model_update_task (manager->model, tasktmp); + } + g_free (color); + } + break; } @@ -402,7 +445,7 @@ xtm_task_manager_update_model (XtmTaskManager *manager) #if DEBUG g_debug ("Add new task %d %s", tasktmp->pid, tasktmp->name); #endif - model_add_task (manager->model, tasktmp); + model_add_task (manager->model, tasktmp, __current_timestamp ()); g_array_append_val (manager->tasks, *tasktmp); } }