sysprof: drop libsysprof-gtk and absorb it in sysprof

We are dropping the whole "embed this gtk stuff in your app" model since
that never really worked that well.
This commit is contained in:
Christian Hergert
2023-07-14 21:06:45 -07:00
parent 6dd8f7014f
commit f199f26fe9
129 changed files with 115 additions and 4632 deletions

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<gresources>
<gresource prefix="/libsysprof-gtk">
<file preprocess="xml-stripblanks">sysprof-callgraph-view.ui</file>
<file preprocess="xml-stripblanks">sysprof-mark-chart.ui</file>
<file preprocess="xml-stripblanks">sysprof-mark-chart-row.ui</file>
<file preprocess="xml-stripblanks">sysprof-mark-table.ui</file>
<file preprocess="xml-stripblanks">sysprof-memory-callgraph-view.ui</file>
<file preprocess="xml-stripblanks">sysprof-track-view.ui</file>
<file preprocess="xml-stripblanks">sysprof-tracks-view.ui</file>
<file preprocess="xml-stripblanks">sysprof-weighted-callgraph-view.ui</file>
<file>style.css</file>
</gresource>
</gresources>

View File

@ -1,142 +0,0 @@
libsysprof_gtk_public_sources = [
'sysprof-axis.c',
'sysprof-callgraph-view.c',
'sysprof-chart.c',
'sysprof-chart-layer.c',
'sysprof-column-layer.c',
'sysprof-duplex-layer.c',
'sysprof-line-layer.c',
'sysprof-mark-chart.c',
'sysprof-mark-table.c',
'sysprof-memory-callgraph-view.c',
'sysprof-normalized-series.c',
'sysprof-normalized-series-item.c',
'sysprof-series.c',
'sysprof-session.c',
'sysprof-session-model.c',
'sysprof-session-model-item.c',
'sysprof-split-layer.c',
'sysprof-time-filter-model.c',
'sysprof-time-label.c',
'sysprof-time-ruler.c',
'sysprof-time-span-layer.c',
'sysprof-time-series.c',
'sysprof-time-series-item.c',
'sysprof-track.c',
'sysprof-track-view.c',
'sysprof-tracks-view.c',
'sysprof-value-axis.c',
'sysprof-weighted-callgraph-view.c',
'sysprof-xy-layer.c',
'sysprof-xy-series.c',
'sysprof-xy-series-item.c',
]
libsysprof_gtk_public_headers = [
'sysprof-gtk.h',
'sysprof-axis.h',
'sysprof-callgraph-view.h',
'sysprof-chart.h',
'sysprof-chart-layer.h',
'sysprof-column-layer.h',
'sysprof-duplex-layer.h',
'sysprof-line-layer.h',
'sysprof-mark-chart.h',
'sysprof-mark-table.h',
'sysprof-memory-callgraph-view.h',
'sysprof-normalized-series.h',
'sysprof-normalized-series-item.h',
'sysprof-series.h',
'sysprof-session.h',
'sysprof-session-model.h',
'sysprof-session-model-item.h',
'sysprof-split-layer.h',
'sysprof-time-filter-model.h',
'sysprof-time-label.h',
'sysprof-time-ruler.h',
'sysprof-time-series.h',
'sysprof-time-series-item.h',
'sysprof-time-span-layer.h',
'sysprof-track.h',
'sysprof-track-view.h',
'sysprof-tracks-view.h',
'sysprof-weighted-callgraph-view.h',
'sysprof-value-axis.h',
'sysprof-xy-layer.h',
'sysprof-xy-series.h',
'sysprof-xy-series-item.h',
]
libsysprof_gtk_private_sources = [
'sysprof-color-iter.c',
'sysprof-css.c',
'sysprof-mark-chart-item.c',
'sysprof-mark-chart-row.c',
'sysprof-progress-cell.c',
'sysprof-scheduler.c',
'sysprof-session-discover.c',
'sysprof-symbol-label.c',
]
libsysprof_gtk_deps = [
dependency('libadwaita-1'),
dependency('libpanel-1'),
dependency('gtk4', version: gtk_req_version),
libsysprof_analyze_dep,
]
libsysprof_gtk_resources = gnome.compile_resources(
'libsysprof-gtk-resources',
'libsysprof-gtk.gresource.xml',
c_name: 'libsysprof_gtk',
)
libsysprof_gtk_static = static_library(
'sysprof-gtk-@0@'.format(soname_major_version),
(libsysprof_gtk_public_sources +
libsysprof_gtk_private_sources +
libsysprof_gtk_resources +
mapped_ring_buffer_sources),
include_directories: [include_directories('.'),
ipc_include_dirs,
libsysprof_capture_include_dirs],
dependencies: libsysprof_gtk_deps,
gnu_symbol_visibility: 'hidden',
)
libsysprof_gtk_static_dep = declare_dependency(
link_with: libsysprof_gtk_static,
dependencies: libsysprof_gtk_deps,
include_directories: [include_directories('.'),
libsysprof_capture_include_dirs],
)
libsysprof_gtk = library('sysprof-gtk-@0@'.format(soname_major_version),
dependencies: [libsysprof_gtk_static_dep],
gnu_symbol_visibility: 'hidden',
version: '@0@.0.0'.format(soname_major_version),
darwin_versions: '@0@.0'.format(soname_major_version),
install: true,
)
libsysprof_gtk_dep = declare_dependency(
link_with: libsysprof_gtk,
dependencies: libsysprof_gtk_deps,
include_directories: [include_directories('.'), libsysprof_capture_include_dirs],
)
meson.override_dependency('sysprof-gtk-@0@'.format(soname_major_version), libsysprof_gtk_dep)
pkgconfig.generate(libsysprof_gtk,
subdirs: [sysprof_header_subdir],
description: 'Provides GTK widgets for sysprof visualizion',
install_dir: join_paths(get_option('libdir'), 'pkgconfig'),
requires: ['gtk4'],
variables: ['datadir=' + datadir_for_pc_file],
)
install_headers(libsysprof_gtk_public_headers, subdir: sysprof_header_subdir)
subdir('tests')

View File

@ -1,58 +0,0 @@
/* sysprof-gtk.h
*
* 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
*/
#pragma once
#include <sysprof-analyze.h>
G_BEGIN_DECLS
#define SYSPROF_GTK_INSIDE
# include "sysprof-axis.h"
# include "sysprof-callgraph-view.h"
# include "sysprof-chart.h"
# include "sysprof-chart-layer.h"
# include "sysprof-column-layer.h"
# include "sysprof-duplex-layer.h"
# include "sysprof-line-layer.h"
# include "sysprof-mark-chart.h"
# include "sysprof-mark-table.h"
# include "sysprof-memory-callgraph-view.h"
# include "sysprof-normalized-series.h"
# include "sysprof-normalized-series-item.h"
# include "sysprof-series.h"
# include "sysprof-session.h"
# include "sysprof-session-model.h"
# include "sysprof-session-model-item.h"
# include "sysprof-split-layer.h"
# include "sysprof-time-label.h"
# include "sysprof-time-ruler.h"
# include "sysprof-time-series.h"
# include "sysprof-time-series-item.h"
# include "sysprof-time-span-layer.h"
# include "sysprof-tracks-view.h"
# include "sysprof-value-axis.h"
# include "sysprof-weighted-callgraph-view.h"
# include "sysprof-xy-layer.h"
# include "sysprof-xy-series.h"
# include "sysprof-xy-series-item.h"
#undef SYSPROF_GTK_INSIDE
G_END_DECLS

View File

