[sysprof] menu-button: show process arguments in process list



commit 57faf5b9e61fb137f3cd36f16bba097b9c715b91
Author: Christian Hergert <christian hergert me>
Date:   Sat Apr 16 18:57:50 2016 -0700

    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.

 lib/resources/ui/sp-process-model-row.ui |   11 ++++++
 lib/sp-process-model-item.c              |   51 +++++++++++++++++++++++++++--
 lib/sp-process-model-item.h              |   15 +++++----
 lib/sp-process-model-row.c               |   42 ++++++++++++++++++++++++
 4 files changed, 108 insertions(+), 11 deletions(-)
---
diff --git a/lib/resources/ui/sp-process-model-row.ui b/lib/resources/ui/sp-process-model-row.ui
index 8f65dd8..48a4c93 100644
--- a/lib/resources/ui/sp-process-model-row.ui
+++ b/lib/resources/ui/sp-process-model-row.ui
@@ -19,6 +19,17 @@
           </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>
             <property name="icon-name">object-select-symbolic</property>
diff --git a/lib/sp-process-model-item.c b/lib/sp-process-model-item.c
index 7067dc6..73fe3c4 100644
--- a/lib/sp-process-model-item.c
+++ b/lib/sp-process-model-item.c
@@ -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;
+}
+
diff --git a/lib/sp-process-model-item.h b/lib/sp-process-model-item.h
index 850a741..3db0dfa 100644
--- a/lib/sp-process-model-item.h
+++ b/lib/sp-process-model-item.h
@@ -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
 
diff --git a/lib/sp-process-model-row.c b/lib/sp-process-model-row.c
index b8e6e77..a5b005f 100644
--- a/lib/sp-process-model-row.c
+++ b/lib/sp-process-model-row.c
@@ -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);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]