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.
This commit is contained in:
Christian Hergert
2023-07-12 15:48:28 -07:00
parent 27f429d4f2
commit ea8befb624
11 changed files with 293 additions and 297 deletions

View File

@ -40,12 +40,9 @@ struct _SysprofCallgraphView
GtkColumnView *callers_column_view;
GtkColumnView *descendants_column_view;
GtkColumnView *functions_column_view;
GtkColumnView *traceables_column_view;
GtkColumnView *traceable_column_view;
GtkCustomSorter *descendants_name_sorter;
GtkCustomSorter *functions_name_sorter;
GtkScrolledWindow *scrolled_window;
PanelPaned *right_paned;
GtkWidget *paned;
GCancellable *cancellable;

View File

@ -160,9 +160,6 @@ sysprof_callgraph_view_list_traceables_cb (GObject *object,
model = sysprof_callgraph_frame_list_traceables_finish (frame, result, &error);
sysprof_callgraph_view_set_utility_traceables (self, model);
gtk_widget_set_visible (gtk_widget_get_parent (GTK_WIDGET (self->right_paned)),
model && g_list_model_get_n_items (model));
}
static void
@ -250,6 +247,7 @@ functions_selection_changed_cb (SysprofCallgraphView *self,
}
}
#if 0
static void
traceable_activate_cb (SysprofCallgraphView *self,
guint position,
@ -297,52 +295,7 @@ traceable_activate_cb (SysprofCallgraphView *self,
}
}
}
static char *
format_time_offset (gpointer cell)
{
g_autoptr(SysprofDocumentFrame) frame = NULL;
int hours;
int minutes;
double time;
g_object_get (cell, "item", &frame, NULL);
g_assert (!frame || SYSPROF_IS_DOCUMENT_FRAME (frame));
if (!frame)
return NULL;
time = sysprof_document_frame_get_time_offset (frame) / (double)SYSPROF_NSEC_PER_SEC;
hours = time / (60 * 60);
time -= hours * (60 * 60);
minutes = time / 60;
time -= minutes * 60;
if (hours == 0 && minutes == 0)
return g_strdup_printf ("%.4lf", time);
if (hours == 0)
return g_strdup_printf ("%02d:%02.4lf", minutes, time);
return g_strdup_printf ("%02d:%02d:%02.4lf", hours, minutes, time);
}
static GListModel *
symbolize_traceable_cb (SysprofCallgraphView *self,
SysprofDocumentTraceable *traceable)
{
SysprofDocument *document;
g_assert (SYSPROF_IS_CALLGRAPH_VIEW (self));
g_assert (!traceable || SYSPROF_IS_DOCUMENT_TRACEABLE (traceable));
if (traceable == NULL || !(document = sysprof_callgraph_view_get_document (self)))
return NULL;
return sysprof_document_list_symbols_in_traceable (document, traceable);
}
#endif
static void
sysprof_callgraph_view_dispose (GObject *object)
@ -485,12 +438,6 @@ sysprof_callgraph_view_class_init (SysprofCallgraphViewClass *klass)
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);
gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, right_paned);
gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, traceable_column_view);
gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, traceables_column_view);
gtk_widget_class_bind_template_callback (widget_class, format_time_offset);
gtk_widget_class_bind_template_callback (widget_class, traceable_activate_cb);
gtk_widget_class_bind_template_callback (widget_class, symbolize_traceable_cb);
klass->augment_size = GLIB_SIZEOF_VOID_P;
@ -504,8 +451,6 @@ static void
sysprof_callgraph_view_init (SysprofCallgraphView *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
gtk_widget_set_visible (gtk_widget_get_parent (GTK_WIDGET (self->right_paned)), FALSE);
}
static int

View File