@ -1,672 +0,0 @@
/* sysprof-session-discover.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 <glib/gi18n.h>
#include "sysprof-chart.h"
#include "sysprof-chart-layer.h"
#include "sysprof-color-iter-private.h"
#include "sysprof-column-layer.h"
#include "sysprof-line-layer.h"
#include "sysprof-session-private.h"
#include "sysprof-time-span-layer.h"
#include "sysprof-track-private.h"
#include "sysprof-value-axis.h"
typedef enum _LineFlags
{
LINE_FLAGS_DASHED = 1 << 0,
LINE_FLAGS_NO_SPLINE = 1 << 1,
LINE_FLAGS_FILL = 1 << 2,
LINE_FLAGS_IGNORE_RANGE_ON_SUBCHART = 1 << 3,
LINE_FLAGS_FORMAT_MEMORY = 1 << 4,
} LineFlags;
typedef struct _SysprofTrackSamples
{
SysprofSession *session;
GListModel *samples;
} SysprofTrackSamples;
typedef struct _SysprofTrackCounter
{
const char *track_name;
/* Used to layer values into main view */
const char *category;
const char *name;
/* Used to split out sub views */
const char *subtracks_category;
const char *subtracks_name;
double min_value;
double max_value;
LineFlags flags;
} SysprofTrackCounter;
typedef struct _SysprofTrackCounterChart
{
GListModel *counters;
GListModel *subcounters;
SysprofDocument *document;
SysprofSession *session;
const SysprofTrackCounter *info;
GdkRGBA color;
guint apply_range : 1;
} SysprofTrackCounterChart;
typedef struct _SysprofTrackMarksChart
{
GListModel *model;
SysprofDocument *document;
SysprofSession *session;
} SysprofTrackMarksChart;
static const SysprofTrackCounter discovery_counters[] = {
{
N_("CPU Usage"),
"CPU Percent", "Combined",
"CPU Percent", "Total *",
.0, 100.,
LINE_FLAGS_FILL,
},
{
N_("CPU Frequency"),
"CPU Frequency", "*",
"CPU Frequency", "*",
.0, 100.,
LINE_FLAGS_DASHED,
},
{ N_("Memory"),
"Memory", "Used",
NULL, NULL,
.0, .0,
LINE_FLAGS_FILL | LINE_FLAGS_FORMAT_MEMORY,
},
{ N_("FPS"), "gtk", "fps", "gtk", "*",
0, 144, LINE_FLAGS_IGNORE_RANGE_ON_SUBCHART },
{
N_("Energy"),
"RAPL", "*",
"RAPL*", "*",
},
};
static void
sysprof_track_samples_free (SysprofTrackSamples *samples)
{
g_clear_object (&samples->samples);
g_clear_weak_pointer (&samples->session);
g_free (samples);
}
static SysprofTrackSamples *
sysprof_track_samples_new (SysprofSession *session,
GListModel *samples)
{
SysprofTrackSamples *state;
state = g_new0 (SysprofTrackSamples, 1);
state->samples = g_object_ref (samples);
g_set_weak_pointer (&state->session, session);
return state;
}
static void
sysprof_track_counter_chart_free (SysprofTrackCounterChart *info)
{
g_clear_object (&info->counters);
g_clear_object (&info->document);
g_clear_weak_pointer (&info->session);
info->info = NULL;
g_free (info);
}
static void
sysprof_track_marks_chart_free (SysprofTrackMarksChart *info)
{
g_clear_object (&info->model);
g_clear_object (&info->document);
g_clear_weak_pointer (&info->session);
g_free (info);
}
static GListModel *
filter_counters (GListModel *model,
const char *category_glob,
const char *name_glob)
{
g_autoptr(GListStore) store = NULL;
g_autoptr(GPatternSpec) cat_spec = NULL;
g_autoptr(GPatternSpec) name_spec = NULL;
guint n_items;
g_assert (G_IS_LIST_MODEL (model));
if (category_glob == NULL || name_glob == NULL)
return NULL;
store = g_list_store_new (SYSPROF_TYPE_DOCUMENT_COUNTER);
cat_spec = g_pattern_spec_new (category_glob);
name_spec = g_pattern_spec_new (name_glob);
n_items = g_list_model_get_n_items (model);
for (guint i = 0; i < n_items; i++)
{
g_autoptr(SysprofDocumentCounter) counter = g_list_model_get_item (model, i);
const char *ctrcat = sysprof_document_counter_get_category (counter);
const char *ctrname = sysprof_document_counter_get_name (counter);
if (g_pattern_spec_match (cat_spec, strlen (ctrcat), ctrcat, NULL) &&
g_pattern_spec_match (name_spec, strlen (ctrname), ctrname, NULL))
g_list_store_append (store, counter);
}
if (g_list_model_get_n_items (G_LIST_MODEL (store)) == 0)
return NULL;
return G_LIST_MODEL (g_steal_pointer (&store));
}
static GtkWidget *
create_chart_for_samples (SysprofTrack *track,
SysprofTrackSamples *state)
{
g_autoptr(SysprofSeries) xy_series = NULL;
g_autoptr(SysprofAxis) y_axis = NULL;
SysprofChartLayer *layer;
SysprofChart *chart;
SysprofAxis *x_axis = NULL;
g_assert (state != NULL);
g_assert (SYSPROF_IS_SESSION (state->session));
g_assert (SYSPROF_IS_TRACK (track));
x_axis = sysprof_session_get_visible_time_axis (state->session);
y_axis = sysprof_value_axis_new (0, 128);
xy_series = sysprof_xy_series_new (sysprof_track_get_title (track),
g_object_ref (state->samples),
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_SAMPLE, NULL, "time"),
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_SAMPLE, NULL, "stack-depth"));
chart = g_object_new (SYSPROF_TYPE_CHART, NULL);
layer = g_object_new (SYSPROF_TYPE_COLUMN_LAYER,
"series", xy_series,
"x-axis", x_axis,
"y-axis", y_axis,
NULL);
sysprof_chart_add_layer (chart, layer);
return GTK_WIDGET (chart);
}
static void
sysprof_session_discover_sampler (SysprofSession *self,
SysprofDocument *document,
GListStore *tracks)
{
g_autoptr(GListModel) samples = NULL;
g_autoptr(GListModel) samples_with_context_switch = NULL;
g_autoptr(GListModel) samples_without_context_switch = NULL;
g_assert (SYSPROF_IS_SESSION (self));
g_assert (SYSPROF_IS_DOCUMENT (document));
g_assert (G_IS_LIST_STORE (tracks));
samples = sysprof_document_list_samples (document);
samples_with_context_switch = sysprof_document_list_samples_with_context_switch (document);
samples_without_context_switch = sysprof_document_list_samples_without_context_switch (document);
if (g_list_model_get_n_items (samples) > 0)
{
g_autoptr(SysprofTrack) track = NULL;
track = g_object_new (SYSPROF_TYPE_TRACK,
"title", _("Profiler"),
NULL);
g_signal_connect_data (track,
"create-chart",
G_CALLBACK (create_chart_for_samples),
sysprof_track_samples_new (self, samples),
(GClosureNotify)sysprof_track_samples_free,
0);
g_list_store_append (tracks, track);
if (g_list_model_get_n_items (samples_with_context_switch))
{
g_autoptr(SysprofTrack) subtrack = NULL;
subtrack = g_object_new (SYSPROF_TYPE_TRACK,
"title", _("Stack Traces (In Kernel)"),
NULL);
g_signal_connect_data (subtrack,
"create-chart",
G_CALLBACK (create_chart_for_samples),
sysprof_track_samples_new (self, samples_with_context_switch),
(GClosureNotify)sysprof_track_samples_free,
0);
_sysprof_track_add_subtrack (track, subtrack);
}
if (g_list_model_get_n_items (samples_without_context_switch))
{
g_autoptr(SysprofTrack) subtrack = NULL;
subtrack = g_object_new (SYSPROF_TYPE_TRACK,
"title", _("Stack Traces (In User)"),
NULL);
g_signal_connect_data (subtrack,
"create-chart",
G_CALLBACK (create_chart_for_samples),
sysprof_track_samples_new (self, samples_without_context_switch),
(GClosureNotify)sysprof_track_samples_free,
0);
_sysprof_track_add_subtrack (track, subtrack);
}
}
}
static GtkWidget *
create_chart_for_counters (SysprofTrack *track,
SysprofTrackCounterChart *info)
{
g_autoptr(SysprofDocumentCounter) first = NULL;
g_autoptr(SysprofSeries) xy_series = NULL;
g_autoptr(SysprofAxis) y_axis = NULL;
SysprofChartLayer *layer;
SysprofColorIter colors;
SysprofChart *chart;
SysprofAxis *x_axis = NULL;
double min_value = 0;
double max_value = 0;
gboolean ignore_range = FALSE;
guint n_items;
g_assert (SYSPROF_IS_TRACK (track));
g_assert (info != NULL);
g_assert (SYSPROF_IS_DOCUMENT (info->document));
g_assert (SYSPROF_IS_SESSION (info->session));
g_assert (G_IS_LIST_MODEL (info->counters));
if (!(n_items = g_list_model_get_n_items (info->counters)))
return NULL;
sysprof_color_iter_init (&colors);
x_axis = sysprof_session_get_visible_time_axis (info->session);
chart = g_object_new (SYSPROF_TYPE_CHART, NULL);
/* Setup Y axis usin first item. We'll expand the range
* after we've processed all the counters.
*/
first = g_list_model_get_item (info->counters, 0);
min_value = sysprof_document_counter_get_min_value (first);
max_value = sysprof_document_counter_get_max_value (first);
y_axis = sysprof_value_axis_new (min_value, max_value);
if (info->apply_range &&
(info->info->min_value != .0 || info->info->max_value != .0))
{
min_value = info->info->min_value;
max_value = info->info->max_value;
ignore_range = TRUE;
}
for (guint i = 0; i < n_items; i++)
{
g_autoptr(SysprofDocumentCounter) counter = g_list_model_get_item (info->counters, i);
double item_min_value = sysprof_document_counter_get_min_value (counter);
double item_max_value = sysprof_document_counter_get_max_value (counter);
const GdkRGBA *color;
if (!ignore_range)
{
if (item_min_value < min_value)
min_value = item_min_value;
if (item_max_value > max_value)
max_value = item_max_value;
}
if (info->color.alpha > 0)
color = &info->color;
else
color = sysprof_color_iter_next (&colors);
xy_series = sysprof_xy_series_new (sysprof_track_get_title (track),
g_object_ref (G_LIST_MODEL (counter)),
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_COUNTER_VALUE, NULL, "time"),
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_COUNTER_VALUE, NULL, "value-double"));
layer = g_object_new (SYSPROF_TYPE_LINE_LAYER,
"spline", !(info->info->flags & LINE_FLAGS_NO_SPLINE),
"dashed", !!(info->info->flags & LINE_FLAGS_DASHED),
"fill", !!(info->info->flags & LINE_FLAGS_FILL),
"color", color,
"series", xy_series,
"x-axis", x_axis,
"y-axis", y_axis,
NULL);
sysprof_chart_add_layer (chart, layer);
}
sysprof_value_axis_set_min_value (SYSPROF_VALUE_AXIS (y_axis), min_value);
sysprof_value_axis_set_max_value (SYSPROF_VALUE_AXIS (y_axis), max_value);
return GTK_WIDGET (chart);
}
static char *
format_value_as_memory (SysprofTrack *track,
SysprofDocumentCounterValue *value,
SysprofDocument *document)
{
const SysprofTimeSpan *span = sysprof_document_get_time_span (document);
gint64 v = sysprof_document_counter_value_get_value_int64 (value);
gint64 t = sysprof_document_counter_value_get_time (value) - span->begin_nsec;
g_autofree char *vstr = g_format_size (v);
g_autofree char *tstr = sysprof_time_offset_to_string (t);
return g_strdup_printf ("%s: %s", tstr, vstr);
}
static void
sysprof_session_discover_counters (SysprofSession *self,
SysprofDocument *document,
GListStore *tracks)
{
g_autoptr(GListModel) counters = NULL;
g_assert (SYSPROF_IS_SESSION (self));
g_assert (SYSPROF_IS_DOCUMENT (document));
g_assert (G_IS_LIST_STORE (tracks));
counters = sysprof_document_list_counters (document);
for (guint i = 0; i < G_N_ELEMENTS (discovery_counters); i++)
{
const SysprofTrackCounter *info = &discovery_counters[i];
g_autoptr(GListModel) track_counters = filter_counters (counters, info->category, info->name);
if (track_counters != NULL)
{
g_autoptr(SysprofTrack) track = NULL;
g_autoptr(GListModel) subtrack_counters = NULL;
SysprofTrackCounterChart *chart;
SysprofColorIter iter;
sysprof_color_iter_init (&iter);
chart = g_new0 (SysprofTrackCounterChart, 1);
g_set_weak_pointer (&chart->session, self);
chart->document = g_object_ref (document);
chart->counters = g_object_ref (track_counters);
chart->info = info;
chart->apply_range = TRUE;
track = g_object_new (SYSPROF_TYPE_TRACK,
"title", info->track_name,
NULL);
if ((info->flags & LINE_FLAGS_FORMAT_MEMORY) != 0)
g_signal_connect_object (track,
"format-item-for-display",
G_CALLBACK (format_value_as_memory),
document,
0);
g_signal_connect_data (track,
"create-chart",
G_CALLBACK (create_chart_for_counters),
chart,
(GClosureNotify)sysprof_track_counter_chart_free,
0);
if ((subtrack_counters = filter_counters (counters, info->subtracks_category, info->subtracks_name)))
{
guint n_items = g_list_model_get_n_items (subtrack_counters);
for (guint j = 0; j < n_items; j++)
{
g_autoptr(SysprofDocumentCounter) subtrack_counter = g_list_model_get_item (subtrack_counters, j);
g_autoptr(SysprofTrack) subtrack = NULL;
g_autoptr(GListStore) store = g_list_store_new (SYSPROF_TYPE_DOCUMENT_COUNTER);
SysprofTrackCounterChart *subchart;
g_list_store_append (store, subtrack_counter);
subchart = g_new0 (SysprofTrackCounterChart, 1);
g_set_weak_pointer (&subchart->session, self);
subchart->document = g_object_ref (document);
subchart->counters = g_object_ref (G_LIST_MODEL (store));
subchart->info = info;
subchart->apply_range = !(info->flags & LINE_FLAGS_IGNORE_RANGE_ON_SUBCHART);
subchart->color = *sysprof_color_iter_next (&iter);
subtrack = g_object_new (SYSPROF_TYPE_TRACK,
"title", sysprof_document_counter_get_name (subtrack_counter),
NULL);
if ((info->flags & LINE_FLAGS_FORMAT_MEMORY) != 0)
g_signal_connect_object (subtrack,
"format-item-for-display",
G_CALLBACK (format_value_as_memory),
document,
0);
g_signal_connect_data (subtrack,
"create-chart",
G_CALLBACK (create_chart_for_counters),
subchart,
(GClosureNotify)sysprof_track_counter_chart_free,
0);
_sysprof_track_add_subtrack (track, subtrack);
}
}
g_list_store_append (tracks, track);
}
}
}
static gboolean
activate_mark_cb (SysprofSession *session,
SysprofTimeSpanLayer *layer,
SysprofDocumentMark *mark,
SysprofChart *chart)
{
gint64 duration;
g_assert (SYSPROF_IS_SESSION (session));
g_assert (SYSPROF_IS_TIME_SPAN_LAYER (layer));
g_assert (SYSPROF_IS_DOCUMENT_MARK (mark));
g_assert (SYSPROF_IS_CHART (chart));
if ((duration = sysprof_document_mark_get_duration (mark)))
{
gint64 t = sysprof_document_frame_get_time (SYSPROF_DOCUMENT_FRAME (mark));
SysprofTimeSpan span = { t, t + duration };
sysprof_session_select_time (session, &span);
sysprof_session_zoom_to_selection (session);
return TRUE;
}
return FALSE;
}
static GtkWidget *
create_chart_for_marks (SysprofTrack *track,
SysprofTrackMarksChart *info)
{
g_autoptr(SysprofSeries) time_series = NULL;
SysprofChartLayer *layer;
SysprofChart *chart;
SysprofAxis *x_axis = NULL;
g_assert (SYSPROF_IS_TRACK (track));
g_assert (info != NULL);
g_assert (SYSPROF_IS_SESSION (info->session));
g_assert (SYSPROF_IS_DOCUMENT (info->document));
g_assert (G_IS_LIST_MODEL (info->model));
x_axis = sysprof_session_get_visible_time_axis (info->session);
time_series = sysprof_time_series_new (sysprof_track_get_title (track),
g_object_ref (G_LIST_MODEL (info->model)),
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_MARK, NULL, "time"),
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_MARK, NULL, "duration"),
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_MARK, NULL, "message"));
chart = g_object_new (SYSPROF_TYPE_CHART, NULL);
g_signal_connect_object (chart,
"activate-layer-item",
G_CALLBACK (activate_mark_cb),
info->session,
G_CONNECT_SWAPPED);
layer = g_object_new (SYSPROF_TYPE_TIME_SPAN_LAYER,
"series", time_series,
"axis", x_axis,
NULL);
sysprof_chart_add_layer (chart, layer);
return GTK_WIDGET (chart);
}
static void
sysprof_session_discover_marks (SysprofSession *self,
SysprofDocument *document,
GListStore *tracks)
{
g_autoptr(GListModel) catalogs = NULL;
g_autoptr(SysprofTrack) toplevel = NULL;
SysprofTrackMarksChart *topchart;
guint n_catalogs;
g_assert (SYSPROF_IS_SESSION (self));
g_assert (SYSPROF_IS_DOCUMENT (document));
g_assert (G_IS_LIST_STORE (tracks));
catalogs = sysprof_document_catalog_marks (document);
n_catalogs = g_list_model_get_n_items (catalogs);
if (n_catalogs == 0)
return;
toplevel = g_object_new (SYSPROF_TYPE_TRACK,
"title", _("Points of Interest"),
NULL);
topchart = g_new0 (SysprofTrackMarksChart, 1);
g_set_weak_pointer (&topchart->session, self);
topchart->document = g_object_ref (document);
topchart->model = sysprof_document_list_marks (document);
g_signal_connect_data (toplevel,
"create-chart",
G_CALLBACK (create_chart_for_marks),
topchart,
(GClosureNotify)sysprof_track_marks_chart_free,
0);
for (guint i = 0; i < n_catalogs; i++)
{
g_autoptr(GListModel) by_group = g_list_model_get_item (catalogs, i);
g_autoptr(SysprofMarkCatalog) first = g_list_model_get_item (by_group, 0);
g_autoptr(SysprofTrack) track = NULL;
SysprofTrackMarksChart *chart;
const char *group;
guint n_names;
if (first == NULL)
continue;
n_names = g_list_model_get_n_items (G_LIST_MODEL (by_group));
group = sysprof_mark_catalog_get_group (first);
chart = g_new0 (SysprofTrackMarksChart, 1);
g_set_weak_pointer (&chart->session, self);
chart->document = g_object_ref (document);
chart->model = sysprof_document_list_marks_by_group (document, group);
track = g_object_new (SYSPROF_TYPE_TRACK,
"title", sysprof_mark_catalog_get_group (first),
NULL);
g_signal_connect_data (track,
"create-chart",
G_CALLBACK (create_chart_for_marks),
chart,
(GClosureNotify)sysprof_track_marks_chart_free,
0);
_sysprof_track_add_subtrack (toplevel, track);
for (guint j = 0; j < n_names; j++)
{
g_autoptr(SysprofMarkCatalog) catalog = g_list_model_get_item (by_group, j);
g_autoptr(SysprofTrack) subtrack = NULL;
SysprofTrackMarksChart *subchart;
subchart = g_new0 (SysprofTrackMarksChart, 1);
g_set_weak_pointer (&subchart->session, self);
subchart->document = g_object_ref (document);
subchart->model = g_object_ref (G_LIST_MODEL (catalog));
subtrack = g_object_new (SYSPROF_TYPE_TRACK,
"title", sysprof_mark_catalog_get_name (catalog),
NULL);
g_signal_connect_data (subtrack,
"create-chart",
G_CALLBACK (create_chart_for_marks),
subchart,
(GClosureNotify)sysprof_track_marks_chart_free,
0);
_sysprof_track_add_subtrack (track, subtrack);
}
}
g_list_store_append (tracks, toplevel);
}
void
_sysprof_session_discover_tracks (SysprofSession *self,
SysprofDocument *document,
GListStore *tracks)
{
g_assert (SYSPROF_IS_SESSION (self));
g_assert (SYSPROF_IS_DOCUMENT (document));
g_assert (G_IS_LIST_STORE (tracks));
sysprof_session_discover_sampler (self, document, tracks);
sysprof_session_discover_counters (self, document, tracks);
sysprof_session_discover_marks (self, document, tracks);
}

View File

@ -1,33 +0,0 @@
/* sysprof-track-private.h
*
* 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
*/
#pragma once
#include "sysprof-track.h"
G_BEGIN_DECLS
GtkWidget *_sysprof_track_create_chart (SysprofTrack *self);
void _sysprof_track_add_subtrack (SysprofTrack *self,
SysprofTrack *subtrack);
char *_sysprof_track_format_item_for_display (SysprofTrack *self,
gpointer item);
G_END_DECLS

View File

@ -1,164 +0,0 @@
/* sysprof-track-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 "sysprof-track-private.h"
#include "sysprof-track-view.h"
struct _SysprofTrackView
{
GtkWidget parent_instance;
SysprofTrack *track;
};
enum {
PROP_0,
PROP_TRACK,
N_PROPS
};
G_DEFINE_FINAL_TYPE (SysprofTrackView, sysprof_track_view, GTK_TYPE_WIDGET)
static GParamSpec *properties [N_PROPS];
static void
sysprof_track_view_dispose (GObject *object)
{
SysprofTrackView *self = (SysprofTrackView *)object;
GtkWidget *child;
gtk_widget_dispose_template (GTK_WIDGET (self), SYSPROF_TYPE_TRACK_VIEW);
g_clear_object (&self->track);
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
gtk_widget_unparent (child);
G_OBJECT_CLASS (sysprof_track_view_parent_class)->dispose (object);
}
static void
sysprof_track_view_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
SysprofTrackView *self = SYSPROF_TRACK_VIEW (object);
switch (prop_id)
{
case PROP_TRACK:
g_value_set_object (value, sysprof_track_view_get_track (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sysprof_track_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
SysprofTrackView *self = SYSPROF_TRACK_VIEW (object);
switch (prop_id)
{
case PROP_TRACK:
sysprof_track_view_set_track (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sysprof_track_view_class_init (SysprofTrackViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = sysprof_track_view_dispose;
object_class->get_property = sysprof_track_view_get_property;
object_class->set_property = sysprof_track_view_set_property;
properties[PROP_TRACK] =
g_param_spec_object ("track", NULL, NULL,
SYSPROF_TYPE_TRACK,
(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_template_from_resource (widget_class, "/libsysprof-gtk/sysprof-track-view.ui");
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
g_type_ensure (SYSPROF_TYPE_TRACK);
}
static void
sysprof_track_view_init (SysprofTrackView *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
GtkWidget *
sysprof_track_view_new (void)
{
return g_object_new (SYSPROF_TYPE_TRACK_VIEW, NULL);
}
/**
* sysprof_track_view_get_track:
* @self: a #SysprofTrackView
*
* Returns: (transfer none) (nullable): A #SysprofTrack or %NULL
*/
SysprofTrack *
sysprof_track_view_get_track (SysprofTrackView *self)
{
g_return_val_if_fail (SYSPROF_IS_TRACK_VIEW (self), NULL);
return self->track;
}
void
sysprof_track_view_set_track (SysprofTrackView *self,
SysprofTrack *track)
{
g_return_if_fail (SYSPROF_IS_TRACK_VIEW (self));
g_return_if_fail (!track || SYSPROF_IS_TRACK (track));
if (g_set_object (&self->track, track))
{
GtkWidget *child;
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
gtk_widget_unparent (child);
if ((child = _sysprof_track_create_chart (track)))
gtk_widget_set_parent (child, GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TRACK]);
}
}

