menu-button: show process arguments in process list

This parses the \0 out of the cmdline proc entry and makes them visible
as both in the list of processes and as tooltips when hovered.
This commit is contained in:
Christian Hergert
2016-04-16 18:57:50 -07:00
parent 9e082a257d
commit 57faf5b9e6
4 changed files with 108 additions and 11 deletions

View File

@ -18,6 +18,17 @@
<property name="xalign">0.0</property>
</object>
</child>
<child>
<object class="GtkLabel" id="args_label">
<property name="hexpand">false</property>
<property name="visible">true</property>
<property name="ellipsize">end</property>
<property name="xalign">0.0</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkImage" id="check">
<property name="hexpand">false</property>

View File

@ -16,15 +16,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "sp-process-model-item.h"
#include "sp-proc-source.h"
struct _SpProcessModelItem
{
GObject parent_instance;
GPid pid;
gchar *command_line;
guint is_kernel : 1;
GObject parent_instance;
GPid pid;
gchar *command_line; /* Short version (first field) */
gchar **argv; /* Long version (argv as a strv) */
guint is_kernel : 1;
};
G_DEFINE_TYPE (SpProcessModelItem, sp_process_model_item, G_TYPE_OBJECT)
@ -44,6 +47,7 @@ sp_process_model_item_finalize (GObject *object)
SpProcessModelItem *self = (SpProcessModelItem *)object;
g_clear_pointer (&self->command_line, g_free);
g_clear_pointer (&self->argv, g_strfreev);
G_OBJECT_CLASS (sp_process_model_item_parent_class)->finalize (object);
}
@ -189,3 +193,42 @@ sp_process_model_item_is_kernel (SpProcessModelItem *self)
return self->is_kernel;
}
const gchar const * const *
sp_process_model_item_get_argv (SpProcessModelItem *self)
{
g_autofree gchar *contents = NULL;
g_autofree gchar *path = NULL;
const gchar *pos;
const gchar *endptr;
GPtrArray *ar;
gsize size = 0;
GPid pid;
g_return_val_if_fail (SP_IS_PROCESS_MODEL_ITEM (self), NULL);
if (self->argv)
return (const gchar * const *)self->argv;
if ((pid = sp_process_model_item_get_pid (self)) < 0)
return NULL;
path = g_strdup_printf ("/proc/%u/cmdline", (guint)pid);
if (!g_file_get_contents (path, &contents, &size, NULL))
return NULL;
ar = g_ptr_array_new ();
/* Each parameter is followed by \0 */
for (pos = contents, endptr = contents + size;
pos < endptr;
pos += strlen (pos) + 1)
g_ptr_array_add (ar, g_strdup (pos));
g_ptr_array_add (ar, NULL);
g_clear_pointer (&self->argv, g_strfreev);
self->argv = (gchar **)g_ptr_array_free (ar, FALSE);
return (const gchar * const *)self->argv;
}

View File

@ -27,13 +27,14 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (SpProcessModelItem, sp_process_model_item, SP, PROCESS_MODEL_ITEM, GObject)
SpProcessModelItem *sp_process_model_item_new (GPid pid);
guint sp_process_model_item_hash (SpProcessModelItem *self);
gboolean sp_process_model_item_equal (SpProcessModelItem *self,
SpProcessModelItem *other);
GPid sp_process_model_item_get_pid (SpProcessModelItem *self);
const gchar *sp_process_model_item_get_command_line (SpProcessModelItem *self);
gboolean sp_process_model_item_is_kernel (SpProcessModelItem *self);
SpProcessModelItem *sp_process_model_item_new (GPid pid);
guint sp_process_model_item_hash (SpProcessModelItem *self);
gboolean sp_process_model_item_equal (SpProcessModelItem *self,
SpProcessModelItem *other);
GPid sp_process_model_item_get_pid (SpProcessModelItem *self);
const gchar *sp_process_model_item_get_command_line (SpProcessModelItem *self);
gboolean sp_process_model_item_is_kernel (SpProcessModelItem *self);
const gchar * const *sp_process_model_item_get_argv (SpProcessModelItem *self);
G_END_DECLS

View File

@ -22,6 +22,7 @@ typedef struct
{
SpProcessModelItem *item;
GtkLabel *args_label;
GtkLabel *label;
GtkLabel *pid;
GtkImage *image;
@ -71,12 +72,20 @@ sp_process_model_row_set_item (SpProcessModelRow *self,
const gchar *command_line;
g_auto(GStrv) parts = NULL;
g_autofree gchar *pidstr = NULL;
const gchar * const *argv;
GPid pid;
command_line = sp_process_model_item_get_command_line (item);
parts = g_strsplit (command_line ?: "", "\n", 0);
gtk_label_set_label (priv->label, parts [0]);
if ((NULL != (argv = sp_process_model_item_get_argv (item))) && (argv[0] != NULL))
{
g_autofree gchar *argvstr = g_strjoinv (" ", (gchar **)&argv[1]);
gtk_label_set_label (priv->args_label, argvstr);
}
pid = sp_process_model_item_get_pid (item);
pidstr = g_strdup_printf ("<small>%u</small>", pid);
gtk_label_set_label (priv->pid, pidstr);
@ -111,6 +120,34 @@ sp_process_model_row_set_selected (SpProcessModelRow *self,
}
}
static gboolean
sp_process_model_row_query_tooltip (GtkWidget *widget,
gint x,
gint y,
gboolean keyboard_mode,
GtkTooltip *tooltip)
{
SpProcessModelRow *self = (SpProcessModelRow *)widget;
SpProcessModelRowPrivate *priv = sp_process_model_row_get_instance_private (self);
g_assert (SP_IS_PROCESS_MODEL_ROW (self));
g_assert (GTK_IS_TOOLTIP (tooltip));
if (priv->item != NULL)
{
const gchar * const *argv = sp_process_model_item_get_argv (priv->item);
if (argv != NULL)
{
g_autofree gchar *str = g_strjoinv (" ", (gchar **)argv);
gtk_tooltip_set_text (tooltip, str);
return TRUE;
}
}
return FALSE;
}
static void
sp_process_model_row_finalize (GObject *object)
{
@ -178,6 +215,8 @@ sp_process_model_row_class_init (SpProcessModelRowClass *klass)
object_class->get_property = sp_process_model_row_get_property;
object_class->set_property = sp_process_model_row_set_property;
widget_class->query_tooltip = sp_process_model_row_query_tooltip;
properties [PROP_ITEM] =
g_param_spec_object ("item",
"Item",
@ -196,6 +235,7 @@ sp_process_model_row_class_init (SpProcessModelRowClass *klass)
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/sysprof/ui/sp-process-model-row.ui");
gtk_widget_class_bind_template_child_private (widget_class, SpProcessModelRow, args_label);
gtk_widget_class_bind_template_child_private (widget_class, SpProcessModelRow, image);
gtk_widget_class_bind_template_child_private (widget_class, SpProcessModelRow, label);
gtk_widget_class_bind_template_child_private (widget_class, SpProcessModelRow, pid);
@ -206,4 +246,6 @@ static void
sp_process_model_row_init (SpProcessModelRow *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
gtk_widget_set_has_tooltip (GTK_WIDGET (self), TRUE);
}