@ -220,176 +220,6 @@
</child>
</object>
</child>
<child>
<object class="PanelPaned" id="right_paned">
<property name="hexpand">false</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow">
<property name="min-content-height">100</property>
<child>
<object class="GtkColumnView" id="traceables_column_view">
<style>
<class name="data-table"/>
</style>
<property name="model">
<object class="GtkSingleSelection" id="traceables_selection">
<binding name="model">
<lookup name="utility-traceables">SysprofCallgraphView</lookup>
</binding>
</object>
</property>
<child>
<object class="GtkColumnViewColumn" id="traceables_time_column">
<property name="title" translatable="yes">Time</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<attributes>
<attribute name="font-features" value="'tnum'"/>
</attributes>
<binding name="label">
<closure type="gchararray" function="format_time_offset">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="traceables_pid_column">
<property name="title" translatable="yes">PID</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<attributes>
<attribute name="font-features" value="'tnum'"/>
</attributes>
<binding name="label">
<lookup name="pid" type="SysprofDocumentFrame">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="traceables_depth_column">
<property name="title" translatable="yes">Depth</property>
<property name="expand">true</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<attributes>
<attribute name="font-features" value="'tnum'"/>
</attributes>
<binding name="label">
<lookup name="stack-depth" type="SysprofDocumentTraceable">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="propagate-natural-width">true</property>
<property name="vexpand">true</property>
<child>
<object class="GtkColumnView" id="traceable_column_view">
<style>
<class name="data-table"/>
</style>
<signal name="activate" handler="traceable_activate_cb" swapped="true"/>
<property name="single-click-activate">true</property>
<property name="model">
<object class="GtkNoSelection">
<binding name="model">
<closure type="GListModel" function="symbolize_traceable_cb" object="SysprofCallgraphView" swapped="true">
<lookup name="selected-item">traceables_selection</lookup>
</closure>
</binding>
</object>
</property>
<child>
<object class="GtkColumnViewColumn" id="traceable_symbol_column">
<property name="title" translatable="yes">Stack Trace</property>
<property name="expand">true</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkInscription">
<property name="text-overflow">clip</property>
<property name="nat-chars">15</property>
<binding name="text">
<lookup name="name" type="SysprofSymbol">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
<binding name="tooltip-text">
<lookup name="name" type="SysprofSymbol">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</template>

View File

@ -23,6 +23,7 @@
#include <sysprof-gtk.h>
#include "sysprof-samples-section.h"
#include "sysprof-traceables-utility.h"
struct _SysprofSamplesSection
{
@ -57,6 +58,7 @@ sysprof_samples_section_class_init (SysprofSamplesSectionClass *klass)
g_type_ensure (SYSPROF_TYPE_CHART);
g_type_ensure (SYSPROF_TYPE_XY_SERIES);
g_type_ensure (SYSPROF_TYPE_COLUMN_LAYER);
g_type_ensure (SYSPROF_TYPE_TRACEABLES_UTILITY);
g_type_ensure (SYSPROF_TYPE_VALUE_AXIS);
g_type_ensure (SYSPROF_TYPE_WEIGHTED_CALLGRAPH_VIEW);
}

View File

@ -73,5 +73,28 @@
</child>
</object>
</child>
<property name="utility">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar">
<property name="title-widget">
<object class="AdwWindowTitle">
<property name="title" translatable="yes">Stack Trace</property>
</object>
</property>
</object>
</child>
<property name="content">
<object class="SysprofTraceablesUtility">
<binding name="session">
<lookup name="session">SysprofSamplesSection</lookup>
</binding>
<binding name="traceables">
<lookup name="utility-traceables">callgraph_view</lookup>
</binding>
</object>
</property>
</object>
</property>
</template>
</interface>

View File

