[Xfce4-commits] <xfce4-taskmanager:master> Context menu for sending signals and setting priorities
Mike Massonnet
noreply at xfce.org
Sun May 9 01:44:02 CEST 2010
Updating branch refs/heads/master
to 07131a81b3b52a5b856c81e2bc353a6b2d22f8fe (commit)
from e524915ac7ed98dcf0c08084711567e885f6024a (commit)
commit 07131a81b3b52a5b856c81e2bc353a6b2d22f8fe
Author: Mike Massonnet <mmassonnet at xfce.org>
Date: Sun May 9 00:51:46 2010 +0200
Context menu for sending signals and setting priorities
Base signals and priorities are defined inside the task-manager.h file
to be reused as general values inside the interface. The different OS
implementations have to do the conversion from the enumeration to real
values.
src/process-tree-view.c | 140 ++++++++++++++++++++++++++++++++++++++++++++-
src/task-manager-linux.c | 63 +++++++++++++++++++++
src/task-manager.c | 10 ---
src/task-manager.h | 29 +++++++++-
4 files changed, 225 insertions(+), 17 deletions(-)
diff --git a/src/process-tree-view.c b/src/process-tree-view.c
index 450681b..5b0bdcc 100644
--- a/src/process-tree-view.c
+++ b/src/process-tree-view.c
@@ -16,6 +16,7 @@
#include <gtk/gtk.h>
#include "process-tree-view.h"
+#include "task-manager.h"
#include "settings.h"
@@ -34,9 +35,9 @@ struct _XtmProcessTreeView
};
G_DEFINE_TYPE (XtmProcessTreeView, xtm_process_tree_view, GTK_TYPE_TREE_VIEW)
-static gboolean treeview_clicked (XtmProcessTreeView *treeview, GdkEventButton *event);
-static void settings_changed (GObject *object, GParamSpec *pspec, XtmProcessTreeView *treeview);
-static int sort_by_string (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data);
+static gboolean treeview_clicked (XtmProcessTreeView *treeview, GdkEventButton *event);
+static void settings_changed (GObject *object, GParamSpec *pspec, XtmProcessTreeView *treeview);
+static int sort_by_string (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data);
@@ -136,13 +137,144 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview)
* Helper functions
*/
+static void
+cb_send_signal (GtkMenuItem *mi, gpointer user_data)
+{
+ guint pid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (mi), "pid"));
+ gint signal = GPOINTER_TO_INT (user_data);
+
+ if (!send_signal_to_pid (pid, signal))
+ {
+ GtkWidget *dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ _("Error sending signal"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), _("An error was encountered by sending a signal to the PID %d. "
+ "It is likely you don't have the required privileges."), pid);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Task Manager"));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
+}
+
+static void
+cb_set_priority (GtkMenuItem *mi, gpointer user_data)
+{
+ guint pid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (mi), "pid"));
+ gint priority = GPOINTER_TO_INT (user_data);
+
+ if (!set_priority_to_pid (pid, priority))
+ {
+ GtkWidget *dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ _("Error setting priority"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), _("An error was encountered by setting a priority to the PID %d. "
+ "It is likely you don't have the required privileges."), pid);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Task Manager"));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
+}
+
+static GtkWidget *
+build_context_menu (guint pid)
+{
+ GtkWidget *menu, *menu_priority, *mi;
+
+ menu = gtk_menu_new ();
+
+ mi = gtk_menu_item_new_with_label (_("Terminate"));
+ g_object_set_data (G_OBJECT (mi), "pid", GUINT_TO_POINTER (pid));
+ gtk_container_add (GTK_CONTAINER (menu), mi);
+ g_signal_connect (mi, "activate", G_CALLBACK (cb_send_signal), GINT_TO_POINTER (XTM_SIGNAL_TERMINATE));
+
+ // TODO look up task for building menu with either Stop or Continue and in an OS-independent way
+ // if (pid_is_sleeping (pid))
+ mi = gtk_menu_item_new_with_label (_("Stop"));
+ g_object_set_data (G_OBJECT (mi), "pid", GUINT_TO_POINTER (pid));
+ gtk_container_add (GTK_CONTAINER (menu), mi);
+ g_signal_connect (mi, "activate", G_CALLBACK (cb_send_signal), GINT_TO_POINTER (XTM_SIGNAL_STOP));
+
+ mi = gtk_menu_item_new_with_label (_("Continue"));
+ g_object_set_data (G_OBJECT (mi), "pid", GUINT_TO_POINTER (pid));
+ gtk_container_add (GTK_CONTAINER (menu), mi);
+ g_signal_connect (mi, "activate", G_CALLBACK (cb_send_signal), GINT_TO_POINTER (XTM_SIGNAL_CONTINUE));
+
+ mi = gtk_menu_item_new_with_label (_("Kill"));
+ g_object_set_data (G_OBJECT (mi), "pid", GUINT_TO_POINTER (pid));
+ gtk_container_add (GTK_CONTAINER (menu), mi);
+ g_signal_connect (mi, "activate", G_CALLBACK (cb_send_signal), GINT_TO_POINTER (XTM_SIGNAL_KILL));
+
+ menu_priority = gtk_menu_new ();
+
+ mi = gtk_menu_item_new_with_label (_("Very low"));
+ g_object_set_data (G_OBJECT (mi), "pid", GUINT_TO_POINTER (pid));
+ gtk_container_add (GTK_CONTAINER (menu_priority), mi);
+ g_signal_connect (mi, "activate", G_CALLBACK (cb_set_priority), GINT_TO_POINTER (XTM_PRIORITY_VERY_LOW));
+
+ mi = gtk_menu_item_new_with_label (_("Low"));
+ g_object_set_data (G_OBJECT (mi), "pid", GUINT_TO_POINTER (pid));
+ gtk_container_add (GTK_CONTAINER (menu_priority), mi);
+ g_signal_connect (mi, "activate", G_CALLBACK (cb_set_priority), GINT_TO_POINTER (XTM_PRIORITY_LOW));
+
+ mi = gtk_menu_item_new_with_label (_("Normal"));
+ g_object_set_data (G_OBJECT (mi), "pid", GUINT_TO_POINTER (pid));
+ gtk_container_add (GTK_CONTAINER (menu_priority), mi);
+ g_signal_connect (mi, "activate", G_CALLBACK (cb_set_priority), GINT_TO_POINTER (XTM_PRIORITY_NORMAL));
+
+ mi = gtk_menu_item_new_with_label (_("High"));
+ g_object_set_data (G_OBJECT (mi), "pid", GUINT_TO_POINTER (pid));
+ gtk_container_add (GTK_CONTAINER (menu_priority), mi);
+ g_signal_connect (mi, "activate", G_CALLBACK (cb_set_priority), GINT_TO_POINTER (XTM_PRIORITY_HIGH));
+
+ mi = gtk_menu_item_new_with_label (_("Very high"));
+ g_object_set_data (G_OBJECT (mi), "pid", GUINT_TO_POINTER (pid));
+ gtk_container_add (GTK_CONTAINER (menu_priority), mi);
+ g_signal_connect (mi, "activate", G_CALLBACK (cb_set_priority), GINT_TO_POINTER (XTM_PRIORITY_VERY_HIGH));
+
+ mi = gtk_menu_item_new_with_label (_("Priority"));
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu_priority);
+ gtk_container_add (GTK_CONTAINER (menu), mi);
+
+ gtk_widget_show_all (menu);
+
+ return menu;
+}
+
static gboolean
treeview_clicked (XtmProcessTreeView *treeview, GdkEventButton *event)
{
+ static GtkWidget *menu = NULL;
+ guint pid;
+
if (event->button != 3)
return FALSE;
- g_debug ("popup menu");
+ if (menu != NULL)
+ gtk_widget_destroy (menu);
+
+ {
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ model = GTK_TREE_MODEL (treeview->model);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+ gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview), (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL);
+
+ if (path == NULL)
+ return;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, XTM_PTV_COLUMN_PID, &pid, -1);
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_path_free (path);
+
+#if DEBUG
+ g_debug ("Found iter with pid %d", pid);
+#endif
+ }
+
+ menu = build_context_menu (pid);
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time);
return TRUE;
}
diff --git a/src/task-manager-linux.c b/src/task-manager-linux.c
index 6a5e2c0..3d61ab7 100644
--- a/src/task-manager-linux.c
+++ b/src/task-manager-linux.c
@@ -14,6 +14,8 @@
#include <pwd.h>
#include <unistd.h>
#include <string.h>
+#include <signal.h>
+#include <sys/resource.h>
#include <glib.h>
@@ -305,3 +307,64 @@ get_task_list (GArray *task_list)
return TRUE;
}
+gboolean
+pid_is_sleeping (guint pid)
+{
+ return TRUE;
+}
+
+gboolean
+send_signal_to_pid (guint pid, gint signal)
+{
+ gint sig;
+ gint res;
+ switch (signal)
+ {
+ case XTM_SIGNAL_TERMINATE:
+ sig = SIGTERM;
+ break;
+ case XTM_SIGNAL_STOP:
+ sig = SIGSTOP;
+ break;
+ case XTM_SIGNAL_CONTINUE:
+ sig = SIGCONT;
+ break;
+ case XTM_SIGNAL_KILL:
+ sig = SIGKILL;
+ break;
+ default:
+ return TRUE;
+ }
+ res = kill (pid, sig);
+ return (res == 0) ? TRUE : FALSE;
+}
+
+gboolean
+set_priority_to_pid (guint pid, gint priority)
+{
+ gint prio;
+ gint res;
+ switch (priority)
+ {
+ case XTM_PRIORITY_VERY_LOW:
+ prio = 15;
+ break;
+ case XTM_PRIORITY_LOW:
+ prio = 5;
+ break;
+ case XTM_PRIORITY_NORMAL:
+ prio = 0;
+ break;
+ case XTM_PRIORITY_HIGH:
+ prio = -5;
+ break;
+ case XTM_PRIORITY_VERY_HIGH:
+ prio = -15;
+ break;
+ default:
+ return TRUE;
+ }
+ res = setpriority (PRIO_PROCESS, pid, prio);
+ return (res == 0) ? TRUE : FALSE;
+}
+
diff --git a/src/task-manager.c b/src/task-manager.c
index e849b34..b481c83 100644
--- a/src/task-manager.c
+++ b/src/task-manager.c
@@ -352,13 +352,3 @@ xtm_task_manager_update_model (XtmTaskManager *manager)
return;
}
-void
-xtm_task_manager_send_signal_to_pid (XtmTaskManager *manager)
-{
-}
-
-void
-xtm_task_manager_set_priority_to_pid (XtmTaskManager *manager)
-{
-}
-
diff --git a/src/task-manager.h b/src/task-manager.h
index 01ca19c..b82eaea 100644
--- a/src/task-manager.h
+++ b/src/task-manager.h
@@ -15,6 +15,7 @@
#endif
#include <glib-object.h>
+#include <gtk/gtk.h>
/**
* Task struct used as elements of a task list GArray.
@@ -38,14 +39,36 @@ struct _Task
};
/**
+ * Enumerations of virtual values between the interface and the OS implementation.
+ */
+
+enum
+{
+ XTM_SIGNAL_TERMINATE = 0,
+ XTM_SIGNAL_STOP,
+ XTM_SIGNAL_CONTINUE,
+ XTM_SIGNAL_KILL,
+};
+
+enum
+{
+ XTM_PRIORITY_VERY_LOW = 0,
+ XTM_PRIORITY_LOW,
+ XTM_PRIORITY_NORMAL,
+ XTM_PRIORITY_HIGH,
+ XTM_PRIORITY_VERY_HIGH,
+};
+
+/**
* OS specific implementation.
*/
gboolean get_memory_usage (guint64 *memory_total, guint64 *memory_free, guint64 *memory_cache, guint64 *memory_buffers, guint64 *swap_total, guint64 *swap_free);
gboolean get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system);
gboolean get_task_list (GArray *task_list);
-//void send_signal_to_task (gint task_id, gint signal);
-//void set_priority_to_task (gint task_id, gint prio);
+gboolean pid_is_sleeping (guint pid);
+gboolean send_signal_to_pid (guint pid, gint signal);
+gboolean set_priority_to_pid (guint pid, gint priority);
/**
* GObject class used to update the graphical widgets.
@@ -61,7 +84,7 @@ gboolean get_task_list (GArray *task_list);
typedef struct _XtmTaskManager XtmTaskManager;
GType xtm_task_manager_get_type (void);
-XtmTaskManager * xtm_task_manager_new ();
+XtmTaskManager * xtm_task_manager_new (GtkTreeModel *model);
const gchar * xtm_task_manager_get_username (XtmTaskManager *manager);
const gchar * xtm_task_manager_get_hostname (XtmTaskManager *manager);
void xtm_task_manager_get_system_info (XtmTaskManager *manager, guint *num_processes, gfloat *cpu, gfloat *memory, gfloat *swap);
More information about the Xfce4-commits
mailing list