mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
sysprof: Add filters popover
This allows visualizing currently applied filters, and remove individual and all filters applied. Currently the only filter that can show up is the mark filter, but in the future new filters may be applied.
This commit is contained in:
@ -46,6 +46,7 @@ src/sysprof/sysprof-processes-section.ui
|
||||
src/sysprof/sysprof-recording-pad.c
|
||||
src/sysprof/sysprof-recording-pad.ui
|
||||
src/sysprof/sysprof-samples-section.ui
|
||||
src/sysprof/sysprof-session-filters-widget.ui
|
||||
src/sysprof/sysprof-sidebar.ui
|
||||
src/sysprof/sysprof-storage-section.ui
|
||||
src/sysprof/sysprof-traceables-utility.ui
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><g fill="#222222"><path d="m 1.042969 0 c -0.8125 0 -1.285157 0.917969 -0.8125 1.582031 l 4.769531 6.738281 v 6.636719 c 0 0.742188 0.78125 1.226563 1.449219 0.894531 l 4 -2 c 0.335937 -0.171874 0.550781 -0.515624 0.550781 -0.894531 v -4.636719 l 4.8125 -6.738281 c 0.476562 -0.664062 0 -1.582031 -0.8125 -1.582031 z m 1.902343 2 h 10.109376 l -3.867188 5.417969 c -0.121094 0.167969 -0.1875 0.375 -0.1875 0.582031 v 4.339844 l -2 1 v -5.339844 c 0 -0.207031 -0.066406 -0.414062 -0.1875 -0.582031 z m 0 0"/><path d="m 3.859375 5 l 2.140625 3 v 7 l 4 -2 v -5 l 2.144531 -3 z m 0 0" fill-opacity="0.34902"/></g></svg>
|
||||
|
After Width: | Height: | Size: 742 B |
@ -52,6 +52,7 @@ sysprof_sources = [
|
||||
'sysprof-scheduler.c',
|
||||
'sysprof-section.c',
|
||||
'sysprof-series.c',
|
||||
'sysprof-session-filters-widget.c',
|
||||
'sysprof-session-model-item.c',
|
||||
'sysprof-session-model.c',
|
||||
'sysprof-session.c',
|
||||
|
||||
@ -96,3 +96,17 @@ popover.tasks listview row {
|
||||
popover.tasks listview row label.heading {
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
sessionfilters row {
|
||||
padding: 3px 0;
|
||||
}
|
||||
|
||||
sessionfilters row:hover {
|
||||
background: none;
|
||||
}
|
||||
|
||||
sessionfilters row button {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
225
src/sysprof/sysprof-session-filters-widget.c
Normal file
225
src/sysprof/sysprof-session-filters-widget.c
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* sysprof-session-filters-widget.c
|
||||
*
|
||||
* Copyright 2025 Georges Basile Stavracas Neto <feaneron@igalia.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 "sysprof-mark-filter.h"
|
||||
#include "sysprof-session-filters-widget.h"
|
||||
#include "sysprof-session.h"
|
||||
|
||||
struct _SysprofSessionFiltersWidget
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
SysprofSession *session;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (SysprofSessionFiltersWidget, sysprof_session_filters_widget, GTK_TYPE_WIDGET)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_SESSION,
|
||||
N_PROPS,
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static void
|
||||
sysprof_session_filters_widget_remove_filter (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *param)
|
||||
{
|
||||
SysprofSessionFiltersWidget *self = (SysprofSessionFiltersWidget *) widget;
|
||||
GtkFilter *filter;
|
||||
unsigned int position;
|
||||
|
||||
g_assert (SYSPROF_IS_SESSION_FILTERS_WIDGET (widget));
|
||||
g_assert (SYSPROF_IS_SESSION (self->session));
|
||||
|
||||
filter = sysprof_session_get_filter (self->session);
|
||||
g_assert (GTK_IS_MULTI_FILTER (filter));
|
||||
|
||||
position = g_variant_get_uint32 (param);
|
||||
|
||||
gtk_multi_filter_remove (GTK_MULTI_FILTER (filter), position);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
item_to_action_target (gpointer unused,
|
||||
GtkFilter *filter,
|
||||
unsigned int position)
|
||||
{
|
||||
if (filter)
|
||||
return g_variant_new_uint32 (position);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
filter_to_icon_name (gpointer unused,
|
||||
GtkFilter *filter)
|
||||
{
|
||||
if (!filter)
|
||||
return g_strdup ("");
|
||||
|
||||
if (SYSPROF_IS_MARK_FILTER (filter))
|
||||
return g_strdup ("mark-chart-symbolic");
|
||||
|
||||
return g_strdup ("funnel-outline-symbolic");
|
||||
}
|
||||
|
||||
static char *
|
||||
filter_to_string (gpointer unused,
|
||||
GtkFilter *filter)
|
||||
{
|
||||
if (!filter)
|
||||
return g_strdup ("");
|
||||
|
||||
if (SYSPROF_IS_MARK_FILTER (filter))
|
||||
{
|
||||
SysprofMarkFilter *mark_filter = (SysprofMarkFilter *) filter;
|
||||
SysprofMarkCatalog *catalog = sysprof_mark_filter_get_catalog (mark_filter);
|
||||
|
||||
return g_strdup_printf ("%s / %s",
|
||||
sysprof_mark_catalog_get_group (catalog),
|
||||
sysprof_mark_catalog_get_name (catalog));
|
||||
}
|
||||
|
||||
return g_strdup (G_OBJECT_TYPE_NAME (filter));
|
||||
}
|
||||
|
||||
static void
|
||||
clear_all_filters (SysprofSessionFiltersWidget *self,
|
||||
GtkButton *button)
|
||||
{
|
||||
GtkFilter *filter;
|
||||
|
||||
g_assert (SYSPROF_IS_SESSION_FILTERS_WIDGET (self));
|
||||
g_assert (SYSPROF_IS_SESSION (self->session));
|
||||
g_assert (GTK_IS_BUTTON (button));
|
||||
|
||||
filter = sysprof_session_get_filter (self->session);
|
||||
g_assert (GTK_IS_MULTI_FILTER (filter));
|
||||
|
||||
while (g_list_model_get_n_items (G_LIST_MODEL (filter)) > 0)
|
||||
gtk_multi_filter_remove (GTK_MULTI_FILTER (filter), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_session_filters_widget_set_session (SysprofSessionFiltersWidget *self,
|
||||
SysprofSession *session)
|
||||
{
|
||||
if (g_set_object (&self->session, session))
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_session_filters_widget_finalize (GObject *object)
|
||||
{
|
||||
SysprofSessionFiltersWidget *self = (SysprofSessionFiltersWidget *)object;
|
||||
|
||||
g_clear_object (&self->session);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_session_filters_widget_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_session_filters_widget_dispose (GObject *object)
|
||||
{
|
||||
SysprofSessionFiltersWidget *self = (SysprofSessionFiltersWidget *)object;
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (self), SYSPROF_TYPE_SESSION_FILTERS_WIDGET);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_session_filters_widget_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_session_filters_widget_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SysprofSessionFiltersWidget *self = SYSPROF_SESSION_FILTERS_WIDGET (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SESSION:
|
||||
g_value_set_object (value, self->session);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_session_filters_widget_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SysprofSessionFiltersWidget *self = SYSPROF_SESSION_FILTERS_WIDGET (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SESSION:
|
||||
sysprof_session_filters_widget_set_session (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_session_filters_widget_class_init (SysprofSessionFiltersWidgetClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = sysprof_session_filters_widget_finalize;
|
||||
object_class->dispose = sysprof_session_filters_widget_dispose;
|
||||
object_class->get_property = sysprof_session_filters_widget_get_property;
|
||||
object_class->set_property = sysprof_session_filters_widget_set_property;
|
||||
|
||||
properties[PROP_SESSION] =
|
||||
g_param_spec_object ("session", NULL, NULL,
|
||||
SYSPROF_TYPE_SESSION,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/sysprof-session-filters-widget.ui");
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "sessionfilters");
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, clear_all_filters);
|
||||
gtk_widget_class_bind_template_callback (widget_class, filter_to_icon_name);
|
||||
gtk_widget_class_bind_template_callback (widget_class, filter_to_string);
|
||||
gtk_widget_class_bind_template_callback (widget_class, item_to_action_target);
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "sessionfilters.remove-filter", "u", sysprof_session_filters_widget_remove_filter);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_session_filters_widget_init (SysprofSessionFiltersWidget *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
32
src/sysprof/sysprof-session-filters-widget.h
Normal file
32
src/sysprof/sysprof-session-filters-widget.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* sysprof-session-filters-widget.c
|
||||
*
|
||||
* Copyright 2025 Georges Basile Stavracas Neto <feaneron@igalia.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>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_SESSION_FILTERS_WIDGET (sysprof_session_filters_widget_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SysprofSessionFiltersWidget, sysprof_session_filters_widget, SYSPROF, SESSION_FILTERS_WIDGET, GtkWidget)
|
||||
|
||||
G_END_DECLS
|
||||
112
src/sysprof/sysprof-session-filters-widget.ui
Normal file
112
src/sysprof/sysprof-session-filters-widget.ui
Normal file
@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="SysprofSessionFiltersWidget" parent="GtkWidget">
|
||||
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="max-content-height">400</property>
|
||||
<property name="propagate-natural-height">true</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkListView">
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="model">
|
||||
<object class="GtkNoSelection">
|
||||
<binding name="model">
|
||||
<lookup name="filter">
|
||||
<lookup name="session">SysprofSessionFiltersWidget</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="activatable">false</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="pixel-size">12</property>
|
||||
<binding name="icon-name">
|
||||
<closure type="gchararray" function="filter_to_icon_name">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">true</property>
|
||||
<binding name="label">
|
||||
<closure type="gchararray" function="filter_to_string">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">window-close-symbolic</property>
|
||||
<property name="action-name">sessionfilters.remove-filter</property>
|
||||
<binding name="action-target">
|
||||
<closure type="GVariant" function="item_to_action_target">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
<lookup name="position">GtkListItem</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
<style>
|
||||
<class name="flat" />
|
||||
<class name="circular" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkSeparator" />
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="label" translatable="yes">Clear All Filters</property>
|
||||
<signal name="clicked" handler="clear_all_filters" swapped="yes" />
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</template>
|
||||
</interface>
|
||||
@ -41,6 +41,7 @@
|
||||
#include "sysprof-pair.h"
|
||||
#include "sysprof-processes-section.h"
|
||||
#include "sysprof-samples-section.h"
|
||||
#include "sysprof-session-filters-widget.h"
|
||||
#include "sysprof-sidebar.h"
|
||||
#include "sysprof-storage-section.h"
|
||||
#include "sysprof-task-row.h"
|
||||
@ -328,6 +329,13 @@ main_view_notify_sidebar (SysprofWindow *self,
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self->show_right_sidebar), sidebar != NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
n_filters_to_button_visibility (SysprofWindow *self,
|
||||
unsigned int n_filters)
|
||||
{
|
||||
return n_filters > 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_window_session_seek_backward (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
@ -617,6 +625,7 @@ sysprof_window_class_init (SysprofWindowClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofWindow, stack_title);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, main_view_notify_sidebar);
|
||||
gtk_widget_class_bind_template_callback (widget_class, n_filters_to_button_visibility);
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "win.open-capture", NULL, sysprof_window_open_capture_action);
|
||||
gtk_widget_class_install_action (widget_class, "win.record-capture", NULL, sysprof_window_record_capture_action);
|
||||
@ -649,6 +658,7 @@ sysprof_window_class_init (SysprofWindowClass *klass)
|
||||
g_type_ensure (SYSPROF_TYPE_NETWORK_SECTION);
|
||||
g_type_ensure (SYSPROF_TYPE_PROCESSES_SECTION);
|
||||
g_type_ensure (SYSPROF_TYPE_SAMPLES_SECTION);
|
||||
g_type_ensure (SYSPROF_TYPE_SESSION_FILTERS_WIDGET);
|
||||
g_type_ensure (SYSPROF_TYPE_STORAGE_SECTION);
|
||||
g_type_ensure (SYSPROF_TYPE_SESSION);
|
||||
g_type_ensure (SYSPROF_TYPE_SYMBOL);
|
||||
|
||||
@ -126,6 +126,36 @@
|
||||
<property name="tooltip-text" translatable="yes">Toggle Left Panel</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="start">
|
||||
<object class="GtkMenuButton">
|
||||
<property name="visible">false</property>
|
||||
<property name="icon-name">funnel-outline-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">View Filters</property>
|
||||
<property name="popover">
|
||||
<object class="GtkPopover">
|
||||
<style>
|
||||
<class name="menu" />
|
||||
</style>
|
||||
<property name="child">
|
||||
<object class="SysprofSessionFiltersWidget">
|
||||
<binding name="session">
|
||||
<lookup name="session">SysprofWindow</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
<binding name="visible">
|
||||
<closure type="gboolean" function="n_filters_to_button_visibility">
|
||||
<lookup name="n-items" type="GtkMultiFilter">
|
||||
<lookup name="filter" type="SysprofSession">
|
||||
<lookup name="session">SysprofWindow</lookup>
|
||||
</lookup>
|
||||
</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
<child type="start">
|
||||
<object class="GtkBox">
|
||||
<property name="margin-start">6</property>
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
<file preprocess="xml-stripblanks">icons/scalable/actions/empty-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">icons/scalable/actions/energy-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">icons/scalable/actions/flamegraph-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">icons/scalable/actions/funnel-outline-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">icons/scalable/actions/graphics-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">icons/scalable/actions/mark-chart-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">icons/scalable/actions/mark-table-symbolic.svg</file>
|
||||
@ -50,6 +51,7 @@
|
||||
<file preprocess="xml-stripblanks">sysprof-processes-section.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-recording-pad.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-samples-section.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-session-filters-widget.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-sidebar.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-storage-section.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-task-row.ui</file>
|
||||
|
||||
Reference in New Issue
Block a user