@ -25,10 +25,11 @@
typedef struct
{
char *category;
char *icon_name;
char *title;
char *category;
char *icon_name;
char *title;
SysprofSession *session;
GtkWidget *utility;
} SysprofSectionPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (SysprofSection, sysprof_section, GTK_TYPE_WIDGET)
@ -39,6 +40,7 @@ enum {
PROP_CATEGORY,
PROP_ICON_NAME,
PROP_TITLE,
PROP_UTILITY,
N_PROPS
};
@ -54,6 +56,7 @@ sysprof_section_dispose (GObject *object)
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
gtk_widget_unparent (child);
g_clear_object (&priv->utility);
g_clear_object (&priv->session);
g_clear_pointer (&priv->title, g_free);
g_clear_pointer (&priv->category, g_free);
@ -88,6 +91,10 @@ sysprof_section_get_property (GObject *object,
g_value_set_string (value, sysprof_section_get_title (self));
break;
case PROP_UTILITY:
g_value_set_object (value, sysprof_section_get_utility (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@ -119,6 +126,10 @@ sysprof_section_set_property (GObject *object,
sysprof_section_set_title (self, g_value_get_string (value));
break;
case PROP_UTILITY:
sysprof_section_set_utility (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@ -154,6 +165,11 @@ sysprof_section_class_init (SysprofSectionClass *klass)
NULL,
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
properties[PROP_UTILITY] =
g_param_spec_object ("utility", NULL, NULL,
GTK_TYPE_WIDGET,
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
@ -252,3 +268,29 @@ sysprof_section_set_icon_name (SysprofSection *self,
if (g_set_str (&priv->icon_name, icon_name))
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ICON_NAME]);
}
GtkWidget *
sysprof_section_get_utility (SysprofSection *self)
{
SysprofSectionPrivate *priv = sysprof_section_get_instance_private (self);
g_return_val_if_fail (SYSPROF_IS_SECTION (self), NULL);
return priv->utility;
}
void
sysprof_section_set_utility (SysprofSection *self,
GtkWidget *utility)
{
SysprofSectionPrivate *priv = sysprof_section_get_instance_private (self);
g_autoptr(GtkWidget) hold = NULL;
g_return_if_fail (SYSPROF_IS_SECTION (self));
g_return_if_fail (!utility || GTK_IS_WIDGET (utility));
g_set_object (&hold, priv->utility);
if (g_set_object (&priv->utility, utility))
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UTILITY]);
}

View File

@ -47,5 +47,8 @@ void sysprof_section_set_icon_name (SysprofSection *self,
const char *sysprof_section_get_title (SysprofSection *self);
void sysprof_section_set_title (SysprofSection *self,
const char *title);
GtkWidget *sysprof_section_get_utility (SysprofSection *self);
void sysprof_section_set_utility (SysprofSection *self,
GtkWidget *utility);
G_END_DECLS

View File

@ -42,6 +42,53 @@ G_DEFINE_FINAL_TYPE (SysprofTraceablesUtility, sysprof_traceables_utility, GTK_T
static GParamSpec *properties[N_PROPS];
static char *
format_time_offset (gpointer cell)
{
g_autoptr(SysprofDocumentFrame) frame = NULL;
int hours;
int minutes;
double time;
g_object_get (cell, "item", &frame, NULL);
g_assert (!frame || SYSPROF_IS_DOCUMENT_FRAME (frame));
if (!frame)
return NULL;
time = sysprof_document_frame_get_time_offset (frame) / (double)SYSPROF_NSEC_PER_SEC;
hours = time / (60 * 60);
time -= hours * (60 * 60);
minutes = time / 60;
time -= minutes * 60;
if (hours == 0 && minutes == 0)
return g_strdup_printf ("%.4lf", time);
if (hours == 0)
return g_strdup_printf ("%02d:%02.4lf", minutes, time);
return g_strdup_printf ("%02d:%02d:%02.4lf", hours, minutes, time);
}
static GListModel *
symbolize_traceable (SysprofTraceablesUtility *self,
SysprofDocumentTraceable *traceable)
{
SysprofDocument *document;
g_assert (SYSPROF_IS_TRACEABLES_UTILITY (self));
g_assert (!traceable || SYSPROF_IS_DOCUMENT_TRACEABLE (traceable));
if (traceable == NULL || self->session == NULL ||
!(document = sysprof_session_get_document (self->session)))
return NULL;
return sysprof_document_list_symbols_in_traceable (document, traceable);
}
static void
sysprof_traceables_utility_finalize (GObject *object)
{
@ -117,17 +164,19 @@ sysprof_traceables_utility_class_init (SysprofTraceablesUtilityClass *klass)
properties[PROP_SESSION] =
g_param_spec_object ("session", NULL, NULL,
SYSPROF_TYPE_SESSION,
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
(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_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
(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, "/org/gnome/sysprof/sysprof-traceables-utility.ui");
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_bind_template_callback (widget_class, format_time_offset);
gtk_widget_class_bind_template_callback (widget_class, symbolize_traceable);
}
static void

View File

@ -4,6 +4,168 @@
<child>
<object class="GtkPaned">
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow">
<child>
<object class="GtkColumnView" id="traceables_column_view">
<style>
<class name="data-table"/>
</style>
<property name="model">
<object class="GtkSingleSelection" id="traceables_selection">
<binding name="model">
<lookup name="traceables">SysprofTraceablesUtility</lookup>
</binding>
</object>
</property>
<child>
<object class="GtkColumnViewColumn" id="traceables_time_column">
<property name="title" translatable="yes">Time</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<attributes>
<attribute name="font-features" value="'tnum'"/>
</attributes>
<binding name="label">
<closure type="gchararray" function="format_time_offset">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="traceables_pid_column">
<property name="title" translatable="yes">PID</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<attributes>
<attribute name="font-features" value="'tnum'"/>
</attributes>
<binding name="label">
<lookup name="pid" type="SysprofDocumentFrame">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="traceables_depth_column">
<property name="title" translatable="yes">Depth</property>
<property name="expand">true</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<attributes>
<attribute name="font-features" value="'tnum'"/>
</attributes>
<binding name="label">
<lookup name="stack-depth" type="SysprofDocumentTraceable">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">true</property>
<child>
<object class="GtkColumnView" id="traceable_column_view">
<style>
<class name="data-table"/>
</style>
<!--signal name="activate" handler="traceable_activate_cb" swapped="true"/-->
<property name="single-click-activate">true</property>
<property name="model">
<object class="GtkNoSelection">
<binding name="model">
<closure type="GListModel" function="symbolize_traceable" object="SysprofTraceablesUtility" swapped="true">
<lookup name="selected-item">traceables_selection</lookup>
</closure>
</binding>
</object>
</property>
<child>
<object class="GtkColumnViewColumn" id="traceable_symbol_column">
<property name="title" translatable="yes">Stack Trace</property>
<property name="expand">true</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkInscription">
<property name="text-overflow">clip</property>
<property name="nat-chars">15</property>
<binding name="text">
<lookup name="name" type="SysprofSymbol">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
<binding name="tooltip-text">
<lookup name="name" type="SysprofSymbol">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</template>

View File

@ -33,7 +33,6 @@
#include "sysprof-processes-section.h"
#include "sysprof-samples-section.h"
#include "sysprof-sidebar.h"
#include "sysprof-traceables-utility.h"
#include "sysprof-window.h"
struct _SysprofWindow
@ -42,9 +41,6 @@ struct _SysprofWindow
SysprofDocument *document;
SysprofSession *session;
AdwViewStack *utility_stack;
AdwWindowTitle *utility_title;
};
enum {
@ -197,9 +193,6 @@ sysprof_window_class_init (SysprofWindowClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/sysprof-window.ui");
gtk_widget_class_bind_template_child (widget_class, SysprofWindow, utility_stack);
gtk_widget_class_bind_template_child (widget_class, SysprofWindow, utility_title);
gtk_widget_class_install_action (widget_class, "win.open-capture", NULL, sysprof_window_open_capture_action);
gtk_widget_class_install_action (widget_class, "win.record-capture", NULL, sysprof_window_record_capture_action);
@ -213,39 +206,12 @@ sysprof_window_class_init (SysprofWindowClass *klass)
g_type_ensure (SYSPROF_TYPE_SAMPLES_SECTION);
g_type_ensure (SYSPROF_TYPE_SESSION);
g_type_ensure (SYSPROF_TYPE_SIDEBAR);
g_type_ensure (SYSPROF_TYPE_TRACEABLES_UTILITY);
}
static void
utility_stack_notify_visible_child_cb (SysprofWindow *self,
GParamSpec *pspec,
AdwViewStack *utility_stack)
{
AdwViewStackPage *page;
const char *title = NULL;
GtkWidget *child;
g_assert (SYSPROF_IS_WINDOW (self));
g_assert (ADW_IS_VIEW_STACK (utility_stack));
if ((child = adw_view_stack_get_visible_child (utility_stack)) &&
(page = adw_view_stack_get_page (utility_stack, child)))
title = adw_view_stack_page_get_title (page);
adw_window_title_set_title (self->utility_title, title);
}
static void
sysprof_window_init (SysprofWindow *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
g_signal_connect_object (self->utility_stack,
"notify::visible-child",
G_CALLBACK (utility_stack_notify_visible_child_cb),
self,
G_CONNECT_SWAPPED);
utility_stack_notify_visible_child_cb (self, NULL, self->utility_stack);
}
GtkWidget *

View File

@ -164,34 +164,11 @@
</property>
</object>
</property>
<property name="sidebar">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar">
<property name="title-widget">
<object class="AdwWindowTitle" id="utility_title"/>
</property>
</object>
</child>
<property name="content">
<object class="AdwViewStack" id="utility_stack">
<property name="vexpand">true</property>
<child>
<object class="AdwViewStackPage">
<property name="title" translatable="yes">Stack Traces</property>
<property name="child">
<object class="SysprofTraceablesUtility">
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</property>
</object>
</child>
</object>
</property>
</object>
</property>
<binding name="sidebar">
<lookup name="utility" type="SysprofSection">
<lookup name="visible-child">section_stack</lookup>
</lookup>
</binding>
</object>
</property>
</object>