View File

@ -1,42 +0,0 @@
/* sysprof-track-view.h
*
* 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
*/
#pragma once
#include <gtk/gtk.h>
#include "sysprof-track.h"
G_BEGIN_DECLS
#define SYSPROF_TYPE_TRACK_VIEW (sysprof_track_view_get_type())
SYSPROF_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (SysprofTrackView, sysprof_track_view, SYSPROF, TRACK_VIEW, GtkWidget)
SYSPROF_AVAILABLE_IN_ALL
GtkWidget *sysprof_track_view_new (void);
SYSPROF_AVAILABLE_IN_ALL
SysprofTrack *sysprof_track_view_get_track (SysprofTrackView *self);
SYSPROF_AVAILABLE_IN_ALL
void sysprof_track_view_set_track (SysprofTrackView *self,
SysprofTrack *track);
G_END_DECLS

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="SysprofTrackView" parent="GtkWidget">
</template>
</interface>

View File

@ -1,271 +0,0 @@
/* sysprof-track.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 "sysprof-track-private.h"
struct _SysprofTrack
{
GObject parent_instance;
SysprofSession *session;
char *title;
GListStore *subtracks;
GMenuModel *menu_model;
};
enum {
PROP_0,
PROP_MENU_MODEL,
PROP_SESSION,
PROP_SUBTRACKS,
PROP_TITLE,
N_PROPS
};
enum {
CREATE_CHART,
FORMAT_ITEM_FOR_DISPLAY,
N_SIGNALS
};
G_DEFINE_FINAL_TYPE (SysprofTrack, sysprof_track, G_TYPE_OBJECT)
static GParamSpec *properties [N_PROPS];
static guint signals[N_SIGNALS];
static void
sysprof_track_dispose (GObject *object)
{
SysprofTrack *self = (SysprofTrack *)object;
g_clear_object (&self->menu_model);
g_clear_object (&self->subtracks);
g_clear_pointer (&self->title, g_free);
g_clear_weak_pointer (&self->session);
G_OBJECT_CLASS (sysprof_track_parent_class)->dispose (object);
}
static void
sysprof_track_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
SysprofTrack *self = SYSPROF_TRACK (object);
switch (prop_id)
{
case PROP_MENU_MODEL:
g_value_set_object (value, sysprof_track_get_menu_model (self));
break;
case PROP_SESSION:
g_value_set_object (value, sysprof_track_get_session (self));
break;
case PROP_SUBTRACKS:
g_value_take_object (value, sysprof_track_list_subtracks (self));
break;
case PROP_TITLE:
g_value_set_string (value, sysprof_track_get_title (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sysprof_track_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
SysprofTrack *self = SYSPROF_TRACK (object);
switch (prop_id)
{
case PROP_MENU_MODEL:
self->menu_model = g_value_dup_object (value);
break;
case PROP_SESSION:
g_set_weak_pointer (&self->session, g_value_get_object (value));
break;
case PROP_TITLE:
self->title = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sysprof_track_class_init (SysprofTrackClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = sysprof_track_dispose;
object_class->get_property = sysprof_track_get_property;
object_class->set_property = sysprof_track_set_property;
properties [PROP_MENU_MODEL] =
g_param_spec_object ("menu-model", NULL, NULL,
G_TYPE_MENU_MODEL,
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
properties [PROP_SESSION] =
g_param_spec_object ("session", NULL, NULL,
SYSPROF_TYPE_SESSION,
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
properties[PROP_SUBTRACKS] =
g_param_spec_object ("subtracks", NULL, NULL,
G_TYPE_LIST_MODEL,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
properties[PROP_TITLE] =
g_param_spec_string ("title", NULL, NULL,
NULL,
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
signals[CREATE_CHART] =
g_signal_new ("create-chart",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
g_signal_accumulator_first_wins, NULL,
NULL,
GTK_TYPE_WIDGET, 0);
signals[FORMAT_ITEM_FOR_DISPLAY] =
g_signal_new ("format-item-for-display",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
g_signal_accumulator_first_wins, NULL,
NULL,
G_TYPE_STRING, 1, G_TYPE_OBJECT);
}
static void
sysprof_track_init (SysprofTrack *self)
{
self->subtracks = g_list_store_new (SYSPROF_TYPE_TRACK);
}
const char *
sysprof_track_get_title (SysprofTrack *self)
{
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
return self->title;
}
void
_sysprof_track_add_subtrack (SysprofTrack *self,
SysprofTrack *subtrack)
{
g_return_if_fail (SYSPROF_IS_TRACK (self));
g_return_if_fail (SYSPROF_IS_TRACK (subtrack));
g_return_if_fail (subtrack != self);
g_list_store_append (self->subtracks, subtrack);
}
/**
* sysprof_track_list_subtracks:
* @self: a #SysprofTrack
*
* Returns: (transfer full) (nullable): a #GListModel of #SysprofTrack
*/
GListModel *
sysprof_track_list_subtracks (SysprofTrack *self)
{
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
if (g_list_model_get_n_items (G_LIST_MODEL (self->subtracks)) == 0)
return NULL;
return g_object_ref (G_LIST_MODEL (self->subtracks));
}
/**
* sysprof_track_get_session:
* @self: a #SysprofTrack
*
* Returns: (transfer none) (nullable): a #SysprofSession or %NULL
*/
SysprofSession *
sysprof_track_get_session (SysprofTrack *self)
{
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
return self->session;
}
/**
* sysprof_track_get_menu_model:
* @self: a #SysprofTrack
*
* Gets the optional menu model for a track.
*
* Returns: (transfer none) (nullable): a #GMenuModel or %NULL
*/
GMenuModel *
sysprof_track_get_menu_model (SysprofTrack *self)
{
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
return self->menu_model;
}
GtkWidget *
_sysprof_track_create_chart (SysprofTrack *self)
{
GtkWidget *ret = NULL;
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
g_signal_emit (self, signals[CREATE_CHART], 0, &ret);
return ret;
}
char *
_sysprof_track_format_item_for_display (SysprofTrack *self,
gpointer item)
{
char *ret = NULL;
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
g_return_val_if_fail (G_IS_OBJECT (item), NULL);
g_signal_emit (self, signals[FORMAT_ITEM_FOR_DISPLAY], 0, item, &ret);
return ret;
}

View File

@ -1,45 +0,0 @@
/* sysprof-track.h
*
* 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
*/
#pragma once
#include <gtk/gtk.h>
#include <sysprof-analyze.h>
#include "sysprof-session.h"
G_BEGIN_DECLS
#define SYSPROF_TYPE_TRACK (sysprof_track_get_type())
SYSPROF_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (SysprofTrack, sysprof_track, SYSPROF, TRACK, GObject)
SYSPROF_AVAILABLE_IN_ALL
SysprofSession *sysprof_track_get_session (SysprofTrack *self);
SYSPROF_AVAILABLE_IN_ALL
const char *sysprof_track_get_title (SysprofTrack *self);
SYSPROF_AVAILABLE_IN_ALL
GListModel *sysprof_track_list_subtracks (SysprofTrack *self);
SYSPROF_AVAILABLE_IN_ALL
GMenuModel *sysprof_track_get_menu_model (SysprofTrack *self);
G_END_DECLS

View File

