diff --git a/modules/inspector/signals-list.c b/modules/inspector/signals-list.c
index 276b4e65ae..e132a7df13 100644
--- a/modules/inspector/signals-list.c
+++ b/modules/inspector/signals-list.c
@@ -21,26 +21,30 @@
enum
{
- COLUMN_ENABLED,
COLUMN_NAME,
COLUMN_CLASS,
- COLUMN_CONNECTED
+ COLUMN_CONNECTED,
+ COLUMN_COUNT,
+ COLUMN_NO_HOOKS,
+ COLUMN_SIGNAL_ID,
+ COLUMN_HOOK_ID
};
struct _GtkInspectorSignalsListPrivate
{
GtkWidget *view;
GtkListStore *model;
+ GtkTextBuffer *text;
+ GtkWidget *log_win;
+ GtkWidget *trace_button;
+ GtkTreeViewColumn *count_column;
+ GtkCellRenderer *count_renderer;
+ GObject *object;
+ GHashTable *iters;
+ gboolean tracing;
};
-G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorSignalsList, gtk_inspector_signals_list, GTK_TYPE_BOX)
-
-static void
-gtk_inspector_signals_list_init (GtkInspectorSignalsList *sl)
-{
- sl->priv = gtk_inspector_signals_list_get_instance_private (sl);
- gtk_widget_init_template (GTK_WIDGET (sl));
-}
+G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorSignalsList, gtk_inspector_signals_list, GTK_TYPE_PANED)
static GType *
get_types (GObject *object, guint *length)
@@ -92,11 +96,16 @@ add_signals (GtkInspectorSignalsList *sl,
has_handler = g_signal_has_handler_pending (object, ids[i], 0, TRUE);
gtk_list_store_append (sl->priv->model, &iter);
gtk_list_store_set (sl->priv->model, &iter,
- COLUMN_ENABLED, FALSE,
COLUMN_NAME, query.signal_name,
COLUMN_CLASS, g_type_name (type),
COLUMN_CONNECTED, has_handler ? _("Yes") : "",
+ COLUMN_COUNT, 0,
+ COLUMN_NO_HOOKS, (query.signal_flags & G_SIGNAL_NO_HOOKS) != 0,
+ COLUMN_SIGNAL_ID, ids[i],
+ COLUMN_HOOK_ID, 0,
-1);
+ g_hash_table_insert (sl->priv->iters,
+ GINT_TO_POINTER (ids[i]), gtk_tree_iter_copy (&iter));
}
g_free (ids);
}
@@ -115,13 +124,200 @@ read_signals_from_object (GtkInspectorSignalsList *sl,
g_free (types);
}
+static void stop_tracing (GtkInspectorSignalsList *sl);
+
void
gtk_inspector_signals_list_set_object (GtkInspectorSignalsList *sl,
GObject *object)
{
- gtk_list_store_clear (sl->priv->model);
+ if (sl->priv->object == object)
+ return;
- read_signals_from_object (sl, object);
+ stop_tracing (sl);
+ gtk_list_store_clear (sl->priv->model);
+ g_hash_table_remove_all (sl->priv->iters);
+
+ sl->priv->object = object;
+
+ if (object)
+ read_signals_from_object (sl, object);
+}
+
+static void
+render_count (GtkTreeViewColumn *column,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ gint count;
+ gboolean no_hooks;
+ gchar text[100];
+
+ gtk_tree_model_get (model, iter,
+ COLUMN_COUNT, &count,
+ COLUMN_NO_HOOKS, &no_hooks,
+ -1);
+ if (no_hooks)
+ {
+ g_object_set (renderer, "markup", "(untraceable)", NULL);
+ }
+ else if (count != 0)
+ {
+ g_snprintf (text, 100, "%d", count);
+ g_object_set (renderer, "text", text, NULL);
+ }
+ else
+ g_object_set (renderer, "text", "", NULL);
+}
+
+static void
+gtk_inspector_signals_list_init (GtkInspectorSignalsList *sl)
+{
+ sl->priv = gtk_inspector_signals_list_get_instance_private (sl);
+ gtk_widget_init_template (GTK_WIDGET (sl));
+
+ gtk_tree_view_column_set_cell_data_func (sl->priv->count_column,
+ sl->priv->count_renderer,
+ render_count,
+ NULL, NULL);
+
+ sl->priv->iters = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ NULL,
+ (GDestroyNotify) gtk_tree_iter_free);
+}
+
+static gboolean
+trace_hook (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GtkInspectorSignalsList *sl = data;
+ GObject *object;
+
+ object = g_value_get_object (param_values);
+
+ if (object == sl->priv->object)
+ {
+ gint count;
+ GtkTreeIter *iter;
+
+ iter = (GtkTreeIter *)g_hash_table_lookup (sl->priv->iters, GINT_TO_POINTER (ihint->signal_id));
+
+ gtk_tree_model_get (GTK_TREE_MODEL (sl->priv->model), iter, COLUMN_COUNT, &count, -1);
+ gtk_list_store_set (sl->priv->model, iter, COLUMN_COUNT, count + 1, -1);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+start_tracing_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ GtkInspectorSignalsList *sl = data;
+ guint signal_id;
+ gulong hook_id;
+ gboolean no_hooks;
+
+ gtk_tree_model_get (model, iter,
+ COLUMN_SIGNAL_ID, &signal_id,
+ COLUMN_HOOK_ID, &hook_id,
+ COLUMN_NO_HOOKS, &no_hooks,
+ -1);
+
+ g_assert (signal_id != 0);
+ g_assert (hook_id == 0);
+
+ if (!no_hooks)
+ {
+ hook_id = g_signal_add_emission_hook (signal_id, 0, trace_hook, sl, NULL);
+
+ gtk_list_store_set (GTK_LIST_STORE (model), iter,
+ COLUMN_COUNT, 0,
+ COLUMN_HOOK_ID, hook_id,
+ -1);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+stop_tracing_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ guint signal_id;
+ gulong hook_id;
+
+ gtk_tree_model_get (model, iter,
+ COLUMN_SIGNAL_ID, &signal_id,
+ COLUMN_HOOK_ID, &hook_id,
+ -1);
+
+ g_assert (signal_id != 0);
+
+ if (hook_id != 0)
+ {
+ g_signal_remove_emission_hook (signal_id, hook_id);
+ gtk_list_store_set (GTK_LIST_STORE (model), iter,
+ COLUMN_HOOK_ID, 0,
+ -1);
+ }
+
+ return FALSE;
+}
+
+static void
+start_tracing (GtkInspectorSignalsList *sl)
+{
+ sl->priv->tracing = TRUE;
+ gtk_tree_model_foreach (GTK_TREE_MODEL (sl->priv->model), start_tracing_cb, sl);
+}
+
+static void
+stop_tracing (GtkInspectorSignalsList *sl)
+{
+ sl->priv->tracing = FALSE;
+ gtk_tree_model_foreach (GTK_TREE_MODEL (sl->priv->model), stop_tracing_cb, sl);
+ gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (sl->priv->trace_button), FALSE);
+}
+
+static void
+toggle_tracing (GtkToggleToolButton *button, GtkInspectorSignalsList *sl)
+{
+ if (gtk_toggle_tool_button_get_active (button) == sl->priv->tracing)
+ return;
+
+ //gtk_widget_show (sl->priv->log_win);
+
+ if (gtk_toggle_tool_button_get_active (button))
+ start_tracing (sl);
+ else
+ stop_tracing (sl);
+}
+
+static gboolean
+clear_log_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ gtk_list_store_set (GTK_LIST_STORE (model), iter, COLUMN_COUNT, 0, -1);
+ return FALSE;
+}
+
+static void
+clear_log (GtkToolButton *button, GtkInspectorSignalsList *sl)
+{
+ gtk_text_buffer_set_text (sl->priv->text, "", -1);
+
+ gtk_tree_model_foreach (GTK_TREE_MODEL (sl->priv->model), clear_log_cb, sl);
}
static void
@@ -132,6 +328,13 @@ gtk_inspector_signals_list_class_init (GtkInspectorSignalsListClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/inspector/signals-list.ui");
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorSignalsList, view);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorSignalsList, model);
+ gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorSignalsList, text);
+ gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorSignalsList, log_win);
+ gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorSignalsList, count_column);
+ gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorSignalsList, count_renderer);
+ gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorSignalsList, trace_button);
+ gtk_widget_class_bind_template_callback (widget_class, toggle_tracing);
+ gtk_widget_class_bind_template_callback (widget_class, clear_log);
}
GtkWidget *
diff --git a/modules/inspector/signals-list.h b/modules/inspector/signals-list.h
index 4332bd220c..9d90f561e5 100644
--- a/modules/inspector/signals-list.h
+++ b/modules/inspector/signals-list.h
@@ -32,13 +32,13 @@ typedef struct _GtkInspectorSignalsListPrivate GtkInspectorSignalsListPrivate;
typedef struct _GtkInspectorSignalsList
{
- GtkBox parent;
+ GtkPaned parent;
GtkInspectorSignalsListPrivate *priv;
} GtkInspectorSignalsList;
typedef struct _GtkInspectorSignalsListClass
{
- GtkBoxClass parent;
+ GtkPanedClass parent;
} GtkInspectorSignalsListClass;
G_BEGIN_DECLS
diff --git a/modules/inspector/signals-list.ui b/modules/inspector/signals-list.ui
index 8aae0caab0..a7844420b1 100644
--- a/modules/inspector/signals-list.ui
+++ b/modules/inspector/signals-list.ui
@@ -2,64 +2,122 @@
-
+
+
vertical
-
+
+
True
automatic
always
in
-
+
True
- model
-
-
- Name
-
-
- 0.8
-
-
- 1
-
-
-
-
-
-
- Defined At
-
-
- 0.8
-
-
- 2
-
-
-
-
-
-
- Connected
-
-
- 0.8
-
-
- 3
-
-
-
-
+ text
+ False