Files
sysprof/src/libsysprof-gtk/sysprof-callgraph-view.c
Christian Hergert ea8befb624 sysprof: move traceables utility into SyprofSamplesSection
This gets it out of the callgrpah view so that it can live in the sidebar
area of a AdwOverlayNavigationView.

We allow the utility area to control the entire view (including the
toolbarview) so that we don't have to bind extra properties for titles,
and other random things.
2023-07-12 15:48:28 -07:00

742 lines
27 KiB
C

/* sysprof-callgraph-view.c
*
* Copyright 2023 Christian Hergert <chergert@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "config.h"
#include <libpanel.h>
#include "libsysprof-gtk-resources.h"
#include "sysprof-callgraph-view-private.h"
#include "sysprof-symbol-label-private.h"
enum {
PROP_0,
PROP_CALLGRAPH,
PROP_DOCUMENT,
PROP_HIDE_SYSTEM_LIBRARIES,
PROP_INCLUDE_THREADS,
PROP_TRACEABLES,
PROP_UTILITY_TRACEABLES,
N_PROPS
};
static void buildable_iface_init (GtkBuildableIface *iface);
static GListModel *sysprof_callgraph_view_create_model_func (gpointer item,
gpointer user_data);
static void descendants_selection_changed_cb (SysprofCallgraphView *self,
guint position,
guint n_items,
GtkSingleSelection *single);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (SysprofCallgraphView, sysprof_callgraph_view, GTK_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_iface_init))
static GParamSpec *properties [N_PROPS];
static void
sysprof_callgraph_view_set_utility_traceables (SysprofCallgraphView *self,
GListModel *model)
{
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
g_assert (!model || G_IS_LIST_MODEL (model));
if (g_set_object (&self->utility_traceables, model))
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UTILITY_TRACEABLES]);
}
static void
sysprof_callgraph_view_set_descendants (SysprofCallgraphView *self,
GListModel *model)
{
g_autoptr(GtkTreeListRowSorter) descendants_sorter = NULL;
g_autoptr(GtkSingleSelection) descendants_selection = NULL;
g_autoptr(GtkSortListModel) descendants_sort_model = NULL;
g_autoptr(GtkTreeListModel) descendants_tree = NULL;
g_autoptr(GtkTreeListRow) descendants_first = NULL;
GtkSorter *column_sorter;
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
g_assert (G_IS_LIST_MODEL (model));
column_sorter = gtk_column_view_get_sorter (self->descendants_column_view);
descendants_tree = gtk_tree_list_model_new (g_object_ref (model),
FALSE, FALSE,
sysprof_callgraph_view_create_model_func,
NULL, NULL);
descendants_sorter = gtk_tree_list_row_sorter_new (g_object_ref (column_sorter));
descendants_sort_model = gtk_sort_list_model_new (g_object_ref (G_LIST_MODEL (descendants_tree)),
g_object_ref (GTK_SORTER (descendants_sorter)));
descendants_selection = gtk_single_selection_new (g_object_ref (G_LIST_MODEL (descendants_sort_model)));
g_signal_connect_object (descendants_selection,
"selection-changed",
G_CALLBACK (descendants_selection_changed_cb),
self,
G_CONNECT_SWAPPED);
gtk_column_view_set_model (self->descendants_column_view,
GTK_SELECTION_MODEL (descendants_selection));
if ((descendants_first = gtk_tree_list_model_get_row (descendants_tree, 0)))
gtk_tree_list_row_set_expanded (descendants_first, TRUE);
}
static void
sysprof_callgraph_view_descendants_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
SysprofCallgraph *callgraph = (SysprofCallgraph *)object;
g_autoptr(SysprofCallgraphView) self = user_data;
g_autoptr(GListModel) model = NULL;
g_autoptr(GError) error = NULL;
g_assert (SYSPROF_IS_CALLGRAPH (callgraph));
g_assert (G_IS_ASYNC_RESULT (result));
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
if ((model = sysprof_callgraph_descendants_finish (callgraph, result, &error)))
sysprof_callgraph_view_set_descendants (self, model);
}
static void
callers_selection_changed_cb (SysprofCallgraphView *self,
guint position,
guint n_items,
GtkSingleSelection *single)
{
GObject *object;
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
g_assert (GTK_IS_SINGLE_SELECTION (single));
if ((object = gtk_single_selection_get_selected_item (single)))
{
SysprofCallgraphSymbol *sym = SYSPROF_CALLGRAPH_SYMBOL (object);
SysprofSymbol *symbol = sysprof_callgraph_symbol_get_symbol (sym);
g_debug ("Select %s as root callgraph node",
sysprof_symbol_get_name (symbol));
sysprof_callgraph_descendants_async (self->callgraph,
symbol,
NULL,
sysprof_callgraph_view_descendants_cb,
g_object_ref (self));
}
}
static void
sysprof_callgraph_view_list_traceables_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
SysprofCallgraphFrame *frame = (SysprofCallgraphFrame *)object;
g_autoptr(SysprofCallgraphView) self = user_data;
g_autoptr(GListModel) model = NULL;
g_autoptr(GError) error = NULL;
g_assert (SYSPROF_IS_CALLGRAPH_FRAME (frame));
g_assert (G_IS_ASYNC_RESULT (result));
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
model = sysprof_callgraph_frame_list_traceables_finish (frame, result, &error);
sysprof_callgraph_view_set_utility_traceables (self, model);
}
static void
descendants_selection_changed_cb (SysprofCallgraphView *self,
guint position,
guint n_items,
GtkSingleSelection *single)
{
g_autoptr(GObject) item = NULL;
GObject *object;
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
g_assert (GTK_IS_SINGLE_SELECTION (single));
sysprof_callgraph_view_set_utility_traceables (self, NULL);
if ((object = gtk_single_selection_get_selected_item (single)) &&
GTK_IS_TREE_LIST_ROW (object) &&
(item = gtk_tree_list_row_get_item (GTK_TREE_LIST_ROW (object))) &&
SYSPROF_IS_CALLGRAPH_FRAME (item))
sysprof_callgraph_frame_list_traceables_async (SYSPROF_CALLGRAPH_FRAME (item),
NULL,
sysprof_callgraph_view_list_traceables_cb,
g_object_ref (self));
}
static void
functions_selection_changed_cb (SysprofCallgraphView *self,
guint position,
guint n_items,
GtkSingleSelection *single)
{
GObject *object;
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
g_assert (GTK_IS_SINGLE_SELECTION (single));
if ((object = gtk_single_selection_get_selected_item (single)))
{
SysprofCallgraphSymbol *sym = SYSPROF_CALLGRAPH_SYMBOL (object);
SysprofSymbol *symbol = sysprof_callgraph_symbol_get_symbol (sym);
g_autoptr(GtkSortListModel) callers_sort_model = NULL;
g_autoptr(GtkSingleSelection) callers_selection = NULL;
g_autoptr(GListModel) callers = sysprof_callgraph_list_callers (self->callgraph, symbol);
GtkSorter *column_sorter;
column_sorter = gtk_column_view_get_sorter (self->callers_column_view);
callers_sort_model = gtk_sort_list_model_new (g_object_ref (callers),
g_object_ref (column_sorter));
callers_selection = gtk_single_selection_new (g_object_ref (G_LIST_MODEL (callers_sort_model)));
gtk_single_selection_set_autoselect (callers_selection, FALSE);
gtk_single_selection_set_selected (callers_selection, GTK_INVALID_LIST_POSITION);
g_signal_connect_object (callers_selection,
"selection-changed",
G_CALLBACK (callers_selection_changed_cb),
self,
G_CONNECT_SWAPPED);
gtk_column_view_set_model (self->callers_column_view,
GTK_SELECTION_MODEL (callers_selection));
switch (sysprof_symbol_get_kind (symbol))
{
case SYSPROF_SYMBOL_KIND_ROOT:
sysprof_callgraph_view_set_descendants (self, G_LIST_MODEL (self->callgraph));
break;
default:
case SYSPROF_SYMBOL_KIND_PROCESS:
case SYSPROF_SYMBOL_KIND_THREAD:
case SYSPROF_SYMBOL_KIND_CONTEXT_SWITCH:
case SYSPROF_SYMBOL_KIND_UNWINDABLE:
case SYSPROF_SYMBOL_KIND_USER:
case SYSPROF_SYMBOL_KIND_KERNEL:
sysprof_callgraph_descendants_async (self->callgraph,
symbol,
NULL,
sysprof_callgraph_view_descendants_cb,
g_object_ref (self));
break;
}
}
else
{
gtk_column_view_set_model (self->callers_column_view, NULL);
}
}
#if 0
static void
traceable_activate_cb (SysprofCallgraphView *self,
guint position,
GtkColumnView *column_view)
{
g_autoptr(SysprofSymbol) symbol = NULL;
GtkSelectionModel *model;
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
g_assert (GTK_IS_COLUMN_VIEW (column_view));
if ((model = gtk_column_view_get_model (column_view)) &&
(symbol = g_list_model_get_item (G_LIST_MODEL (model), position)))
{
GListModel *functions = G_LIST_MODEL (gtk_column_view_get_model (self->functions_column_view));
guint n_items = g_list_model_get_n_items (functions);
for (guint i = 0; i < n_items; i++)
{
g_autoptr(SysprofCallgraphSymbol) callsym = g_list_model_get_item (functions, i);
SysprofSymbol *cur = sysprof_callgraph_symbol_get_symbol (callsym);
if (sysprof_symbol_equal (cur, symbol))
{
GtkListView *list_view = NULL;
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self->functions_column_view));
child != NULL;
child = gtk_widget_get_next_sibling (child))
{
if (GTK_IS_LIST_VIEW (child))
{
list_view = GTK_LIST_VIEW (child);
break;
}
}
gtk_selection_model_select_item (GTK_SELECTION_MODEL (functions), i, TRUE);
if (list_view != NULL)
gtk_widget_activate_action (GTK_WIDGET (list_view), "list.scroll-to-item", "u", i);
break;
}
}
}
}
#endif
static void
sysprof_callgraph_view_dispose (GObject *object)
{
SysprofCallgraphView *self = (SysprofCallgraphView *)object;
g_clear_handle_id (&self->reload_source, g_source_remove);
g_clear_pointer (&self->paned, gtk_widget_unparent);
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
g_clear_object (&self->callgraph);
g_clear_object (&self->document);
g_clear_object (&self->traceables);
g_clear_object (&self->utility_traceables);
G_OBJECT_CLASS (sysprof_callgraph_view_parent_class)->dispose (object);
}
static void
sysprof_callgraph_view_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
SysprofCallgraphView *self = SYSPROF_CALLGRAPH_VIEW (object);
switch (prop_id)
{
case PROP_CALLGRAPH:
g_value_set_object (value, sysprof_callgraph_view_get_callgraph (self));
break;
case PROP_DOCUMENT:
g_value_set_object (value, sysprof_callgraph_view_get_document (self));
break;
case PROP_HIDE_SYSTEM_LIBRARIES:
g_value_set_boolean (value, sysprof_callgraph_view_get_hide_system_libraries (self));
break;
case PROP_INCLUDE_THREADS:
g_value_set_boolean (value, sysprof_callgraph_view_get_include_threads (self));
break;
case PROP_TRACEABLES:
g_value_set_object (value, sysprof_callgraph_view_get_traceables (self));
break;
case PROP_UTILITY_TRACEABLES:
g_value_set_object (value, self->utility_traceables);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sysprof_callgraph_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
SysprofCallgraphView *self = SYSPROF_CALLGRAPH_VIEW (object);
switch (prop_id)
{
case PROP_DOCUMENT:
sysprof_callgraph_view_set_document (self, g_value_get_object (value));
break;
case PROP_HIDE_SYSTEM_LIBRARIES:
sysprof_callgraph_view_set_hide_system_libraries (self, g_value_get_boolean (value));
break;
case PROP_INCLUDE_THREADS:
sysprof_callgraph_view_set_include_threads (self, g_value_get_boolean (value));
break;
case PROP_TRACEABLES:
sysprof_callgraph_view_set_traceables (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sysprof_callgraph_view_class_init (SysprofCallgraphViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = sysprof_callgraph_view_dispose;
object_class->get_property = sysprof_callgraph_view_get_property;
object_class->set_property = sysprof_callgraph_view_set_property;
properties[PROP_CALLGRAPH] =
g_param_spec_object ("callgraph", NULL, NULL,
SYSPROF_TYPE_CALLGRAPH,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
properties[PROP_DOCUMENT] =
g_param_spec_object ("document", NULL, NULL,
SYSPROF_TYPE_DOCUMENT,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties[PROP_HIDE_SYSTEM_LIBRARIES] =
g_param_spec_boolean ("hide-system-libraries", NULL, NULL,
FALSE,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties[PROP_INCLUDE_THREADS] =
g_param_spec_boolean ("include-threads", NULL, NULL,
FALSE,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties[PROP_TRACEABLES] =
g_param_spec_object ("traceables", NULL, NULL,
G_TYPE_LIST_MODEL,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties[PROP_UTILITY_TRACEABLES] =
g_param_spec_object ("utility-traceables", NULL, NULL,
G_TYPE_LIST_MODEL,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
gtk_widget_class_set_template_from_resource (widget_class, "/libsysprof-gtk/sysprof-callgraph-view.ui");
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_css_name (widget_class, "callgraphview");
gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, callers_column_view);
gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, descendants_column_view);
gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, descendants_name_sorter);
gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, functions_column_view);
gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, functions_name_sorter);
gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, paned);
klass->augment_size = GLIB_SIZEOF_VOID_P;
g_resources_register (libsysprof_gtk_get_resource ());
g_type_ensure (PANEL_TYPE_PANED);
g_type_ensure (SYSPROF_TYPE_SYMBOL_LABEL);
}
static void
sysprof_callgraph_view_init (SysprofCallgraphView *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
static int
descendants_name_compare (gconstpointer a,
gconstpointer b,
gpointer user_data)
{
SysprofCallgraphFrame *frame_a = (SysprofCallgraphFrame *)a;
SysprofCallgraphFrame *frame_b = (SysprofCallgraphFrame *)b;
return g_strcmp0 (sysprof_symbol_get_name (sysprof_callgraph_frame_get_symbol (frame_a)),
sysprof_symbol_get_name (sysprof_callgraph_frame_get_symbol (frame_b)));
}
static int
functions_name_compare (gconstpointer a,
gconstpointer b,
gpointer user_data)
{
SysprofCallgraphSymbol *sym_a = (SysprofCallgraphSymbol *)a;
SysprofCallgraphSymbol *sym_b = (SysprofCallgraphSymbol *)b;
return g_strcmp0 (sysprof_symbol_get_name (sysprof_callgraph_symbol_get_symbol (sym_a)),
sysprof_symbol_get_name (sysprof_callgraph_symbol_get_symbol (sym_b)));
}
static GListModel *
sysprof_callgraph_view_create_model_func (gpointer item,
gpointer user_data)
{
if (g_list_model_get_n_items (G_LIST_MODEL (item)) > 0)
return g_object_ref (G_LIST_MODEL (item));
return NULL;
}
static void
sysprof_callgraph_view_reload_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
SysprofDocument *document = (SysprofDocument *)object;
g_autoptr(SysprofCallgraphView) self = user_data;
g_autoptr(SysprofCallgraph) callgraph = NULL;
g_autoptr(GError) error = NULL;
GtkSorter *column_sorter;
g_autoptr(GtkSingleSelection) functions_selection = NULL;
g_autoptr(GtkSortListModel) functions_sort_model = NULL;
g_autoptr(GListModel) functions_model = NULL;
g_assert (SYSPROF_IS_DOCUMENT (document));
g_assert (G_IS_ASYNC_RESULT (result));
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
if (!(callgraph = sysprof_document_callgraph_finish (document, result, &error)))
{
g_debug ("Failed to generate callgraph: %s", error->message);
return;
}
g_set_object (&self->callgraph, callgraph);
sysprof_callgraph_view_set_descendants (self, G_LIST_MODEL (callgraph));
column_sorter = gtk_column_view_get_sorter (self->functions_column_view);
functions_model = sysprof_callgraph_list_symbols (callgraph);
functions_sort_model = gtk_sort_list_model_new (g_object_ref (functions_model),
g_object_ref (column_sorter));
functions_selection = gtk_single_selection_new (g_object_ref (G_LIST_MODEL (functions_sort_model)));
gtk_single_selection_set_autoselect (functions_selection, FALSE);
gtk_single_selection_set_can_unselect (functions_selection, TRUE);
gtk_single_selection_set_selected (functions_selection, GTK_INVALID_LIST_POSITION);
g_signal_connect_object (functions_selection,
"selection-changed",
G_CALLBACK (functions_selection_changed_cb),
self,
G_CONNECT_SWAPPED);
gtk_column_view_set_model (self->functions_column_view,
GTK_SELECTION_MODEL (functions_selection));
gtk_custom_sorter_set_sort_func (self->descendants_name_sorter,
descendants_name_compare, NULL, NULL);
gtk_custom_sorter_set_sort_func (self->functions_name_sorter,
functions_name_compare, NULL, NULL);
if (SYSPROF_CALLGRAPH_VIEW_GET_CLASS (self)->load)
SYSPROF_CALLGRAPH_VIEW_GET_CLASS (self)->load (self, callgraph);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CALLGRAPH]);
}
static gboolean
sysprof_callgraph_view_reload (SysprofCallgraphView *self)
{
SysprofCallgraphFlags flags = 0;
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
g_clear_handle_id (&self->reload_source, g_source_remove);
if (self->include_threads)
flags |= SYSPROF_CALLGRAPH_FLAGS_INCLUDE_THREADS;
if (self->hide_system_libraries)
flags |= SYSPROF_CALLGRAPH_FLAGS_HIDE_SYSTEM_LIBRARIES;
sysprof_document_callgraph_async (self->document,
flags,
self->traceables,
SYSPROF_CALLGRAPH_VIEW_GET_CLASS (self)->augment_size,
SYSPROF_CALLGRAPH_VIEW_GET_CLASS (self)->augment_func,
NULL,
NULL,
self->cancellable,
sysprof_callgraph_view_reload_cb,
g_object_ref (self));
return G_SOURCE_REMOVE;
}
static void
sysprof_callgraph_view_queue_reload (SysprofCallgraphView *self)
{
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
sysprof_callgraph_view_set_utility_traceables (self, NULL);
gtk_column_view_set_model (self->descendants_column_view, NULL);
gtk_column_view_set_model (self->functions_column_view, NULL);
gtk_column_view_set_model (self->callers_column_view, NULL);
g_clear_handle_id (&self->reload_source, g_source_remove);
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
self->cancellable = g_cancellable_new ();
if (self->document != NULL && self->traceables != NULL)
self->reload_source = g_idle_add_full (G_PRIORITY_LOW,
(GSourceFunc)sysprof_callgraph_view_reload,
g_object_ref (self),
g_object_unref);
}
/**
* sysprof_callgraph_view_get_document:
* @self: a #SysprofCallgraphView
*
* Gets the document for the callgraph.
*
* Returns: (transfer none) (nullable): a #SysprofDocument or %NULL
*/
SysprofDocument *
sysprof_callgraph_view_get_document (SysprofCallgraphView *self)
{
g_return_val_if_fail (SYSPROF_IS_CALLGRAPH_VIEW (self), NULL);
return self->document;
}
void
sysprof_callgraph_view_set_document (SysprofCallgraphView *self,
SysprofDocument *document)
{
g_return_if_fail (SYSPROF_IS_CALLGRAPH_VIEW (self));
if (g_set_object (&self->document, document))
{
sysprof_callgraph_view_queue_reload (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DOCUMENT]);
}
}
/**
* sysprof_callgraph_view_get_traceables:
* @self: a #SysprofCallgraphView
*
* Gets the list of traceables to be displayed.
*
* Returns: (transfer none) (nullable): a #GListModel or %NULL
*/
GListModel *
sysprof_callgraph_view_get_traceables (SysprofCallgraphView *self)
{
g_return_val_if_fail (SYSPROF_IS_CALLGRAPH_VIEW (self), NULL);
return self->traceables;
}
void
sysprof_callgraph_view_set_traceables (SysprofCallgraphView *self,
GListModel *traceables)
{
g_return_if_fail (SYSPROF_IS_CALLGRAPH_VIEW (self));
g_return_if_fail (!traceables || G_IS_LIST_MODEL (traceables));
if (g_set_object (&self->traceables, traceables))
{
sysprof_callgraph_view_queue_reload (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TRACEABLES]);
}
}
static GObject *
sysprof_callgraph_view_get_internal_child (GtkBuildable *buildable,
GtkBuilder *builder,
const char *name)
{
if (g_strcmp0 (name, "callers_column_view") == 0)
return G_OBJECT (SYSPROF_CALLGRAPH_VIEW (buildable)->callers_column_view);
else if (g_strcmp0 (name, "descendants_column_view") == 0)
return G_OBJECT (SYSPROF_CALLGRAPH_VIEW (buildable)->descendants_column_view);
else if (g_strcmp0 (name, "functions_column_view") == 0)
return G_OBJECT (SYSPROF_CALLGRAPH_VIEW (buildable)->functions_column_view);
return NULL;
}
static void
buildable_iface_init (GtkBuildableIface *iface)
{
iface->get_internal_child = sysprof_callgraph_view_get_internal_child;
}
/**
* sysprof_callgraph_view_get_callgraph:
* @self: a #SysprofCallgraphView
*
* Gets the callgraph being displayed.
*
* Returns: (transfer none) (nullable): a #SysprofCallgraph or %NULL
*/
SysprofCallgraph *
sysprof_callgraph_view_get_callgraph (SysprofCallgraphView *self)
{
g_return_val_if_fail (SYSPROF_IS_CALLGRAPH_VIEW (self), NULL);
return self->callgraph;
}
gboolean
sysprof_callgraph_view_get_hide_system_libraries (SysprofCallgraphView *self)
{
g_return_val_if_fail (SYSPROF_IS_CALLGRAPH_VIEW (self), FALSE);
return self->hide_system_libraries;
}
void
sysprof_callgraph_view_set_hide_system_libraries (SysprofCallgraphView *self,
gboolean hide_system_libraries)
{
g_return_if_fail (SYSPROF_IS_CALLGRAPH_VIEW (self));
hide_system_libraries = !!hide_system_libraries;
if (self->hide_system_libraries != hide_system_libraries)
{
self->hide_system_libraries = hide_system_libraries;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HIDE_SYSTEM_LIBRARIES]);
sysprof_callgraph_view_queue_reload (self);
}
}
gboolean
sysprof_callgraph_view_get_include_threads (SysprofCallgraphView *self)
{
g_return_val_if_fail (SYSPROF_IS_CALLGRAPH_VIEW (self), FALSE);
return self->include_threads;
}
void
sysprof_callgraph_view_set_include_threads (SysprofCallgraphView *self,
gboolean include_threads)
{
g_return_if_fail (SYSPROF_IS_CALLGRAPH_VIEW (self));
include_threads = !!include_threads;
if (self->include_threads != include_threads)
{
self->include_threads = include_threads;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INCLUDE_THREADS]);
sysprof_callgraph_view_queue_reload (self);
}
}