@ -1,720 +0,0 @@
/* sysprof-tracks-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 "sysprof-chart-layer.h"
#include "sysprof-css-private.h"
#include "sysprof-session-private.h"
#include "sysprof-track-view.h"
#include "sysprof-tracks-view.h"
#include "sysprof-time-ruler.h"
struct _SysprofTracksView
{
GtkWidget parent_instance;
SysprofSession *session;
GtkBox *box;
GtkLabel *informative;
GtkWidget *top_left;
GtkListView *list_view;
SysprofTimeRuler *ruler;
GtkLabel *timecode;
GtkButton *zoom;
double motion_x;
double motion_y;
double drag_start_x;
double drag_start_y;
double drag_offset_x;
double drag_offset_y;
guint in_drag_selection : 1;
};
enum {
PROP_0,
PROP_SESSION,
N_PROPS
};
G_DEFINE_FINAL_TYPE (SysprofTracksView, sysprof_tracks_view, GTK_TYPE_WIDGET)
static GParamSpec *properties [N_PROPS];
static void
set_motion (SysprofTracksView *self,
double x,
double y)
{
gboolean timecode_visible = FALSE;
gboolean informative_visible = FALSE;
GtkWidget *pick;
int ruler_start;
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
if (self->motion_x == x && self->motion_y == y)
return;
self->motion_x = x;
self->motion_y = y;
ruler_start = gtk_widget_get_width (self->top_left);
timecode_visible = x >= ruler_start;
if (timecode_visible)
{
g_autofree char *str = sysprof_time_ruler_get_label_at_point (self->ruler, x - ruler_start);
gtk_label_set_label (self->timecode, str);
}
pick = gtk_widget_pick (GTK_WIDGET (self), x, y, 0);
if (pick != NULL)
{
SysprofChartLayer *layer = SYSPROF_CHART_LAYER (gtk_widget_get_ancestor (pick, SYSPROF_TYPE_CHART_LAYER));
SysprofTrackView *track_view = SYSPROF_TRACK_VIEW (gtk_widget_get_ancestor (pick, SYSPROF_TYPE_TRACK_VIEW));
if (layer != NULL && track_view != NULL)
{
SysprofTrack *track = sysprof_track_view_get_track (track_view);
g_autoptr(GObject) item = NULL;
g_autofree char *text = NULL;
double layer_x;
double layer_y;
gtk_widget_translate_coordinates (GTK_WIDGET (self),
GTK_WIDGET (layer),
x, y, &layer_x, &layer_y);
if ((item = sysprof_chart_layer_lookup_item (layer, layer_x, layer_y)))
text = _sysprof_session_describe (self->session, track, item);
gtk_label_set_label (self->informative, text);
informative_visible = text != NULL;
}
}
gtk_widget_set_visible (GTK_WIDGET (self->timecode), timecode_visible);
gtk_widget_set_visible (GTK_WIDGET (self->informative), informative_visible);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
sysprof_tracks_view_motion_enter_cb (SysprofTracksView *self,
double x,
double y,
GtkEventControllerMotion *motion)
{
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (motion));
set_motion (self, x, y);
}
static void
sysprof_tracks_view_motion_leave_cb (SysprofTracksView *self,
GtkEventControllerMotion *motion)
{
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (motion));
set_motion (self, -1, -1);
}
static void
sysprof_tracks_view_motion_cb (SysprofTracksView *self,
double x,
double y,
GtkEventControllerMotion *motion)
{
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (motion));
set_motion (self, x, y);
}
static void
sysprof_tracks_view_drag_begin_cb (SysprofTracksView *self,
double start_x,
double start_y,
GtkGestureDrag *drag)
{
graphene_rect_t zoom_area;
double x, y;
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
g_assert (GTK_IS_GESTURE_DRAG (drag));
gtk_widget_translate_coordinates (GTK_WIDGET (self->zoom),
GTK_WIDGET (self),
0, 0, &x, &y);
zoom_area = GRAPHENE_RECT_INIT (x, y,
gtk_widget_get_width (GTK_WIDGET (self->zoom)),
gtk_widget_get_height (GTK_WIDGET (self->zoom)));
if (start_x < gtk_widget_get_width (self->top_left) ||
(gtk_widget_get_visible (GTK_WIDGET (self->zoom)) &&
graphene_rect_contains_point (&zoom_area, &GRAPHENE_POINT_INIT (start_x, start_y))))
{
gtk_gesture_set_state (GTK_GESTURE (drag), GTK_EVENT_SEQUENCE_DENIED);
return;
}
self->drag_start_x = start_x;
self->drag_start_y = start_y;
self->drag_offset_x = 0;
self->drag_offset_y = 0;
gtk_widget_set_visible (GTK_WIDGET (self->zoom), FALSE);
self->in_drag_selection = TRUE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
sysprof_tracks_view_drag_end_cb (SysprofTracksView *self,
double offset_x,
double offset_y,
GtkGestureDrag *drag)
{
int base_x;
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
g_assert (GTK_IS_GESTURE_DRAG (drag));
if (self->session == NULL)
goto cleanup;
base_x = gtk_widget_get_width (self->top_left);
if (self->drag_offset_x != .0)
{
graphene_rect_t selection;
graphene_rect_t area;
int width;
int height;
width = gtk_widget_get_width (GTK_WIDGET (self)) - base_x;
height = gtk_widget_get_height (GTK_WIDGET (self));
area = GRAPHENE_RECT_INIT (base_x, 0, width, height);
selection = GRAPHENE_RECT_INIT (self->drag_start_x,
0,
self->drag_offset_x,
height);
graphene_rect_normalize (&selection);
if (graphene_rect_intersection (&area, &selection, &selection))
{
double begin = (selection.origin.x - area.origin.x) / area.size.width;
double end = (selection.origin.x + selection.size.width - area.origin.x) / area.size.width;
const SysprofTimeSpan *visible = sysprof_session_get_visible_time (self->session);
gint64 visible_duration = visible->end_nsec - visible->begin_nsec;
SysprofTimeSpan to_select;
to_select.begin_nsec = visible->begin_nsec + (begin * visible_duration);
to_select.end_nsec = visible->begin_nsec + (end * visible_duration);
sysprof_session_select_time (self->session, &to_select);
}
}
else if (self->drag_start_x >= base_x)
{
sysprof_session_select_time (self->session, sysprof_session_get_visible_time (self->session));
}
cleanup:
self->drag_start_x = -1;
self->drag_start_y = -1;
self->drag_offset_x = 0;
self->drag_offset_y = 0;
self->in_drag_selection = FALSE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
sysprof_tracks_view_drag_update_cb (SysprofTracksView *self,
double offset_x,
double offset_y,
GtkGestureDrag *drag)
{
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
g_assert (GTK_IS_GESTURE_DRAG (drag));
self->drag_offset_x = offset_x,
self->drag_offset_y = offset_y;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static gboolean
get_selected_area (SysprofTracksView *self,
graphene_rect_t *area,
graphene_rect_t *selection)
{
const SysprofTimeSpan *selected;
const SysprofTimeSpan *visible;
SysprofTimeSpan relative;
gint64 time_duration;
double begin;
double end;
int base_x;
int width;
int height;
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
g_assert (area != NULL);
g_assert (selection != NULL);
if (self->session == NULL)
return FALSE;
base_x = gtk_widget_get_width (self->top_left);
width = gtk_widget_get_width (GTK_WIDGET (self)) - base_x;
height = gtk_widget_get_height (GTK_WIDGET (self));
*area = GRAPHENE_RECT_INIT (base_x, 0, width, height);
if (self->in_drag_selection && self->drag_offset_x != .0)
{
*selection = GRAPHENE_RECT_INIT (self->drag_start_x,
0,
self->drag_offset_x,
height);
graphene_rect_normalize (selection);
return graphene_rect_intersection (area, selection, selection);
}
/* If selected range == visible range, then there is no selection */
selected = sysprof_session_get_selected_time (self->session);
visible = sysprof_session_get_visible_time (self->session);
if (memcmp (selected, visible, sizeof *selected) == 0)
return FALSE;
time_duration = sysprof_time_span_duration (*visible);
relative = sysprof_time_span_relative_to (*selected, visible->begin_nsec);
begin = relative.begin_nsec / (double)time_duration;
end = relative.end_nsec / (double)time_duration;
*selection = GRAPHENE_RECT_INIT (area->origin.x + (begin * width),
0,
(end * width) - (begin * width),
area->size.height);
return TRUE;
}
static void
sysprof_tracks_view_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
SysprofTracksView *self = (SysprofTracksView *)widget;
graphene_rect_t area;
graphene_rect_t selection;
GdkRGBA shadow_color;
GdkRGBA line_color;
GdkRGBA color;
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
g_assert (GTK_IS_SNAPSHOT (snapshot));
gtk_widget_snapshot_child (GTK_WIDGET (self), GTK_WIDGET (self->box), snapshot);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
{
GtkStyleContext *style_context = gtk_widget_get_style_context (GTK_WIDGET (self));
gtk_style_context_get_color (style_context, &color);
shadow_color = color;
shadow_color.alpha *= .1;
line_color = color;
line_color.alpha *= .5;
}
G_GNUC_END_IGNORE_DEPRECATIONS
if (get_selected_area (self, &area, &selection))
{
gtk_snapshot_append_color (snapshot,
&shadow_color,
&GRAPHENE_RECT_INIT (area.origin.x,
area.origin.y,
selection.origin.x - area.origin.x,
area.size.height));
gtk_snapshot_append_color (snapshot,
&shadow_color,
&GRAPHENE_RECT_INIT (selection.origin.x + selection.size.width,
area.origin.y,
(area.origin.x + area.size.width) - (selection.origin.x + selection.size.width),
area.size.height));
}
if (self->motion_x != -1 &&
self->motion_y != -1 &&
self->motion_x > gtk_widget_get_width (self->top_left))
gtk_snapshot_append_color (snapshot,
&line_color,
&GRAPHENE_RECT_INIT (self->motion_x, 0, 1,
gtk_widget_get_height (GTK_WIDGET (self))));
if (gtk_widget_get_visible (GTK_WIDGET (self->zoom)))
gtk_widget_snapshot_child (GTK_WIDGET (self), GTK_WIDGET (self->zoom), snapshot);
if (gtk_widget_get_visible (GTK_WIDGET (self->timecode)))
gtk_widget_snapshot_child (GTK_WIDGET (self), GTK_WIDGET (self->timecode), snapshot);
if (gtk_widget_get_visible (GTK_WIDGET (self->informative)))
gtk_widget_snapshot_child (GTK_WIDGET (self), GTK_WIDGET (self->informative), snapshot);
}
static void
sysprof_tracks_view_zoom_to_selection (GtkWidget *widget,
const char *action_name,
GVariant *params)
{
SysprofTracksView *self = (SysprofTracksView *)widget;
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
if (self->session != NULL)
sysprof_session_zoom_to_selection (self->session);
}
static void
sysprof_tracks_view_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
SysprofTracksView *self = (SysprofTracksView *)widget;
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
gtk_widget_measure (GTK_WIDGET (self->box),
orientation,
for_size,
minimum,
natural,
minimum_baseline,
natural_baseline);
}
static void
sysprof_tracks_view_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
SysprofTracksView *self = (SysprofTracksView *)widget;
graphene_rect_t area;
graphene_rect_t selection;
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
gtk_widget_size_allocate (GTK_WIDGET (self->box),
&(GtkAllocation) {0, 0, width, height},
baseline);
if (get_selected_area (self, &area, &selection))
{
graphene_point_t middle;
GtkRequisition min_req;
GtkRequisition nat_req;
/* Position the zoom button in the center of the selected area */
gtk_widget_get_preferred_size (GTK_WIDGET (self->zoom), &min_req, &nat_req);
graphene_rect_get_center (&selection, &middle);
gtk_widget_size_allocate (GTK_WIDGET (self->zoom),
&(GtkAllocation) {
middle.x - (min_req.width/2),
middle.y - (min_req.height/2),
min_req.width,
min_req.height
}, -1);
}
if (gtk_widget_get_visible (GTK_WIDGET (self->timecode)))
{
GtkRequisition min_req;
GtkRequisition nat_req;
gtk_widget_get_preferred_size (GTK_WIDGET (self->timecode), &min_req, &nat_req);
if (self->motion_x + min_req.width < gtk_widget_get_width (GTK_WIDGET (self)))
gtk_widget_size_allocate (GTK_WIDGET (self->timecode),
&(GtkAllocation) {
self->motion_x, 0,
min_req.width, min_req.height
}, -1);
else
gtk_widget_size_allocate (GTK_WIDGET (self->timecode),
&(GtkAllocation) {
self->motion_x - min_req.width, 0,
min_req.width, min_req.height
}, -1);
}
if (gtk_widget_get_visible (GTK_WIDGET (self->informative)))
{
GtkRequisition min_req;
GtkRequisition nat_req;
gtk_widget_get_preferred_size (GTK_WIDGET (self->informative), &min_req, &nat_req);
if (self->motion_x + min_req.width < gtk_widget_get_width (GTK_WIDGET (self)))
gtk_widget_size_allocate (GTK_WIDGET (self->informative),
&(GtkAllocation) {
self->motion_x, self->motion_y,
min_req.width, min_req.height
}, -1);
else
gtk_widget_size_allocate (GTK_WIDGET (self->informative),
&(GtkAllocation) {
self->motion_x - min_req.width, self->motion_y,
min_req.width, min_req.height
}, -1);
}
}
static void
sysprof_tracks_view_dispose (GObject *object)
{
SysprofTracksView *self = (SysprofTracksView *)object;
GtkWidget *child;
sysprof_tracks_view_set_session (self, NULL);
gtk_widget_dispose_template (GTK_WIDGET (self), SYSPROF_TYPE_TRACKS_VIEW);
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
gtk_widget_unparent (child);
G_OBJECT_CLASS (sysprof_tracks_view_parent_class)->dispose (object);
}
static void
sysprof_tracks_view_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
SysprofTracksView *self = SYSPROF_TRACKS_VIEW (object);
switch (prop_id)
{
case PROP_SESSION:
g_value_set_object (value, sysprof_tracks_view_get_session (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sysprof_tracks_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
SysprofTracksView *self = SYSPROF_TRACKS_VIEW (object);
switch (prop_id)
{
case PROP_SESSION:
sysprof_tracks_view_set_session (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sysprof_tracks_view_class_init (SysprofTracksViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = sysprof_tracks_view_dispose;
object_class->get_property = sysprof_tracks_view_get_property;
object_class->set_property = sysprof_tracks_view_set_property;
widget_class->snapshot = sysprof_tracks_view_snapshot;
widget_class->measure = sysprof_tracks_view_measure;
widget_class->size_allocate = sysprof_tracks_view_size_allocate;
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_object_class_install_properties (object_class, N_PROPS, properties);
gtk_widget_class_set_template_from_resource (widget_class, "/libsysprof-gtk/sysprof-tracks-view.ui");
gtk_widget_class_set_css_name (widget_class, "tracks");
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, box);
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, informative);
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, list_view);
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, ruler);
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, timecode);
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, top_left);
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, zoom);
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_motion_enter_cb);
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_motion_leave_cb);
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_motion_cb);
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_drag_begin_cb);
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_drag_end_cb);
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_drag_update_cb);
gtk_widget_class_install_action (widget_class, "zoom-to-selection", NULL, sysprof_tracks_view_zoom_to_selection);
g_type_ensure (SYSPROF_TYPE_TIME_RULER);
g_type_ensure (SYSPROF_TYPE_TRACK_VIEW);
}
static void
sysprof_tracks_view_init (SysprofTracksView *self)
{
_sysprof_css_init ();
gtk_widget_init_template (GTK_WIDGET (self));
}
GtkWidget *
sysprof_tracks_view_new (void)
{
return g_object_new (SYSPROF_TYPE_TRACKS_VIEW, NULL);
}
/**
* sysprof_tracks_view_get_session:
* @self: a #SysprofTracksView
*
* Gets the session for the tracks.
*
* Returns: (transfer none) (nullable): a #SysprofSession or %NULL
*/
SysprofSession *
sysprof_tracks_view_get_session (SysprofTracksView *self)
{
g_return_val_if_fail (SYSPROF_IS_TRACKS_VIEW (self), NULL);
return self->session;
}
static GListModel *
sysprof_tracks_view_create_model_func (gpointer item,
gpointer user_data)
{
g_assert (SYSPROF_IS_TRACK (item));
return sysprof_track_list_subtracks (item);
}
static void
sysprof_tracks_view_notify_time_cb (SysprofTracksView *self,
GParamSpec *pspec,
SysprofSession *session)
{
const SysprofTimeSpan *visible;
const SysprofTimeSpan *selected;
gboolean button_visible;
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
g_assert (SYSPROF_IS_SESSION (session));
visible = sysprof_session_get_visible_time (session);
selected = sysprof_session_get_selected_time (session);
button_visible = memcmp (visible, selected, sizeof *visible) != 0;
gtk_widget_set_visible (GTK_WIDGET (self->zoom), button_visible);
}
void
sysprof_tracks_view_set_session (SysprofTracksView *self,
SysprofSession *session)
{
g_return_if_fail (SYSPROF_IS_TRACKS_VIEW (self));
g_return_if_fail (!session || SYSPROF_IS_SESSION (session));
if (self->session == session)
return;
if (self->session)
{
g_signal_handlers_disconnect_by_func (self->session,
G_CALLBACK (sysprof_tracks_view_notify_time_cb),
self);
gtk_list_view_set_model (self->list_view, NULL);
g_clear_object (&self->session);
}
if (session)
{
g_autoptr(GtkTreeListModel) tree_list_model = NULL;
g_autoptr(GtkNoSelection) no = NULL;
g_autoptr(GListModel) tracks = NULL;
self->session = g_object_ref (session);
tracks = sysprof_session_list_tracks (session);
tree_list_model = gtk_tree_list_model_new (g_object_ref (tracks),
FALSE,
FALSE,
sysprof_tracks_view_create_model_func,
self, NULL);
no = gtk_no_selection_new (g_object_ref (G_LIST_MODEL (tree_list_model)));
gtk_list_view_set_model (self->list_view, GTK_SELECTION_MODEL (no));
g_signal_connect_object (session,
"notify::selected-time",
G_CALLBACK (sysprof_tracks_view_notify_time_cb),
self,
G_CONNECT_SWAPPED);
g_signal_connect_object (session,
"notify::visible-time",
G_CALLBACK (sysprof_tracks_view_notify_time_cb),
self,
G_CONNECT_SWAPPED);
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
}

View File

@ -1,44 +0,0 @@
/* sysprof-tracks-view.h
*
* 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
*/
#pragma once
#include <gtk/gtk.h>
#include <sysprof-analyze.h>
#include "sysprof-session.h"
G_BEGIN_DECLS
#define SYSPROF_TYPE_TRACKS_VIEW (sysprof_tracks_view_get_type())
SYSPROF_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (SysprofTracksView, sysprof_tracks_view, SYSPROF, TRACKS_VIEW, GtkWidget)
SYSPROF_AVAILABLE_IN_ALL
GtkWidget *sysprof_tracks_view_new (void);
SYSPROF_AVAILABLE_IN_ALL
SysprofSession *sysprof_tracks_view_get_session (SysprofTracksView *self);
SYSPROF_AVAILABLE_IN_ALL
void sysprof_tracks_view_set_session (SysprofTracksView *self,
SysprofSession *session);
G_END_DECLS

View File

@ -1,181 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="SysprofTracksView" parent="GtkWidget">
<child>
<object class="GtkBox" id="box">
<child>
<object class="GtkEventControllerMotion" id="motion">
<property name="propagation-phase">capture</property>
<signal name="enter" handler="sysprof_tracks_view_motion_enter_cb" swapped="true"/>
<signal name="leave" handler="sysprof_tracks_view_motion_leave_cb" swapped="true"/>
<signal name="motion" handler="sysprof_tracks_view_motion_cb" swapped="true"/>
</object>
</child>
<child>
<object class="GtkGestureDrag" id="drag">
<property name="propagation-phase">bubble</property>
<signal name="drag-begin" handler="sysprof_tracks_view_drag_begin_cb" swapped="true"/>
<signal name="drag-end" handler="sysprof_tracks_view_drag_end_cb" swapped="true"/>
<signal name="drag-update" handler="sysprof_tracks_view_drag_update_cb" swapped="true"/>
</object>
</child>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkInscription" id="top_left">
<property name="min-chars">30</property>
<property name="nat-chars">30</property>
</object>
</child>
<child>
<object class="SysprofTimeRuler" id="ruler">
<property name="hexpand">true</property>
<binding name="session">
<lookup name="session">SysprofTracksView</lookup>
</binding>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="propagate-natural-height">true</property>
<property name="vexpand">true</property>
<child>
<object class="GtkListView" id="list_view">
<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="GtkBox">
<property name="css-name">track</property>
<child>
<object class="GtkStack">
<property name="css-name">info</property>
<property name="hhomogeneous">true</property>
<property name="vhomogeneous">true</property>
<property name="hexpand">false</property>
<child>
<object class="GtkStackPage">
<property name="child">
<object class="GtkTreeExpander">
<binding name="list-row">
<lookup name="item">GtkListItem</lookup>
</binding>
<property name="child">
<object class="GtkBox">
<property name="spacing">6</property>
<child>
<object class="GtkInscription" id="title">
<property name="hexpand">true</property>
<property name="text-overflow">ellipsize-end</property>
<style>
<class name="heading"/>
</style>
<binding name="text">
<lookup name="title" type="SysprofTrack">
<lookup name="item" type="GtkTreeListRow">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkMenuButton">
<style>
<class name="flat"/>
</style>
<property name="icon-name">view-more-symbolic</property>
<binding name="menu-model">
<lookup name="menu-model" type="SysprofTrack">
<lookup name="item" type="GtkTreeListRow">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="child">
<object class="GtkInscription">
<property name="min-chars">30</property>
<property name="nat-chars">30</property>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="SysprofTrackView">
<property name="hexpand">true</property>
<binding name="track">
<lookup name="item" type="GtkTreeListRow">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</property>
</template>
</interface>
]]>
</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="zoom">
<property name="action-name">zoom-to-selection</property>
<property name="icon-name">zoom-in-symbolic</property>
<property name="valign">center</property>
<property name="halign">center</property>
<property name="visible">false</property>
<style>
<class name="circular"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="timecode">
<property name="css-name">timecode</property>
<property name="can-focus">false</property>
<property name="can-target">false</property>
<property name="visible">false</property>
<property name="xalign">.5</property>
<property name="single-line-mode">true</property>
<property name="width-chars">10</property>
<property name="max-width-chars">10</property>
</object>
</child>
<child>
<object class="GtkLabel" id="informative">
<property name="css-name">informative</property>
<property name="can-focus">false</property>
<property name="can-target">false</property>
<property name="visible">false</property>
<property name="xalign">0</property>
<property name="single-line-mode">true</property>
</object>
</child>
</template>
</interface>

