[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