View File

@ -1,44 +0,0 @@
libsysprof_gtk_test_env = [
'G_DEBUG=gc-friendly',
'GSETTINGS_BACKEND=memory',
'MALLOC_CHECK_=2',
]
libsysprof_gtk_testsuite_c_args = [
'-DG_LOG_DOMAIN="libsysprof-gtk"',
'-DG_ENABLE_DEBUG',
'-UG_DISABLE_ASSERT',
'-UG_DISABLE_CAST_CHECKS',
]
libsysprof_gtk_testsuite = {
'test-callgraph' : {'skip': true},
'test-charts' : {'skip': true},
'test-files' : {'skip': true},
'test-processes' : {'skip': true},
'test-tracks' : {'skip': true},
'test-mark-chart' : {'skip': true},
'test-mark-table' : {'skip': true},
}
libsysprof_gtk_testsuite_deps = [
libsysprof_analyze_static_dep,
libsysprof_gtk_static_dep,
]
tests_resources = gnome.compile_resources(
'tests-resources',
'tests.gresource.xml',
c_name: 'tests',
)
foreach test, params: libsysprof_gtk_testsuite
test_exe = executable(test,
['@0@.c'.format(test), tests_resources[0]],
c_args: libsysprof_gtk_testsuite_c_args,
dependencies: libsysprof_gtk_testsuite_deps,
)
if not params.get('skip', false)
test(test, test_exe, env: libsysprof_gtk_test_env)
endif
endforeach

View File

@ -1,180 +0,0 @@
/* test-callgraph.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 <adwaita.h>
#include <gtk/gtk.h>
#include <sysprof-analyze.h>
#include <sysprof-gtk.h>
static GMainLoop *main_loop;
static char *kallsyms_path;
static char *filename;
static gboolean include_threads;
static gboolean hide_system_libraries;
static const GOptionEntry entries[] = {
{ "kallsyms", 'k', 0, G_OPTION_ARG_FILENAME, &kallsyms_path, "The path to kallsyms to use for decoding", "PATH" },
{ "threads", 't', 0, G_OPTION_ARG_NONE, &include_threads, "Include threads in the callgraph" },
{ "hide-system-libraries", 's', 0, G_OPTION_ARG_NONE, &hide_system_libraries, "Hide system libraries in the callgraph" },
{ 0 }
};
static void
load_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
g_autoptr(GtkWidget) view = user_data;
g_autoptr(SysprofDocument) document = NULL;
g_autoptr(GListModel) model = NULL;
g_autoptr(GError) error = NULL;
document = sysprof_document_loader_load_finish (SYSPROF_DOCUMENT_LOADER (object), result, &error);
g_assert_no_error (error);
g_assert_nonnull (document);
model = sysprof_document_list_samples (document);
g_object_set (view,
"document", document,
"traceables", model,
NULL);
}
int
main (int argc,
char *argv[])
{
g_autoptr(GOptionContext) context = g_option_context_new ("- show a callgraph");
g_autoptr(SysprofDocumentLoader) loader = NULL;
g_autoptr(SysprofDocument) document = NULL;
g_autoptr(SysprofMultiSymbolizer) multi = NULL;
g_autoptr(GError) error = NULL;
SysprofCallgraphView *view;
GtkWidget *box;
GtkWidget *hbox;
GtkWidget *status;
GtkWidget *progress;
GtkWidget *message;
GtkWidget *threads;
GtkWidget *system_libs;
GtkWindow *window;
sysprof_clock_init ();
gtk_init ();
adw_init ();
g_option_context_add_main_entries (context, entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s\n", error->message);
return 1;
}
if (argc != 2)
{
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
return 1;
}
filename = argv[1];
main_loop = g_main_loop_new (NULL, FALSE);
multi = sysprof_multi_symbolizer_new ();
if (kallsyms_path)
{
g_autoptr(GFile) kallsyms_file = g_file_new_for_path (kallsyms_path);
GFileInputStream *kallsyms_stream = g_file_read (kallsyms_file, NULL, NULL);
sysprof_multi_symbolizer_take (multi, sysprof_kallsyms_symbolizer_new_for_symbols (G_INPUT_STREAM (kallsyms_stream)));
}
else
{
sysprof_multi_symbolizer_take (multi, sysprof_kallsyms_symbolizer_new ());
}
sysprof_multi_symbolizer_take (multi, sysprof_elf_symbolizer_new ());
sysprof_multi_symbolizer_take (multi, sysprof_jitmap_symbolizer_new ());
loader = sysprof_document_loader_new (filename);
sysprof_document_loader_set_symbolizer (loader, SYSPROF_SYMBOLIZER (multi));
window = g_object_new (GTK_TYPE_WINDOW,
"default-width", 800,
"default-height", 600,
NULL);
box = g_object_new (GTK_TYPE_BOX,
"orientation", GTK_ORIENTATION_VERTICAL,
"spacing", 12,
NULL);
hbox = g_object_new (GTK_TYPE_BOX,
"spacing", 6,
NULL);
gtk_box_append (GTK_BOX (box), hbox);
gtk_box_append (GTK_BOX (hbox), gtk_label_new ("Show Threads"));
threads = g_object_new (GTK_TYPE_SWITCH,
"active", include_threads,
NULL);
gtk_box_append (GTK_BOX (hbox), threads);
gtk_box_append (GTK_BOX (hbox), gtk_label_new ("Hide System Libraries"));
system_libs = g_object_new (GTK_TYPE_SWITCH,
"active", hide_system_libraries,
NULL);
gtk_box_append (GTK_BOX (hbox), system_libs);
view = g_object_new (SYSPROF_TYPE_WEIGHTED_CALLGRAPH_VIEW,
"include-threads", include_threads,
"hide-system-libraries", hide_system_libraries,
"vexpand", TRUE,
NULL);
gtk_box_append (GTK_BOX (box), GTK_WIDGET (view));
g_signal_connect_swapped (window,
"close-request",
G_CALLBACK (g_main_loop_quit),
main_loop);
status = g_object_new (GTK_TYPE_BOX,
"spacing", 6,
NULL);
message = g_object_new (GTK_TYPE_LABEL,
"xalign", 1.f,
"hexpand", TRUE,
NULL);
progress = g_object_new (GTK_TYPE_PROGRESS_BAR,
NULL);
gtk_box_append (GTK_BOX (status), message);
gtk_box_append (GTK_BOX (status), progress);
gtk_box_append (GTK_BOX (box), status);
gtk_window_set_child (window, box);
gtk_window_present (window);
g_object_bind_property (threads, "active", view, "include-threads", 0);
g_object_bind_property (system_libs, "active", view, "hide-system-libraries", 0);
g_object_bind_property (loader, "message", message, "label", 0);
g_object_bind_property (loader, "fraction", progress, "fraction", 0);
sysprof_document_loader_load_async (loader, NULL, load_cb, g_object_ref (view));
g_main_loop_run (main_loop);
return 0;
}

View File

@ -1,269 +0,0 @@
/* test-charts.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 <adwaita.h>
#include <libpanel.h>
#include <gtk/gtk.h>
#include <sysprof-analyze.h>
#include <sysprof-gtk.h>
static GMainLoop *main_loop;
static char *filename;
static const GOptionEntry entries[] = {
{ 0 }
};
#define TEST_TYPE_CHARTS (test_charts_get_type())
G_DECLARE_FINAL_TYPE (TestCharts, test_charts, TEST, CHARTS, AdwWindow)
struct _TestCharts
{
AdwWindow parent_instance;
SysprofDocument *document;
SysprofSession *session;
};
G_DEFINE_FINAL_TYPE (TestCharts, test_charts, ADW_TYPE_WINDOW)
enum {
PROP_0,
PROP_DOCUMENT,
PROP_SESSION,
N_PROPS
};
static GParamSpec *properties [N_PROPS];
static gboolean
activate_layer_item_cb (SysprofChart *chart,
SysprofChartLayer *layer,
gpointer item,
TestCharts *test)
{
g_assert (SYSPROF_IS_CHART (chart));
g_assert (SYSPROF_IS_CHART_LAYER (layer));
g_assert (G_IS_OBJECT (item));
g_assert (TEST_IS_CHARTS (test));
g_print ("Activated %s in layer '%s' [%s]\n",
G_OBJECT_TYPE_NAME (item),
sysprof_chart_layer_get_title (layer),
G_OBJECT_TYPE_NAME (layer));
if (SYSPROF_IS_DOCUMENT_FRAME (item))
{
g_print ("time_offset=%"G_GINT64_FORMAT" pid=%d\n",
sysprof_document_frame_get_time_offset (item),
sysprof_document_frame_get_pid (item));
}
if (SYSPROF_IS_DOCUMENT_TRACEABLE (item))
{
guint depth = sysprof_document_traceable_get_stack_depth (item);
g_print ("Thread-Id: %u\n",
sysprof_document_traceable_get_thread_id (item));
g_print ("Stack Depth: %u\n", depth);
if (depth <= 128)
{
SysprofSymbol *symbols[128];
SysprofAddressContext final_context;
guint n_symbols = G_N_ELEMENTS (symbols);
n_symbols = sysprof_document_symbolize_traceable (test->document,
item,
symbols,
n_symbols,
&final_context);
for (guint i = 0; i < n_symbols; i++)
g_print (" %s\n", sysprof_symbol_get_name (symbols[i]));
}
}
return GDK_EVENT_STOP;
}
static void
test_charts_set_document (TestCharts *self,
SysprofDocument *document)
{
if (g_set_object (&self->document, document))
{
g_clear_object (&self->session);
self->session = sysprof_session_new (self->document);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DOCUMENT]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
}
}
static void
test_charts_dispose (GObject *object)
{
TestCharts *self = (TestCharts *)object;
g_clear_object (&self->document);
g_clear_object (&self->session);
G_OBJECT_CLASS (test_charts_parent_class)->dispose (object);
}
static void
test_charts_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
TestCharts *self = TEST_CHARTS (object);
switch (prop_id)
{
case PROP_DOCUMENT:
g_value_set_object (value, self->document);
break;
case PROP_SESSION:
g_value_set_object (value, self->session);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
test_charts_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
TestCharts *self = TEST_CHARTS (object);
switch (prop_id)
{
case PROP_DOCUMENT:
test_charts_set_document (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
test_charts_class_init (TestChartsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = test_charts_dispose;
object_class->get_property = test_charts_get_property;
object_class->set_property = test_charts_set_property;
properties [PROP_DOCUMENT] =
g_param_spec_object ("document", NULL, NULL,
SYSPROF_TYPE_DOCUMENT,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties [PROP_SESSION] =
g_param_spec_object ("session", NULL, NULL,
SYSPROF_TYPE_SESSION,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
gtk_widget_class_set_template_from_resource (widget_class, "/test-charts.ui");
gtk_widget_class_bind_template_callback (widget_class, activate_layer_item_cb);
g_type_ensure (SYSPROF_TYPE_CHART);
g_type_ensure (SYSPROF_TYPE_CHART_LAYER);
g_type_ensure (SYSPROF_TYPE_COLUMN_LAYER);
g_type_ensure (SYSPROF_TYPE_LINE_LAYER);
g_type_ensure (SYSPROF_TYPE_DOCUMENT_COUNTER_VALUE);
g_type_ensure (SYSPROF_TYPE_VALUE_AXIS);
g_type_ensure (SYSPROF_TYPE_SESSION_MODEL);
g_type_ensure (SYSPROF_TYPE_SESSION_MODEL_ITEM);
g_type_ensure (SYSPROF_TYPE_DUPLEX_LAYER);
g_type_ensure (SYSPROF_TYPE_TIME_RULER);
}
static void
test_charts_init (TestCharts *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
int
main (int argc,
char *argv[])
{
g_autoptr(GOptionContext) context = g_option_context_new ("- test various charts");
g_autoptr(SysprofDocumentLoader) loader = NULL;
g_autoptr(SysprofDocument) document = NULL;
g_autoptr(GError) error = NULL;
GtkWindow *window;
sysprof_clock_init ();
gtk_init ();
adw_init ();
g_option_context_add_main_entries (context, entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s\n", error->message);
return 1;
}
if (argc != 2)
{
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
return 1;
}
filename = argv[1];
main_loop = g_main_loop_new (NULL, FALSE);
loader = sysprof_document_loader_new (filename);
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
g_error ("Failed to load document: %s", error->message);
window = g_object_new (TEST_TYPE_CHARTS,
"default-width", 800,
"default-height", 600,
"document", document,
NULL);
g_signal_connect_swapped (window,
"close-request",
G_CALLBACK (g_main_loop_quit),
main_loop);
gtk_window_present (window);
g_main_loop_run (main_loop);
return 0;
}

View File

@ -1,303 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="TestCharts" parent="AdwWindow">
<child>
<object class="AdwToolbarView">
<property name="top-bar-style">raised</property>
<child type="top">
<object class="AdwHeaderBar">
</object>
</child>
<property name="content">
<object class="GtkPaned">
<property name="position">200</property>
<child type="start">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="SysprofChart">
<property name="height-request">128</property>
<signal name="activate-layer-item" handler="activate_layer_item_cb"/>
<child>
<object class="SysprofColumnLayer">
<property name="title">Stack Traces</property>
<binding name="x-axis">
<lookup name="selected-time-axis" type="SysprofSession">
<lookup name="session">TestCharts</lookup>
</lookup>
</binding>
<property name="y-axis">
<object class="SysprofValueAxis">
<property name="min-value">0</property>
<property name="max-value">128</property>
</object>
</property>
<property name="series">
<object class="SysprofXYSeries">
<property name="model">
<object class="GtkFilterListModel">
<binding name="filter">
<lookup name="filter" type="SysprofSession">
<lookup name="session">TestCharts</lookup>
</lookup>
</binding>
<binding name="model">
<lookup name="samples" type="SysprofDocument">
<lookup name="document">TestCharts</lookup>
</lookup>
</binding>
</object>
</property>
<property name="x-expression">
<lookup name="time" type="SysprofDocumentFrame"/>
</property>
<property name="y-expression">
<lookup name="stack-depth" type="SysprofDocumentTraceable"/>
</property>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="SysprofChart">
<property name="height-request">128</property>
<signal name="activate-layer-item" handler="activate_layer_item_cb"/>
<child>
<object class="SysprofDuplexLayer">
<property name="upper-layer">
<object class="SysprofLineLayer">
<property name="vexpand">true</property>
<binding name="x-axis">
<lookup name="selected-time-axis" type="SysprofSession">
<lookup name="session">TestCharts</lookup>
</lookup>
</binding>
<property name="y-axis">
<object class="SysprofValueAxis">
<property name="min-value">0</property>
<property name="max-value">128</property>
</object>
</property>
<property name="series">
<object class="SysprofXYSeries">
<property name="model">
<object class="GtkFilterListModel">
<binding name="filter">
<lookup name="filter" type="SysprofSession">
<lookup name="session">TestCharts</lookup>
</lookup>
</binding>
<binding name="model">
<lookup name="samples" type="SysprofDocument">
<lookup name="document">TestCharts</lookup>
</lookup>
</binding>
</object>
</property>
<property name="x-expression">
<lookup name="time" type="SysprofDocumentFrame"/>
</property>
<property name="y-expression">
<lookup name="stack-depth" type="SysprofDocumentTraceable"/>
</property>
</object>
</property>
</object>
</property>
<property name="lower-layer">
<object class="SysprofLineLayer">
<property name="antialias">false</property>
<property name="vexpand">true</property>
<property name="flip-y">true</property>
<binding name="x-axis">
<lookup name="selected-time-axis" type="SysprofSession">
<lookup name="session">TestCharts</lookup>
</lookup>
</binding>
<property name="y-axis">
<object class="SysprofValueAxis">
<property name="min-value">0</property>
<property name="max-value">128</property>
</object>
</property>
<property name="series">
<object class="SysprofXYSeries">
<property name="model">
<object class="GtkFilterListModel">
<binding name="filter">
<lookup name="filter" type="SysprofSession">
<lookup name="session">TestCharts</lookup>
</lookup>
</binding>
<binding name="model">
<lookup name="samples" type="SysprofDocument">
<lookup name="document">TestCharts</lookup>
</lookup>
</binding>
</object>
</property>
<property name="x-expression">
<lookup name="time" type="SysprofDocumentFrame"/>
</property>
<property name="y-expression">
<lookup name="stack-depth" type="SysprofDocumentTraceable"/>
</property>
</object>
</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="end">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkInscription">
<property name="nat-chars">35</property>
<property name="min-chars">35</property>
<property name="margin-end">8</property>
</object>
</child>
<child>
<object class="SysprofTimeRuler" id="ruler">
<property name="height-request">24</property>
<property name="hexpand">true</property>
<binding name="session">
<lookup name="session">TestCharts</lookup>
</binding>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="vexpand">true</property>
<style>
<class name="undershoot-top"/>
</style>
<child>
<object class="GtkListView">
<property name="show-separators">true</property>
<style>
<class name="data-table"/>
</style>
<property name="model">
<object class="GtkNoSelection">
<property name="model">
<object class="SysprofSessionModel">
<property name="session" bind-source="TestCharts" bind-property="session" bind-flags="sync-create"/>
<binding name="model">
<lookup name="counters" type="SysprofDocument">
<lookup name="document">TestCharts</lookup>
</lookup>
</binding>
</object>
</property>
</object>
</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="GtkBox">
<child>
<object class="GtkInscription">
<property name="xalign">1</property>
<property name="nat-chars">35</property>
<property name="min-chars">35</property>
<property name="margin-end">8</property>
<property name="text-overflow">clip</property>
<binding name="text">
<lookup name="name" type="SysprofDocumentCounter">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofChart">
<property name="hexpand">true</property>
<signal name="activate-layer-item" handler="activate_layer_item_cb"/>
<child>
<object class="SysprofLineLayer">
<property name="spline">true</property>
<property name="dashed">true</property>
<property name="fill">true</property>
<binding name="x-axis">
<lookup name="selected-time-axis" type="SysprofSession">
<lookup name="session" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</binding>
<property name="y-axis">
<object class="SysprofValueAxis">
<binding name="min-value">
<lookup name="min-value" type="SysprofDocumentCounter">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</binding>
<binding name="max-value">
<lookup name="max-value" type="SysprofDocumentCounter">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</binding>
</object>
</property>
<property name="series">
<object class="SysprofXYSeries">
<binding name="model">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
<property name="x-expression">
<lookup name="time" type="SysprofDocumentCounterValue"/>
</property>
<property name="y-expression">
<lookup name="value-double" type="SysprofDocumentCounterValue"/>
</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</property>
</template>
</interface>
]]>
</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
</template>
</interface>

View File

@ -1,208 +0,0 @@
/* test-files.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 <adwaita.h>
#include <libpanel.h>
#include <gtk/gtk.h>
#include <sysprof-analyze.h>
#include <sysprof-gtk.h>
static GMainLoop *main_loop;
static char *filename;
static const GOptionEntry entries[] = {
{ 0 }
};
#define TEST_TYPE_FILES (test_files_get_type())
G_DECLARE_FINAL_TYPE (TestFiles, test_files, TEST, FILES, AdwWindow)
struct _TestFiles
{
AdwWindow parent_instance;
SysprofDocument *document;
SysprofSession *session;
};
G_DEFINE_FINAL_TYPE (TestFiles, test_files, ADW_TYPE_WINDOW)
enum {
PROP_0,
PROP_DOCUMENT,
PROP_SESSION,
N_PROPS
};
static GParamSpec *properties [N_PROPS];
static void
test_files_set_document (TestFiles *self,
SysprofDocument *document)
{
if (g_set_object (&self->document, document))
{
g_clear_object (&self->session);
self->session = sysprof_session_new (self->document);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DOCUMENT]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
}
}
static void
test_files_dispose (GObject *object)
{
TestFiles *self = (TestFiles *)object;
g_clear_object (&self->document);
g_clear_object (&self->session);
G_OBJECT_CLASS (test_files_parent_class)->dispose (object);
}
static void
test_files_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
TestFiles *self = TEST_FILES (object);
switch (prop_id)
{
case PROP_DOCUMENT:
g_value_set_object (value, self->document);
break;
case PROP_SESSION:
g_value_set_object (value, self->session);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
test_files_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
TestFiles *self = TEST_FILES (object);
switch (prop_id)
{
case PROP_DOCUMENT:
test_files_set_document (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
test_files_class_init (TestFilesClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = test_files_dispose;
object_class->get_property = test_files_get_property;
object_class->set_property = test_files_set_property;
properties [PROP_DOCUMENT] =
g_param_spec_object ("document", NULL, NULL,
SYSPROF_TYPE_DOCUMENT,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties [PROP_SESSION] =
g_param_spec_object ("session", NULL, NULL,
SYSPROF_TYPE_SESSION,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
gtk_widget_class_set_template_from_resource (widget_class, "/test-files.ui");
g_type_ensure (SYSPROF_TYPE_DOCUMENT_FILE);
}
static void
test_files_init (TestFiles *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
int
main (int argc,
char *argv[])
{
g_autoptr(GOptionContext) context = g_option_context_new ("- test various files");
g_autoptr(SysprofDocumentLoader) loader = NULL;
g_autoptr(SysprofDocument) document = NULL;
g_autoptr(GError) error = NULL;
GtkWindow *window;
sysprof_clock_init ();
gtk_init ();
adw_init ();
g_option_context_add_main_entries (context, entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s\n", error->message);
return 1;
}
if (argc != 2)
{
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
return 1;
}
filename = argv[1];
main_loop = g_main_loop_new (NULL, FALSE);
loader = sysprof_document_loader_new (filename);
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
g_error ("Failed to load document: %s", error->message);
window = g_object_new (TEST_TYPE_FILES,
"default-width", 800,
"default-height", 600,
"document", document,
NULL);
g_signal_connect_swapped (window,
"close-request",
G_CALLBACK (g_main_loop_quit),
main_loop);
gtk_window_present (window);
g_main_loop_run (main_loop);
return 0;
}

View File

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="TestFiles" parent="AdwWindow">
<child>
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar">
</object>
</child>
<property name="content">
<object class="GtkScrolledWindow">
<child>
<object class="GtkListView">
<property name="show-separators">true</property>
<style>
<class name="data-table"/>
</style>
<property name="model">
<object class="GtkNoSelection">
<binding name="model">
<lookup name="files" type="SysprofDocument">
<lookup name="document">TestFiles</lookup>
</lookup>
</binding>
</object>
</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>
<binding name="label">
<lookup name="path" type="SysprofDocumentFile">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]>
</property>
</object>
</property>
</object>
</child>
</object>
</property>
</object>
</child>
</template>
</interface>

View File

@ -1,94 +0,0 @@
/* test-mark-chart.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 <adwaita.h>
#include <gtk/gtk.h>
#include <sysprof-analyze.h>
#include <sysprof-gtk.h>
static GMainLoop *main_loop;
static char *filename;
static const GOptionEntry entries[] = {
{ 0 }
};
int
main (int argc,
char *argv[])
{
g_autoptr(GOptionContext) context = g_option_context_new ("- test the mark chart");
g_autoptr(SysprofDocumentLoader) loader = NULL;
g_autoptr(SysprofDocument) document = NULL;
g_autoptr(SysprofSession) session = NULL;
g_autoptr(GError) error = NULL;
SysprofMarkChart *chart;
GtkWindow *window;
sysprof_clock_init ();
gtk_init ();
adw_init ();
g_option_context_add_main_entries (context, entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s\n", error->message);
return 1;
}
if (argc != 2)
{
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
return 1;
}
filename = argv[1];
main_loop = g_main_loop_new (NULL, FALSE);
loader = sysprof_document_loader_new (filename);
sysprof_document_loader_set_symbolizer (loader, sysprof_no_symbolizer_get ());
g_print ("Loading %s, ignoring embedded symbols...\n", filename);
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
g_error ("Failed to load document: %s", error->message);
session = sysprof_session_new (document);
window = g_object_new (GTK_TYPE_WINDOW,
"default-width", 800,
"default-height", 600,
NULL);
chart = g_object_new (SYSPROF_TYPE_MARK_CHART,
"session", session,
NULL);
g_signal_connect_swapped (window,
"close-request",
G_CALLBACK (g_main_loop_quit),
main_loop);
gtk_window_set_child (window, GTK_WIDGET (chart));
gtk_window_present (window);
g_main_loop_run (main_loop);
return 0;
}

View File

@ -1,94 +0,0 @@
/* test-callgraph.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 <adwaita.h>
#include <gtk/gtk.h>
#include <sysprof-analyze.h>
#include <sysprof-gtk.h>
static GMainLoop *main_loop;
static char *filename;
static const GOptionEntry entries[] = {
{ 0 }
};
int
main (int argc,
char *argv[])
{
g_autoptr(GOptionContext) context = g_option_context_new ("- show a callgraph");
g_autoptr(SysprofDocumentLoader) loader = NULL;
g_autoptr(SysprofDocument) document = NULL;
g_autoptr(SysprofSession) session = NULL;
g_autoptr(GError) error = NULL;
SysprofMarkTable *table;
GtkWindow *window;
sysprof_clock_init ();
gtk_init ();
adw_init ();
g_option_context_add_main_entries (context, entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s\n", error->message);
return 1;
}
if (argc != 2)
{
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
return 1;
}
filename = argv[1];
main_loop = g_main_loop_new (NULL, FALSE);
loader = sysprof_document_loader_new (filename);
sysprof_document_loader_set_symbolizer (loader, sysprof_no_symbolizer_get ());
g_print ("Loading %s, ignoring embedded symbols...\n", filename);
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
g_error ("Failed to load document: %s", error->message);
session = sysprof_session_new (document);
window = g_object_new (GTK_TYPE_WINDOW,
"default-width", 800,
"default-height", 600,
NULL);
table = g_object_new (SYSPROF_TYPE_MARK_TABLE,
"session", session,
NULL);
g_signal_connect_swapped (window,
"close-request",
G_CALLBACK (g_main_loop_quit),
main_loop);
gtk_window_set_child (window, GTK_WIDGET (table));
gtk_window_present (window);
g_main_loop_run (main_loop);
return 0;
}

View File

@ -1,350 +0,0 @@
/* test-processes.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 "tests-resources.h"
#include <adwaita.h>
#include <libpanel.h>
#include <gtk/gtk.h>
#include <sysprof-analyze.h>
#include <sysprof-gtk.h>
static GMainLoop *main_loop;
static char *filename;
static const GOptionEntry entries[] = {
{ 0 }
};
#define TEST_TYPE_SINGLE_MODEL (test_single_model_get_type())
G_DECLARE_FINAL_TYPE (TestSingleModel, test_single_model, TEST, SINGLE_MODEL, GObject)
struct _TestSingleModel
{
GObject parent_instance;
GObject *item;
};
enum {
MODEL_PROP_0,
MODEL_PROP_ITEM,
MODEL_N_PROPS
};
static GParamSpec *model_properties[MODEL_N_PROPS];
static guint
get_n_items (GListModel *model)
{
return TEST_SINGLE_MODEL (model)->item ? 1 : 0;
}
static gpointer
get_item (GListModel *model,
guint position)
{
if (position == 0 && TEST_SINGLE_MODEL (model)->item)
return g_object_ref (TEST_SINGLE_MODEL (model)->item);
return NULL;
}
static GType
get_item_type (GListModel *model)
{
if (TEST_SINGLE_MODEL (model)->item)
return G_OBJECT_TYPE (TEST_SINGLE_MODEL (model)->item);
return G_TYPE_OBJECT;
}
static void
list_model_iface_init (GListModelInterface *iface)
{
iface->get_n_items = get_n_items;
iface->get_item = get_item;
iface->get_item_type = get_item_type;
}
G_DEFINE_FINAL_TYPE_WITH_CODE (TestSingleModel, test_single_model, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
static void
test_single_model_finalize (GObject *object)
{
TestSingleModel *self = (TestSingleModel *)object;
g_clear_object (&self->item);
G_OBJECT_CLASS (test_single_model_parent_class)->finalize (object);
}
static void
test_single_model_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
TestSingleModel *self = TEST_SINGLE_MODEL (object);
switch (prop_id)
{
case MODEL_PROP_ITEM:
g_value_set_object (value, self->item);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
test_single_model_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
TestSingleModel *self = TEST_SINGLE_MODEL (object);
switch (prop_id)
{
case MODEL_PROP_ITEM:
if (self->item != NULL)
{
g_clear_object (&self->item);
g_list_model_items_changed (G_LIST_MODEL (self), 0, 1, 0);
}
self->item = g_value_dup_object (value);
if (self->item != NULL)
g_list_model_items_changed (G_LIST_MODEL (self), 0, 0, 1);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
test_single_model_class_init (TestSingleModelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = test_single_model_finalize;
object_class->get_property = test_single_model_get_property;
object_class->set_property = test_single_model_set_property;
model_properties[MODEL_PROP_ITEM] =
g_param_spec_object ("item", NULL, NULL,
G_TYPE_OBJECT,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, MODEL_N_PROPS, model_properties);
}
static void
test_single_model_init (TestSingleModel *self)
{
}
#define TEST_TYPE_PROCESSES (test_processes_get_type())
G_DECLARE_FINAL_TYPE (TestProcesses, test_processes, TEST, PROCESSES, AdwWindow)
struct _TestProcesses
{
AdwWindow parent_instance;
SysprofDocument *document;
SysprofSession *session;
};
G_DEFINE_FINAL_TYPE (TestProcesses, test_processes, ADW_TYPE_WINDOW)
enum {
PROP_0,
PROP_DOCUMENT,
PROP_SESSION,
N_PROPS
};
static GParamSpec *properties [N_PROPS];
static void
test_processes_set_document (TestProcesses *self,
SysprofDocument *document)
{
if (g_set_object (&self->document, document))
{
g_clear_object (&self->session);
self->session = sysprof_session_new (self->document);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DOCUMENT]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
}
}
static void
test_processes_dispose (GObject *object)
{
TestProcesses *self = (TestProcesses *)object;
g_clear_object (&self->document);
g_clear_object (&self->session);
G_OBJECT_CLASS (test_processes_parent_class)->dispose (object);
}
static void
test_processes_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
TestProcesses *self = TEST_PROCESSES (object);
switch (prop_id)
{
case PROP_DOCUMENT:
g_value_set_object (value, self->document);
break;
case PROP_SESSION:
g_value_set_object (value, self->session);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
test_processes_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
TestProcesses *self = TEST_PROCESSES (object);
switch (prop_id)
{
case PROP_DOCUMENT:
test_processes_set_document (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
test_processes_class_init (TestProcessesClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = test_processes_dispose;
object_class->get_property = test_processes_get_property;
object_class->set_property = test_processes_set_property;
properties [PROP_DOCUMENT] =
g_param_spec_object ("document", NULL, NULL,
SYSPROF_TYPE_DOCUMENT,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties [PROP_SESSION] =
g_param_spec_object ("session", NULL, NULL,
SYSPROF_TYPE_SESSION,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
gtk_widget_class_set_template_from_resource (widget_class, "/test-processes.ui");
g_type_ensure (TEST_TYPE_SINGLE_MODEL);
g_type_ensure (SYSPROF_TYPE_CHART);
g_type_ensure (SYSPROF_TYPE_CHART_LAYER);
g_type_ensure (SYSPROF_TYPE_COLUMN_LAYER);
g_type_ensure (SYSPROF_TYPE_LINE_LAYER);
g_type_ensure (SYSPROF_TYPE_VALUE_AXIS);
g_type_ensure (SYSPROF_TYPE_SESSION_MODEL);
g_type_ensure (SYSPROF_TYPE_SESSION_MODEL_ITEM);
g_type_ensure (SYSPROF_TYPE_TIME_RULER);
g_type_ensure (SYSPROF_TYPE_TIME_SPAN_LAYER);
g_type_ensure (SYSPROF_TYPE_TIME_SERIES);
}
static void
test_processes_init (TestProcesses *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
int
main (int argc,
char *argv[])
{
g_autoptr(GOptionContext) context = g_option_context_new ("- test processes listing");
g_autoptr(SysprofDocumentLoader) loader = NULL;
g_autoptr(SysprofDocument) document = NULL;
g_autoptr(GError) error = NULL;
GtkWindow *window;
sysprof_clock_init ();
gtk_init ();
adw_init ();
g_option_context_add_main_entries (context, entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s\n", error->message);
return 1;
}
if (argc != 2)
{
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
return 1;
}
g_resources_register (tests_get_resource ());
filename = argv[1];
main_loop = g_main_loop_new (NULL, FALSE);
loader = sysprof_document_loader_new (filename);
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
g_error ("Failed to load document: %s", error->message);
window = g_object_new (TEST_TYPE_PROCESSES,
"default-width", 800,
"default-height", 600,
"document", document,
NULL);
g_signal_connect_swapped (window,
"close-request",
G_CALLBACK (g_main_loop_quit),
main_loop);
gtk_window_present (window);
g_main_loop_run (main_loop);
return 0;
}

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="TestProcesses" parent="AdwWindow">
<child>
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar">
</object>
</child>
<property name="content">
<object class="GtkScrolledWindow">
<child>
<object class="GtkListView">
<property name="model">
<object class="GtkNoSelection">
<property name="model">
<object class="SysprofSessionModel">
<property name="session" bind-source="TestProcesses" bind-property="session" bind-flags="sync-create"/>
<binding name="model">
<lookup name="processes" type="SysprofDocument">
<lookup name="document">TestProcesses</lookup>
</lookup>
</binding>
</object>
</property>
</object>
</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="GtkBox">
<property name="height-request">16</property>
<child>
<object class="SysprofChart">
<property name="hexpand">true</property>
<child>
<object class="SysprofTimeSpanLayer">
<binding name="axis">
<lookup name="selected-time-axis" type="SysprofSession">
<lookup name="session" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</binding>
<property name="series">
<object class="SysprofTimeSeries">
<property name="model">
<object class="TestSingleModel">
<binding name="item">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
<property name="begin-time-expression">
<lookup name="time" type="SysprofDocumentFrame"/>
</property>
<property name="end-time-expression">
<lookup name="exit-time" type="SysprofDocumentProcess"/>
</property>
<property name="label-expression">
<lookup name="command-line" type="SysprofDocumentProcess"/>
</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</property>
</template>
</interface>
]]>
</property>
</object>
</property>
</object>
</child>
</object>
</property>
</object>
</child>
</template>
</interface>

View File

@ -1,212 +0,0 @@
/* test-tracks.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 <adwaita.h>
#include <gtk/gtk.h>
#include <libpanel.h>
#include <sysprof-analyze.h>
#include <sysprof-gtk.h>
static GMainLoop *main_loop;
static char *filename;
static const GOptionEntry entries[] = {
{ 0 }
};
#define TEST_TYPE_TRACKS (test_tracks_get_type())
G_DECLARE_FINAL_TYPE (TestTracks, test_tracks, TEST, TRACKS, AdwWindow)
struct _TestTracks
{
AdwWindow parent_instance;
SysprofDocument *document;
SysprofSession *session;
};
G_DEFINE_FINAL_TYPE (TestTracks, test_tracks, ADW_TYPE_WINDOW)
enum {
PROP_0,
PROP_DOCUMENT,
PROP_SESSION,
N_PROPS
};
static GParamSpec *properties [N_PROPS];
static void
test_tracks_set_document (TestTracks *self,
SysprofDocument *document)
{
if (g_set_object (&self->document, document))
{
g_clear_object (&self->session);
self->session = sysprof_session_new (self->document);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DOCUMENT]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
}
}
static void
test_tracks_dispose (GObject *object)
{
TestTracks *self = (TestTracks *)object;
g_clear_object (&self->document);
g_clear_object (&self->session);
G_OBJECT_CLASS (test_tracks_parent_class)->dispose (object);
}
static void
test_tracks_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
TestTracks *self = TEST_TRACKS (object);
switch (prop_id)
{
case PROP_DOCUMENT:
g_value_set_object (value, self->document);
break;
case PROP_SESSION:
g_value_set_object (value, self->session);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
test_tracks_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
TestTracks *self = TEST_TRACKS (object);
switch (prop_id)
{
case PROP_DOCUMENT:
test_tracks_set_document (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
test_tracks_class_init (TestTracksClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = test_tracks_dispose;
object_class->get_property = test_tracks_get_property;
object_class->set_property = test_tracks_set_property;
properties [PROP_DOCUMENT] =
g_param_spec_object ("document", NULL, NULL,
SYSPROF_TYPE_DOCUMENT,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties [PROP_SESSION] =
g_param_spec_object ("session", NULL, NULL,
SYSPROF_TYPE_SESSION,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
gtk_widget_class_set_template_from_resource (widget_class, "/test-tracks.ui");
g_type_ensure (SYSPROF_TYPE_TRACKS_VIEW);
g_type_ensure (SYSPROF_TYPE_MARK_CHART);
g_type_ensure (SYSPROF_TYPE_MARK_TABLE);
g_type_ensure (SYSPROF_TYPE_WEIGHTED_CALLGRAPH_VIEW);
}
static void
test_tracks_init (TestTracks *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
int
main (int argc,
char *argv[])
{
g_autoptr(GOptionContext) context = g_option_context_new ("- test track layout");
g_autoptr(SysprofDocumentLoader) loader = NULL;
g_autoptr(SysprofDocument) document = NULL;
g_autoptr(GError) error = NULL;
GtkWindow *window;
sysprof_clock_init ();
gtk_init ();
adw_init ();
panel_init ();
g_option_context_add_main_entries (context, entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s\n", error->message);
return 1;
}
if (argc != 2)
{
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
return 1;
}
filename = argv[1];
main_loop = g_main_loop_new (NULL, FALSE);
loader = sysprof_document_loader_new (filename);
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
g_error ("Failed to load document: %s", error->message);
window = g_object_new (TEST_TYPE_TRACKS,
"default-width", 800,
"default-height", 600,
"document", document,
NULL);
g_signal_connect_swapped (window,
"close-request",
G_CALLBACK (g_main_loop_quit),
main_loop);
gtk_window_present (window);
g_main_loop_run (main_loop);
return 0;
}

View File

@ -1,222 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="TestTracks" parent="AdwWindow">
<child>
<object class="AdwToolbarView">
<property name="top-bar-style">raised</property>
<property name="bottom-bar-style">raised</property>
<child type="top">
<object class="AdwHeaderBar">
<child type="start">
<object class="GtkMenuButton">
<child>
<object class="GtkBox">
<property name="spacing">3</property>
<child>
<object class="GtkLabel">
<property name="label">Open</property>
</object>
</child>
<child>
<object class="GtkImage">
<property name="icon-name">pan-down-symbolic</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="title">
<object class="PanelOmniBar">
<property name="menu-model">omni_menu</property>
<child type="prefix">
<object class="GtkInscription">
<property name="min-chars">25</property>
<property name="nat-chars">25</property>
<property name="valign">center</property>
<property name="text-overflow">ellipsize-end</property>
<binding name="text">
<lookup name="title" type="AdwTabPage">
<lookup name="selected-page">tracks_view</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</child>
<child type="end">
<object class="GtkMenuButton">
<property name="icon-name">open-menu-symbolic</property>
<property name="menu-model">primary_menu</property>
<property name="primary">true</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton">
<property name="icon-name">document-properties-symbolic</property>
<property name="menu-model">view_menu</property>
</object>
</child>
</object>
</child>
<child type="top">
<object class="AdwTabBar">
<property name="view">tracks_view</property>
</object>
</child>
<property name="content">
<object class="GtkPaned">
<property name="orientation">vertical</property>
<child>
<object class="AdwTabView" id="tracks_view">
<child>
<object class="AdwTabPage">
<binding name="title">
<lookup name="title" type="SysprofDocument">
<lookup name="document" type="SysprofSession">
<lookup name="session">TestTracks</lookup>
</lookup>
</lookup>
</binding>
<property name="child">
<object class="SysprofTracksView">
<binding name="session">
<lookup name="session">TestTracks</lookup>
</binding>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="vexpand">true</property>
<child>
<object class="GtkStackSwitcher">
<property name="halign">center</property>
<property name="stack">data_stack</property>
<property name="margin-top">3</property>
<property name="margin-bottom">3</property>
</object>
</child>
<child>
<object class="GtkStack" id="data_stack">
<property name="vexpand">true</property>
<child>
<object class="GtkStackPage">
<property name="title">Callgraph</property>
<property name="child">
<object class="SysprofWeightedCallgraphView">
<binding name="document">
<lookup name="document" type="SysprofSession">
<lookup name="session">TestTracks</lookup>
</lookup>
</binding>
<binding name="traceables">
<lookup name="samples" type="SysprofDocument">
<lookup name="document" type="SysprofSession">
<lookup name="session">TestTracks</lookup>
</lookup>
</lookup>
</binding>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="title">Mark Chart</property>
<property name="child">
<object class="SysprofMarkChart">
<binding name="session">
<lookup name="session">TestTracks</lookup>
</binding>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="title">Mark Table</property>
<property name="child">
<object class="SysprofMarkTable">
<binding name="session">
<lookup name="session">TestTracks</lookup>
</binding>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
<child type="bottom">
<object class="PanelStatusbar">
<child type="suffix">
<object class="PanelToggleButton">
<property name="area">bottom</property>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
<menu id="primary_menu">
<section>
<item>
<attribute name="label">Preferences</attribute>
</item>
<item>
<attribute name="label">Keyboard Shortcuts</attribute>
<attribute name="accel">&lt;ctrl&gt;question</attribute>
</item>
<item>
<attribute name="label">Help</attribute>
</item>
<item>
<attribute name="label">About Sysprof</attribute>
</item>
</section>
</menu>
<menu id="view_menu">
<section>
<attribute name="label">Callgraph</attribute>
<item><attribute name="label">Show Threads</attribute></item>
<item><attribute name="label">Show System Libraries</attribute></item>
</section>
</menu>
<menu id="omni_menu">
<section>
<attribute name="label">Profiling</attribute>
<item><attribute name="label">Sample Native Stacks</attribute></item>
<item><attribute name="label">Sample JavaScript Stacks</attribute></item>
<item><attribute name="label">Trace Memory Allocations</attribute></item>
</section>
<section>
<attribute name="label">Graphics</attribute>
<item><attribute name="label">Display Timings</attribute></item>
</section>
<section>
<attribute name="label">Counters</attribute>
<item><attribute name="label">CPU Usage</attribute></item>
<item><attribute name="label">Memory Usage</attribute></item>
<item><attribute name="label">Storage I/O</attribute></item>
<item><attribute name="label">Network I/O</attribute></item>
</section>
<section>
<attribute name="label">Energy</attribute>
<item><attribute name="label">Consumption</attribute></item>
<item><attribute name="label">Battery Charge</attribute></item>
</section>
<section>
<item><attribute name="label">Allow Application Integration</attribute></item>
<item><attribute name="label">Allow CPU Throttling</attribute></item>
</section>
</menu>
</interface>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<gresources>
<gresource prefix="/">
<file preprocess="xml-stripblanks">test-charts.ui</file>
<file preprocess="xml-stripblanks">test-files.ui</file>
<file preprocess="xml-stripblanks">test-processes.ui</file>
<file preprocess="xml-stripblanks">test-tracks.ui</file>
</gresource>
</gresources>

View File

@ -72,9 +72,6 @@ endif
if get_option('libsysprof') or get_option('agent')
subdir('libsysprof')
endif
if get_option('gtk') and get_option('libsysprof')
subdir('libsysprof-gtk')
endif
if get_option('gtk') and get_option('libsysprof')
subdir('sysprof')
endif

View File

@ -1,26 +1,61 @@
sysprof_sources = [
'main.c',
'sysprof-application.c',
'sysprof-axis.c',
'sysprof-callgraph-view.c',
'sysprof-chart-layer.c',
'sysprof-chart.c',
'sysprof-color-iter.c',
'sysprof-column-layer.c',
'sysprof-counters-section.c',
'sysprof-cpu-info-dialog.c',
'sysprof-cpu-section.c',
'sysprof-css.c',
'sysprof-duplex-layer.c',
'sysprof-files-section.c',
'sysprof-frame-utility.c',
'sysprof-greeter.c',
'sysprof-line-layer.c',
'sysprof-logs-section.c',
'sysprof-mark-chart-item.c',
'sysprof-mark-chart-row.c',
'sysprof-mark-chart.c',
'sysprof-mark-table.c',
'sysprof-marks-section.c',
'sysprof-memory-callgraph-view.c',
'sysprof-memory-section.c',
'sysprof-metadata-section.c',
'sysprof-normalized-series-item.c',
'sysprof-normalized-series.c',
'sysprof-process-dialog.c',
'sysprof-processes-section.c',
'sysprof-progress-cell.c',
'sysprof-recording-pad.c',
'sysprof-samples-section.c',
'sysprof-scheduler.c',
'sysprof-section.c',
'sysprof-series.c',
'sysprof-session-model-item.c',
'sysprof-session-model.c',
'sysprof-session.c',
'sysprof-sidebar.c',
'sysprof-single-model.c',
'sysprof-split-layer.c',
'sysprof-symbol-label.c',
'sysprof-time-filter-model.c',
'sysprof-time-label.c',
'sysprof-time-ruler.c',
'sysprof-time-scrubber.c',
'sysprof-time-series-item.c',
'sysprof-time-series.c',
'sysprof-time-span-layer.c',
'sysprof-traceables-utility.c',
'sysprof-value-axis.c',
'sysprof-weighted-callgraph-view.c',
'sysprof-window.c',
'sysprof-xy-layer.c',
'sysprof-xy-series-item.c',
'sysprof-xy-series.c',
]
sysprof_resources = gnome.compile_resources('sysprof-resources', 'sysprof.gresource.xml',
@ -30,11 +65,11 @@ sysprof_resources = gnome.compile_resources('sysprof-resources', 'sysprof.gresou
sysprof_deps = [
cc.find_library('m', required: false),
dependency('gtk4', version: gtk_req_version),
dependency('libadwaita-1', version: '>= 1.4.alpha'),
dependency('libpanel-1', version: '>= 1.3.0'),
libsysprof_analyze_static_dep,
libsysprof_profile_static_dep,
libsysprof_gtk_static_dep,
]
sysprof = executable('sysprof', sysprof_resources + sysprof_sources,

View File

@ -73,9 +73,7 @@ timeruler {
}
timescrubber informative,
timescrubber timecode,
tracks informative,
tracks timecode {
timescrubber timecode {
border-radius: 7px;
background: @accent_bg_color;
color: @accent_fg_color;
@ -87,24 +85,6 @@ tracks timecode {
font-size: .9em;
}
tracks track chart {
margin-top: 1px;
}
tracks track info {
background: alpha(@borders, .25);
}
tracks track info button {
min-height: 0px;
min-width: 0px;
}
tracks row {
padding: 0;
margin: 0;
}
tracks row track info {
padding: 1px 0 0 0;
}
.utility .view {
background: transparent;
}

View File

@ -22,7 +22,7 @@
#include <libpanel.h>
#include "libsysprof-gtk-resources.h"
#include "sysprof-resources.h"
#include "sysprof-callgraph-view-private.h"
#include "sysprof-symbol-label-private.h"
@ -441,7 +441,7 @@ sysprof_callgraph_view_class_init (SysprofCallgraphViewClass *klass)
klass->augment_size = GLIB_SIZEOF_VOID_P;
g_resources_register (libsysprof_gtk_get_resource ());
g_resources_register (sysprof_get_resource ());
g_type_ensure (PANEL_TYPE_PANED);
g_type_ensure (SYSPROF_TYPE_SYMBOL_LABEL);

View File

@ -20,9 +20,12 @@
#include "config.h"
#include <sysprof-gtk.h>
#include "sysprof-chart.h"
#include "sysprof-counters-section.h"
#include "sysprof-line-layer.h"
#include "sysprof-time-series.h"
#include "sysprof-time-span-layer.h"
#include "sysprof-xy-series.h"
struct _SysprofCountersSection
{

View File

@ -20,12 +20,15 @@
#include "config.h"
#include <sysprof-gtk.h>
#include "sysprof-chart.h"
#include "sysprof-cpu-section.h"
#include "sysprof-line-layer.h"
#include "sysprof-time-filter-model.h"
#include "sysprof-time-scrubber.h"
#include "sysprof-time-series.h"
#include "sysprof-time-span-layer.h"
#include "sysprof-value-axis.h"
#include "sysprof-xy-series.h"
struct _SysprofCpuSection
{

View File

@ -20,7 +20,7 @@
#include "config.h"
#include "libsysprof-gtk-resources.h"
#include "sysprof-resources.h"
#include "sysprof-css-private.h"
@ -31,7 +31,7 @@ _sysprof_css_init (void)
if (css == NULL)
{
g_resources_register (libsysprof_gtk_get_resource ());
g_resources_register (sysprof_get_resource ());
css = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (css, "/libsysprof-gtk/style.css");

View File

@ -23,9 +23,9 @@
#include <glib/gi18n.h>
#include <adwaita.h>
#include <sysprof-gtk.h>
#include "sysprof-files-section.h"
#include "sysprof-time-label.h"
struct _SysprofFilesSection
{

View File

@ -20,9 +20,8 @@
#include "config.h"
#include <sysprof-gtk.h>
#include "sysprof-frame-utility.h"
#include "sysprof-session.h"
struct _SysprofFrameUtility
{

View File

@ -22,11 +22,13 @@
#include <glib/gi18n.h>
#include <sysprof-gtk.h>
#include "sysprof-chart.h"
#include "sysprof-document-bitset-index-private.h"
#include "sysprof-frame-utility.h"
#include "sysprof-logs-section.h"
#include "sysprof-time-label.h"
#include "sysprof-time-series.h"
#include "sysprof-time-span-layer.h"
struct _SysprofLogsSection
{

View File

@ -25,7 +25,7 @@
#include "sysprof-mark-chart-item-private.h"
#include "sysprof-mark-chart-row-private.h"
#include "libsysprof-gtk-resources.h"
#include "sysprof-resources.h"
struct _SysprofMarkChart
{
@ -164,7 +164,7 @@ sysprof_mark_chart_class_init (SysprofMarkChartClass *klass)
gtk_widget_class_bind_template_child (widget_class, SysprofMarkChart, box);
gtk_widget_class_bind_template_child (widget_class, SysprofMarkChart, list_view);
g_resources_register (libsysprof_gtk_get_resource ());
g_resources_register (sysprof_get_resource ());
g_type_ensure (SYSPROF_TYPE_MARK_CHART_ITEM);
g_type_ensure (SYSPROF_TYPE_MARK_CHART_ROW);

View File

@ -25,7 +25,7 @@
#include "sysprof-mark-table.h"
#include "sysprof-time-label.h"
#include "libsysprof-gtk-resources.h"
#include "sysprof-resources.h"
struct _SysprofMarkTable
{
@ -149,7 +149,7 @@ sysprof_mark_table_class_init (SysprofMarkTableClass *klass)
gtk_widget_class_bind_template_child (widget_class, SysprofMarkTable, start_column);
gtk_widget_class_bind_template_callback (widget_class, sysprof_mark_table_activate_cb);
g_resources_register (libsysprof_gtk_get_resource ());
g_resources_register (sysprof_get_resource ());
g_type_ensure (SYSPROF_TYPE_DOCUMENT_MARK);
g_type_ensure (SYSPROF_TYPE_TIME_FILTER_MODEL);

View File

@ -20,9 +20,14 @@
#include "config.h"
#include <sysprof-gtk.h>
#include "sysprof-chart.h"
#include "sysprof-mark-chart.h"
#include "sysprof-mark-table.h"
#include "sysprof-marks-section.h"
#include "sysprof-session-model.h"
#include "sysprof-session-model-item.h"
#include "sysprof-time-series.h"
#include "sysprof-time-span-layer.h"
struct _SysprofMarksSection
{

View File

@ -20,15 +20,22 @@
#include "config.h"
#include <sysprof-gtk.h>
#include "sysprof-chart.h"
#include "sysprof-column-layer.h"
#include "sysprof-memory-callgraph-view.h"
#include "sysprof-memory-section.h"
#include "sysprof-session-model-item.h"
#include "sysprof-session-model.h"
#include "sysprof-time-series.h"
#include "sysprof-time-span-layer.h"
#include "sysprof-value-axis.h"
#include "sysprof-xy-series.h"
struct _SysprofMemorySection
{
SysprofSection parent_instance;
SysprofWeightedCallgraphView *callgraph_view;
SysprofMemoryCallgraphView *callgraph_view;
};
G_DEFINE_FINAL_TYPE (SysprofMemorySection, sysprof_memory_section, SYSPROF_TYPE_SECTION)

View File

@ -23,9 +23,9 @@
#include <glib/gi18n.h>
#include <adwaita.h>
#include <sysprof-gtk.h>
#include "sysprof-metadata-section.h"
#include "sysprof-time-label.h"
struct _SysprofMetadataSection
{

View File

@ -23,11 +23,19 @@
#include <glib/gi18n.h>
#include <adwaita.h>
#include <sysprof-gtk.h>
#include "sysprof-chart-layer.h"
#include "sysprof-chart.h"
#include "sysprof-document-process.h"
#include "sysprof-process-dialog.h"
#include "sysprof-processes-section.h"
#include "sysprof-session-model-item.h"
#include "sysprof-session-model.h"
#include "sysprof-single-model.h"
#include "sysprof-time-label.h"
#include "sysprof-time-series.h"
#include "sysprof-time-span-layer.h"
#include "sysprof-value-axis.h"
struct _SysprofProcessesSection
{

View File

@ -20,12 +20,19 @@
#include "config.h"
#include <sysprof-gtk.h>
#include "sysprof-chart.h"
#include "sysprof-column-layer.h"
#include "sysprof-samples-section.h"
#include "sysprof-traceables-utility.h"
#include "sysprof-session-model-item.h"
#include "sysprof-session-model.h"
#include "sysprof-time-filter-model.h"
#include "sysprof-time-scrubber.h"
#include "sysprof-time-series.h"
#include "sysprof-time-span-layer.h"
#include "sysprof-traceables-utility.h"
#include "sysprof-value-axis.h"
#include "sysprof-weighted-callgraph-view.h"
#include "sysprof-xy-series.h"
struct _SysprofSamplesSection
{

View File

@ -22,7 +22,7 @@
#include <gtk/gtk.h>
#include <sysprof-gtk.h>
#include "sysprof-session.h"
G_BEGIN_DECLS

View File

@ -21,15 +21,10 @@
#pragma once
#include "sysprof-session.h"
#include "sysprof-track.h"
G_BEGIN_DECLS
void _sysprof_session_discover_tracks (SysprofSession *session,
SysprofDocument *document,
GListStore *tracks);
char *_sysprof_session_describe (SysprofSession *self,
SysprofTrack *track,
gpointer item);
char *_sysprof_session_describe (SysprofSession *self,
gpointer item);
G_END_DECLS

View File

@ -23,7 +23,6 @@
#include <glib/gi18n.h>
#include "sysprof-session-private.h"
#include "sysprof-track-private.h"
#include "sysprof-value-axis.h"
struct _SysprofSession
@ -33,8 +32,6 @@ struct _SysprofSession
SysprofDocument *document;
GtkEveryFilter *filter;
GListStore *tracks;
SysprofAxis *visible_time_axis;
SysprofAxis *selected_time_axis;
@ -57,7 +54,6 @@ enum {
PROP_INCLUDE_THREADS,
PROP_SELECTED_TIME,
PROP_SELECTED_TIME_AXIS,
PROP_TRACKS,
PROP_VISIBLE_TIME,
PROP_VISIBLE_TIME_AXIS,
N_PROPS
@ -99,9 +95,6 @@ sysprof_session_set_document (SysprofSession *self,
time_span = sysprof_document_get_time_span (document);
self->selected_time = self->visible_time = self->document_time = *time_span;
sysprof_session_update_axis (self);
/* Discover tracks to show from the document */
_sysprof_session_discover_tracks (self, self->document, self->tracks);
}
static void
@ -109,7 +102,6 @@ sysprof_session_dispose (GObject *object)
{
SysprofSession *self = (SysprofSession *)object;
g_clear_object (&self->tracks);
g_clear_object (&self->visible_time_axis);
g_clear_object (&self->selected_time_axis);
g_clear_object (&self->document);
@ -168,10 +160,6 @@ sysprof_session_get_property (GObject *object,
g_value_set_object (value, sysprof_session_get_visible_time_axis (self));
break;
case PROP_TRACKS:
g_value_take_object (value, sysprof_session_list_tracks (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@ -267,11 +255,6 @@ sysprof_session_class_init (SysprofSessionClass *klass)
SYSPROF_TYPE_AXIS,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
properties [PROP_TRACKS] =
g_param_spec_object ("tracks", NULL, NULL,
G_TYPE_LIST_MODEL,
(G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
}
@ -281,7 +264,6 @@ sysprof_session_init (SysprofSession *self)
self->filter = gtk_every_filter_new ();
self->selected_time_axis = sysprof_value_axis_new (0, 0);
self->visible_time_axis = sysprof_value_axis_new (0, 0);
self->tracks = g_list_store_new (SYSPROF_TYPE_TRACK);
}
SysprofSession *
@ -414,22 +396,6 @@ sysprof_session_get_visible_time_axis (SysprofSession *self)
return self->visible_time_axis;
}
/**
* sysprof_session_list_tracks:
* @self: a #SysprofSession
*
* Gets a list of #SysprofTrack to be displayed in the session.
*
* Returns: (transfer full): a #GListModel of #SysprofTrack
*/
GListModel *
sysprof_session_list_tracks (SysprofSession *self)
{
g_return_val_if_fail (SYSPROF_IS_SESSION (self), NULL);
return g_object_ref (G_LIST_MODEL (self->tracks));
}
void
sysprof_session_zoom_to_selection (SysprofSession *self)
{
@ -485,20 +451,15 @@ append_time_string (GString *str,
char *
_sysprof_session_describe (SysprofSession *self,
SysprofTrack *track,
gpointer item)
{
g_autofree char *text = NULL;
g_return_val_if_fail (SYSPROF_IS_SESSION (self), NULL);
g_return_val_if_fail (!track || SYSPROF_IS_TRACK (track), NULL);
if (self->document == NULL)
return NULL;
if (track && (text = _sysprof_track_format_item_for_display (track, item)))
return g_steal_pointer (&text);
if (SYSPROF_IS_DOCUMENT_MARK (item))
{
SysprofDocumentMark *mark = item;

View File

@ -55,7 +55,5 @@ void sysprof_session_select_time (SysprofSession
const SysprofTimeSpan *time_span);
SYSPROF_AVAILABLE_IN_ALL
void sysprof_session_zoom_to_selection (SysprofSession *self);
SYSPROF_AVAILABLE_IN_ALL
GListModel *sysprof_session_list_tracks (SysprofSession *self);
G_END_DECLS

Some files were not shown because too many files have changed in this diff Show More