sysprof: iterate on updated greeter design

This commit is contained in:
Christian Hergert
2023-08-05 23:42:11 -07:00
parent da7b75e8dc
commit 19cd4dca01
7 changed files with 1298 additions and 460 deletions

View File

@ -18,6 +18,7 @@ sysprof_sources = [
'sysprof-dbus-utility.c',
'sysprof-duplex-layer.c',
'sysprof-energy-section.c',
'sysprof-entry-popover.c',
'sysprof-files-section.c',
'sysprof-frame-utility.c',
'sysprof-graphics-section.c',

View File

@ -0,0 +1,427 @@
/* sysprof-entry-popover.c
*
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
*
* 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/>.
*/
#include "config.h"
#include "sysprof-entry-popover.h"
typedef struct
{
GtkPopover parent_instance;
GtkLabel *title;
GtkLabel *message;
GtkEntry *entry;
GtkButton *button;
} SysprofEntryPopoverPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (SysprofEntryPopover, sysprof_entry_popover, GTK_TYPE_POPOVER)
enum {
PROP_0,
PROP_BUTTON_TEXT,
PROP_MESSAGE,
PROP_READY,
PROP_TEXT,
PROP_TITLE,
LAST_PROP
};
enum {
ACTIVATE,
CHANGED,
INSERT_TEXT,
LAST_SIGNAL
};
static GParamSpec *properties [LAST_PROP];
static guint signals [LAST_SIGNAL];
const gchar *
sysprof_entry_popover_get_button_text (SysprofEntryPopover *self)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_return_val_if_fail (SYSPROF_IS_ENTRY_POPOVER (self), NULL);
return gtk_button_get_label (priv->button);
}
void
sysprof_entry_popover_set_button_text (SysprofEntryPopover *self,
const gchar *button_text)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_return_if_fail (SYSPROF_IS_ENTRY_POPOVER (self));
gtk_button_set_label (priv->button, button_text);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BUTTON_TEXT]);
}
const gchar *
sysprof_entry_popover_get_message (SysprofEntryPopover *self)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_return_val_if_fail (SYSPROF_IS_ENTRY_POPOVER (self), NULL);
return gtk_label_get_text (priv->message);
}
void
sysprof_entry_popover_set_message (SysprofEntryPopover *self,
const gchar *message)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_return_if_fail (SYSPROF_IS_ENTRY_POPOVER (self));
gtk_label_set_label (priv->message, message);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_MESSAGE]);
}
gboolean
sysprof_entry_popover_get_ready (SysprofEntryPopover *self)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_return_val_if_fail (SYSPROF_IS_ENTRY_POPOVER (self), FALSE);
return gtk_widget_get_sensitive (GTK_WIDGET (priv->button));
}
void
sysprof_entry_popover_set_ready (SysprofEntryPopover *self,
gboolean ready)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_return_if_fail (SYSPROF_IS_ENTRY_POPOVER (self));
gtk_widget_set_sensitive (GTK_WIDGET (priv->button), ready);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_READY]);
}
const gchar *
sysprof_entry_popover_get_text (SysprofEntryPopover *self)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_return_val_if_fail (SYSPROF_IS_ENTRY_POPOVER (self), NULL);
return gtk_editable_get_text (GTK_EDITABLE (priv->entry));
}
void
sysprof_entry_popover_set_text (SysprofEntryPopover *self,
const gchar *text)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_return_if_fail (SYSPROF_IS_ENTRY_POPOVER (self));
gtk_editable_set_text (GTK_EDITABLE (priv->entry), text);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TEXT]);
}
const gchar *
sysprof_entry_popover_get_title (SysprofEntryPopover *self)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_return_val_if_fail (SYSPROF_IS_ENTRY_POPOVER (self), NULL);
return gtk_label_get_label (priv->title);
}
void
sysprof_entry_popover_set_title (SysprofEntryPopover *self,
const gchar *title)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_return_if_fail (SYSPROF_IS_ENTRY_POPOVER (self));
gtk_label_set_label (priv->title, title);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TITLE]);
}
static void
sysprof_entry_popover_button_clicked (SysprofEntryPopover *self,
GtkButton *button)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
const gchar *text;
g_assert (SYSPROF_IS_ENTRY_POPOVER (self));
g_assert (GTK_IS_BUTTON (button));
text = gtk_editable_get_text (GTK_EDITABLE (priv->entry));
g_signal_emit (self, signals [ACTIVATE], 0, text);
gtk_popover_popdown (GTK_POPOVER (self));
}
static void
sysprof_entry_popover_entry_activate (SysprofEntryPopover *self,
GtkEntry *entry)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_assert (SYSPROF_IS_ENTRY_POPOVER (self));
g_assert (GTK_IS_ENTRY (entry));
if (sysprof_entry_popover_get_ready (self))
gtk_widget_activate (GTK_WIDGET (priv->button));
}
static void
sysprof_entry_popover_entry_changed (SysprofEntryPopover *self,
GtkEntry *entry)
{
g_assert (SYSPROF_IS_ENTRY_POPOVER (self));
g_assert (GTK_IS_ENTRY (entry));
g_signal_emit (self, signals [CHANGED], 0);
}
static void
sysprof_entry_popover_entry_insert_text (SysprofEntryPopover *self,
gchar *new_text,
gint new_text_length,
gint *position,
GtkEntry *entry)
{
gboolean ret = GDK_EVENT_PROPAGATE;
guint pos;
guint n_chars;
g_assert (SYSPROF_IS_ENTRY_POPOVER (self));
g_assert (new_text != NULL);
g_assert (position != NULL);
pos = *position;
n_chars = (new_text_length >= 0) ? new_text_length : g_utf8_strlen (new_text, -1);
g_signal_emit (self, signals [INSERT_TEXT], 0, pos, new_text, n_chars, &ret);
if (ret == GDK_EVENT_STOP)
g_signal_stop_emission_by_name (entry, "insert-text");
}
static void
sysprof_entry_popover_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
SysprofEntryPopover *self = SYSPROF_ENTRY_POPOVER (object);
switch (prop_id)
{
case PROP_BUTTON_TEXT:
g_value_set_string (value, sysprof_entry_popover_get_button_text (self));
break;
case PROP_MESSAGE:
g_value_set_string (value, sysprof_entry_popover_get_message (self));
break;
case PROP_READY:
g_value_set_boolean (value, sysprof_entry_popover_get_ready (self));
break;
case PROP_TEXT:
g_value_set_string (value, sysprof_entry_popover_get_text (self));
break;
case PROP_TITLE:
g_value_set_string (value, sysprof_entry_popover_get_title (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sysprof_entry_popover_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
SysprofEntryPopover *self = SYSPROF_ENTRY_POPOVER (object);
switch (prop_id)
{
case PROP_BUTTON_TEXT:
sysprof_entry_popover_set_button_text (self, g_value_get_string (value));
break;
case PROP_MESSAGE:
sysprof_entry_popover_set_message (self, g_value_get_string (value));
break;
case PROP_READY:
sysprof_entry_popover_set_ready (self, g_value_get_boolean (value));
break;
case PROP_TEXT:
sysprof_entry_popover_set_text (self, g_value_get_string (value));
break;
case PROP_TITLE:
sysprof_entry_popover_set_title (self, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sysprof_entry_popover_class_init (SysprofEntryPopoverClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->get_property = sysprof_entry_popover_get_property;
object_class->set_property = sysprof_entry_popover_set_property;
properties [PROP_BUTTON_TEXT] =
g_param_spec_string ("button-text",
"Button Text",
"Button Text",
NULL,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties [PROP_MESSAGE] =
g_param_spec_string ("message",
"Message",
"Message",
NULL,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties [PROP_READY] =
g_param_spec_boolean ("ready",
"Ready",
"Ready",
FALSE,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties [PROP_TEXT] =
g_param_spec_string ("text",
"Text",
"Text",
NULL,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties [PROP_TITLE] =
g_param_spec_string ("title",
"Title",
"Title",
NULL,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, LAST_PROP, properties);
signals [ACTIVATE] =
g_signal_new ("activate",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (SysprofEntryPopoverClass, activate),
NULL, NULL, NULL,
G_TYPE_NONE,
1,
G_TYPE_STRING);
signals [CHANGED] =
g_signal_new ("changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (SysprofEntryPopoverClass, changed),
NULL, NULL, NULL,
G_TYPE_NONE,
0);
signals [INSERT_TEXT] =
g_signal_new ("insert-text",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (SysprofEntryPopoverClass, insert_text),
NULL, NULL, NULL,
G_TYPE_BOOLEAN,
3,
G_TYPE_UINT,
G_TYPE_STRING,
G_TYPE_UINT);
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/sysprof-entry-popover.ui");
gtk_widget_class_bind_template_child_private (widget_class, SysprofEntryPopover, title);
gtk_widget_class_bind_template_child_private (widget_class, SysprofEntryPopover, message);
gtk_widget_class_bind_template_child_private (widget_class, SysprofEntryPopover, entry);
gtk_widget_class_bind_template_child_private (widget_class, SysprofEntryPopover, button);
}
static void
sysprof_entry_popover_init (SysprofEntryPopover *self)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
gtk_widget_init_template (GTK_WIDGET (self));
g_signal_connect_object (priv->button,
"clicked",
G_CALLBACK (sysprof_entry_popover_button_clicked),
self,
G_CONNECT_SWAPPED);
g_signal_connect_object (priv->entry,
"changed",
G_CALLBACK (sysprof_entry_popover_entry_changed),
self,
G_CONNECT_SWAPPED);
g_signal_connect_object (priv->entry,
"activate",
G_CALLBACK (sysprof_entry_popover_entry_activate),
self,
G_CONNECT_SWAPPED);
g_signal_connect_object (gtk_editable_get_delegate (GTK_EDITABLE (priv->entry)),
"insert-text",
G_CALLBACK (sysprof_entry_popover_entry_insert_text),
self,
G_CONNECT_SWAPPED);
}
GtkWidget *
sysprof_entry_popover_new (void)
{
return g_object_new (SYSPROF_TYPE_ENTRY_POPOVER, NULL);
}
void
sysprof_entry_popover_select_all (SysprofEntryPopover *self)
{
SysprofEntryPopoverPrivate *priv = sysprof_entry_popover_get_instance_private (self);
g_return_if_fail (SYSPROF_IS_ENTRY_POPOVER (self));
gtk_editable_select_region (GTK_EDITABLE (priv->entry), 0, -1);
}

View File

@ -0,0 +1,88 @@
/* sysprof-entry-popover.h
*
* Copyright (C) 2015-2022 Christian Hergert <christian@hergert.me>
*
* 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/>.
*/
#pragma once
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define SYSPROF_TYPE_ENTRY_POPOVER (sysprof_entry_popover_get_type())
G_DECLARE_DERIVABLE_TYPE (SysprofEntryPopover, sysprof_entry_popover, SYSPROF, ENTRY_POPOVER, GtkPopover)
struct _SysprofEntryPopoverClass
{
GtkPopoverClass parent;
/**
* SysprofEntryPopover::activate:
* @self: The #SysprofEntryPopover instance.
* @text: The text at the time of activation.
*
* This signal is emitted when the popover's forward button is activated.
* Connect to this signal to perform your forward progress.
*/
void (*activate) (SysprofEntryPopover *self,
const gchar *text);
/**
* SysprofEntryPopover::insert-text:
* @self: A #SysprofEntryPopover.
* @position: the position in UTF-8 characters.
* @chars: the NULL terminated UTF-8 text to insert.
* @n_chars: the number of UTF-8 characters in chars.
*
* Use this signal to determine if text should be allowed to be inserted
* into the text buffer. Return GDK_EVENT_STOP to prevent the text from
* being inserted.
*/
gboolean (*insert_text) (SysprofEntryPopover *self,
guint position,
const gchar *chars,
guint n_chars);
/**
* SysprofEntryPopover::changed:
* @self: A #SysprofEntryPopover.
*
* This signal is emitted when the entry text changes.
*/
void (*changed) (SysprofEntryPopover *self);
};
GtkWidget *sysprof_entry_popover_new (void);
const gchar *sysprof_entry_popover_get_text (SysprofEntryPopover *self);
void sysprof_entry_popover_set_text (SysprofEntryPopover *self,
const gchar *text);
const gchar *sysprof_entry_popover_get_message (SysprofEntryPopover *self);
void sysprof_entry_popover_set_message (SysprofEntryPopover *self,
const gchar *message);
const gchar *sysprof_entry_popover_get_title (SysprofEntryPopover *self);
void sysprof_entry_popover_set_title (SysprofEntryPopover *self,
const gchar *title);
const gchar *sysprof_entry_popover_get_button_text (SysprofEntryPopover *self);
void sysprof_entry_popover_set_button_text (SysprofEntryPopover *self,
const gchar *button_text);
gboolean sysprof_entry_popover_get_ready (SysprofEntryPopover *self);
void sysprof_entry_popover_set_ready (SysprofEntryPopover *self,
gboolean ready);
void sysprof_entry_popover_select_all (SysprofEntryPopover *self);
G_END_DECLS

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<template class="SysprofEntryPopover" parent="GtkPopover">
<child>
<object class="GtkBox">
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<property name="visible">true</property>
<child>
<object class="GtkLabel" id="title">
<property name="xalign">0.5</property>
<property name="visible">true</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">9</property>
<property name="visible">true</property>
<child>
<object class="GtkEntry" id="entry">
<property name="width-chars">20</property>
<property name="hexpand">true</property>
<property name="visible">true</property>
</object>
</child>
<child>
<object class="GtkButton" id="button">
<property name="sensitive">false</property>
<property name="use-underline">true</property>
<property name="visible">true</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel" id="message">
<property name="xalign">0.0</property>
<property name="visible">true</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@ -26,6 +26,7 @@
#include <sysprof-capture.h>
#include <sysprof-profiler.h>
#include "sysprof-entry-popover.h"
#include "sysprof-greeter.h"
#include "sysprof-recording-pad.h"
@ -36,12 +37,12 @@ struct _SysprofGreeter
AdwWindow parent_instance;
GFile *file;
GtkStringList *envvars;
AdwViewStack *view_stack;
GtkWidget *open_buttons;
GtkWidget *record_buttons;
GtkListBox *sidebar_list_box;
AdwPreferencesPage *record_page;
GtkWidget *open_page;
GtkListBox *app_environment;
GtkSwitch *sample_native_stacks;
GtkSwitch *sample_javascript_stacks;
GtkSwitch *record_disk_usage;
@ -63,22 +64,85 @@ G_DEFINE_FINAL_TYPE (SysprofGreeter, sysprof_greeter, ADW_TYPE_WINDOW)
static GParamSpec *properties [N_PROPS];
static void
sysprof_greeter_view_stack_notify_visible_child (SysprofGreeter *self,
GParamSpec *pspec,
AdwViewStack *stack)
#define STRV_INIT(...) (const char * const[]){__VA_ARGS__,NULL}
static inline gboolean
str_empty0 (const char *str)
{
GtkWidget *visible_child;
return str == NULL || str[0] == 0;
}
static void
on_env_items_changed_cb (SysprofGreeter *self,
guint position,
guint removed,
guint added,
GListModel *model)
{
g_assert (SYSPROF_IS_GREETER (self));
g_assert (G_IS_LIST_MODEL (model));
gtk_widget_set_visible (GTK_WIDGET (self->app_environment),
g_list_model_get_n_items (model) > 0);
}
static void
on_env_entry_changed_cb (SysprofGreeter *self,
SysprofEntryPopover *popover)
{
const char *errstr = NULL;
gboolean valid = FALSE;
const char *text;
const char *eq;
g_assert (SYSPROF_IS_GREETER (self));
g_assert (ADW_IS_VIEW_STACK (stack));
g_assert (SYSPROF_IS_ENTRY_POPOVER (popover));
visible_child = adw_view_stack_get_visible_child (stack);
text = sysprof_entry_popover_get_text (popover);
eq = strchr (text, '=');
gtk_widget_set_visible (GTK_WIDGET (self->record_buttons),
GTK_WIDGET (self->record_page) == visible_child);
gtk_widget_set_visible (GTK_WIDGET (self->open_buttons),
GTK_WIDGET (self->open_page) == visible_child);
if (!str_empty0 (text) && eq == NULL)
errstr = _("Use KEY=VALUE to set an environment variable");
if (eq != NULL && eq != text)
{
if (g_unichar_isdigit (g_utf8_get_char (text)))
{
errstr = _("Keys may not start with a number");
goto failure;
}
for (const char *iter = text; iter < eq; iter = g_utf8_next_char (iter))
{
gunichar ch = g_utf8_get_char (iter);
if (!g_unichar_isalnum (ch) && ch != '_')
{
errstr = _("Keys may only contain alpha-numerics or underline.");
goto failure;
}
}
if (g_ascii_isalpha (*text))
valid = TRUE;
}
failure:
sysprof_entry_popover_set_ready (popover, valid);
sysprof_entry_popover_set_message (popover, errstr);
}
static void
on_env_entry_activate_cb (SysprofGreeter *self,
const char *text,
SysprofEntryPopover *popover)
{
g_assert (SYSPROF_IS_GREETER (self));
g_assert (SYSPROF_IS_ENTRY_POPOVER (popover));
g_assert (GTK_IS_STRING_LIST (self->envvars));
gtk_string_list_append (self->envvars, text);
sysprof_entry_popover_set_text (popover, "");
}
static SysprofProfiler *
@ -341,6 +405,120 @@ get_file_path (gpointer unused,
return NULL;
}
static void
sidebar_row_activated_cb (SysprofGreeter *self,
GtkListBoxRow *row,
GtkListBox *list_box)
{
AdwViewStackPage *page = g_object_get_data (G_OBJECT (row), "GREETER_PAGE");
adw_view_stack_set_visible_child (self->view_stack,
adw_view_stack_page_get_child (page));
//adw_window_title_set_title (self->view_title,
//adw_view_stack_page_get_title (page));
}
static GtkWidget *
sysprof_greeter_create_sidebar_row (gpointer item,
gpointer user_data)
{
AdwViewStackPage *page = item;
GtkLabel *label;
GtkBox *box;
GtkImage *image;
GtkWidget *row;
g_assert (ADW_IS_VIEW_STACK_PAGE (page));
box = g_object_new (GTK_TYPE_BOX,
"spacing", 6,
NULL);
image = g_object_new (GTK_TYPE_IMAGE,
"icon-name", adw_view_stack_page_get_icon_name (page),
NULL);
label = g_object_new (GTK_TYPE_LABEL,
"label", adw_view_stack_page_get_title (page),
"use-underline", TRUE,
"xalign", .0f,
NULL);
gtk_box_append (box, GTK_WIDGET (image));
gtk_box_append (box, GTK_WIDGET (label));
row = g_object_new (GTK_TYPE_LIST_BOX_ROW,
"child", box,
NULL);
g_object_set_data_full (G_OBJECT (row),
"GREETER_PAGE",
g_object_ref (page),
g_object_unref);
return row;
}
static void
delete_envvar_cb (SysprofGreeter *self,
GtkButton *button)
{
const char *envvar;
guint n_items;
g_assert (SYSPROF_IS_GREETER (self));
g_assert (GTK_IS_BUTTON (button));
envvar = g_object_get_data (G_OBJECT (button), "ENVVAR");
n_items = g_list_model_get_n_items (G_LIST_MODEL (self->envvars));
for (guint i = 0; i < n_items; i++)
{
g_autoptr(GtkStringObject) str = g_list_model_get_item (G_LIST_MODEL (self->envvars), i);
if (g_strcmp0 (envvar, gtk_string_object_get_string (str)) == 0)
{
gtk_string_list_remove (self->envvars, i);
break;
}
}
}
static GtkWidget *
create_envvar_row_cb (gpointer item,
gpointer user_data)
{
SysprofGreeter *self = user_data;
GtkStringObject *obj = item;
const char *str;
g_autofree char *markup = NULL;
g_autofree char *escaped = NULL;
AdwActionRow *row;
GtkButton *button;
g_assert (SYSPROF_IS_GREETER (self));
g_assert (GTK_IS_STRING_OBJECT (obj));
str = gtk_string_object_get_string (obj);
escaped = g_markup_escape_text (str, -1);
markup = g_strdup_printf ("<tt>%s</tt>", escaped);
row = g_object_new (ADW_TYPE_ACTION_ROW,
"title", markup,
"title-selectable", TRUE,
NULL);
button = g_object_new (GTK_TYPE_BUTTON,
"icon-name", "list-remove-symbolic",
"css-classes", STRV_INIT ("flat", "circular"),
"valign", GTK_ALIGN_CENTER,
NULL);
g_object_set_data_full (G_OBJECT (button),
"ENVVAR",
g_strdup (str),
g_free);
g_signal_connect_object (button,
"clicked",
G_CALLBACK (delete_envvar_cb),
self,
G_CONNECT_SWAPPED);
adw_action_row_add_suffix (row, GTK_WIDGET (button));
return GTK_WIDGET (row);
}
static void
sysprof_greeter_dispose (GObject *object)
{
@ -348,6 +526,8 @@ sysprof_greeter_dispose (GObject *object)
gtk_widget_dispose_template (GTK_WIDGET (self), SYSPROF_TYPE_GREETER);
g_clear_object (&self->envvars);
G_OBJECT_CLASS (sysprof_greeter_parent_class)->dispose (object);
}
@ -408,9 +588,8 @@ sysprof_greeter_class_init (SysprofGreeterClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/sysprof-greeter.ui");
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, app_environment);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, bundle_symbols);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, open_buttons);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, open_page);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, record_compositor);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, record_disk_usage);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, record_network_usage);
@ -420,21 +599,48 @@ sysprof_greeter_class_init (SysprofGreeterClass *klass)
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, record_system_logs);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, sample_native_stacks);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, sample_javascript_stacks);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, record_buttons);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, sidebar_list_box);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, view_stack);
gtk_widget_class_bind_template_callback (widget_class, sysprof_greeter_view_stack_notify_visible_child);
gtk_widget_class_bind_template_callback (widget_class, sidebar_row_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, get_file_path);
gtk_widget_class_bind_template_callback (widget_class, on_env_entry_activate_cb);
gtk_widget_class_bind_template_callback (widget_class, on_env_entry_changed_cb);
gtk_widget_class_install_action (widget_class, "win.record-to-memory", NULL, sysprof_greeter_record_to_memory_action);
gtk_widget_class_install_action (widget_class, "win.record-to-file", NULL, sysprof_greeter_record_to_file_action);
gtk_widget_class_install_action (widget_class, "win.select-file", NULL, sysprof_greeter_select_file_action);
g_type_ensure (SYSPROF_TYPE_ENTRY_POPOVER);
}
static void
sysprof_greeter_init (SysprofGreeter *self)
{
GtkListBoxRow *row;
self->envvars = gtk_string_list_new (NULL);
g_signal_connect_object (self->envvars,
"items-changed",
G_CALLBACK (on_env_items_changed_cb),
self,
G_CONNECT_SWAPPED);
gtk_widget_init_template (GTK_WIDGET (self));
gtk_list_box_bind_model (self->sidebar_list_box,
G_LIST_MODEL (adw_view_stack_get_pages (self->view_stack)),
sysprof_greeter_create_sidebar_row,
NULL, NULL);
gtk_list_box_bind_model (self->app_environment,
G_LIST_MODEL (self->envvars),
create_envvar_row_cb,
self, NULL);
row = gtk_list_box_get_row_at_index (self->sidebar_list_box, 0);
gtk_list_box_select_row (self->sidebar_list_box, row);
sidebar_row_activated_cb (self, row, self->sidebar_list_box);
}
GtkWidget *
@ -452,7 +658,7 @@ sysprof_greeter_set_page (SysprofGreeter *self,
switch (page)
{
case SYSPROF_GREETER_PAGE_OPEN:
adw_view_stack_set_visible_child (self->view_stack, GTK_WIDGET (self->open_page));
//adw_view_stack_set_visible_child (self->view_stack, GTK_WIDGET (self->open_page));
break;
default:

View File

@ -4,467 +4,522 @@
<requires lib="Adw" version="1.0"/>
<template class="SysprofGreeter" parent="AdwWindow">
<property name="default-width">800</property>
<property name="default-height">800</property>
<property name="content">
<object class="AdwToolbarView">
<property name="bottom-bar-style">raised</property>
<child type="top">
<object class="AdwHeaderBar">
<property name="centering-policy">strict</property>
<property name="title-widget">
<object class="AdwViewSwitcherTitle">
<property name="stack">view_stack</property>
</object>
</property>
<property name="default-height">600</property>
<child>
<object class="GtkShortcutController">
<child>
<object class="GtkShortcut">
<property name="trigger">Escape</property>
<property name="action">action(window.close)</property>
</object>
</child>
<property name="content">
<object class="AdwViewStack" id="view_stack">
<signal name="notify::visible-child" handler="sysprof_greeter_view_stack_notify_visible_child" swapped="true"/>
<child>
<object class="AdwViewStackPage">
<property name="icon-name">org.gnome.Sysprof-symbolic</property>
<property name="title" translatable="yes">_Record</property>
<property name="use-underline">true</property>
<property name="child">
<object class="AdwPreferencesPage" id="record_page">
<property name="vexpand">true</property>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Time Profiler</property>
<child>
<object class="AdwActionRow" id="first_row">
<property name="activatable-widget">sample_native_stacks</property>
<property name="title" translatable="yes">Sample Native Stacks</property>
<property name="subtitle" translatable="yes">Record native stack traces using a sampling profiler</property>
<child type="suffix">
<object class="GtkSwitch" id="sample_native_stacks">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwComboRow">
<property name="title" translatable="yes">Performance Profile</property>
<property name="subtitle" translatable="yes">Hold the performance profile for the duration of the recording</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="activatable-widget">sample_javascript_stacks</property>
<property name="title" translatable="yes">Sample JavaScript Stacks</property>
<property name="subtitle" translatable="yes">Record JavaScript stack traces using a sampling profiler</property>
<child type="suffix">
<object class="GtkSwitch" id="sample_javascript_stacks">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">This feature is only supported when launching a GJS-based application.</property>
<property name="xalign">0</property>
<property name="margin-top">8</property>
<style>
<class name="caption"/>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Memory</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_memory_counters</property>
<property name="title" translatable="yes">System Memory Usage</property>
<property name="subtitle" translatable="yes">Record coarse-grained counters about system memory usage</property>
<child type="suffix">
<object class="GtkSwitch" id="record_memory_counters">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="activatable-widget">trace_malloc</property>
<property name="title" translatable="yes">Trace Memory Allocations</property>
<property name="subtitle" translatable="yes">Record a strack trace when &lt;tt&gt;malloc&lt;/tt&gt; or similar functions are used</property>
<child type="suffix">
<object class="GtkSwitch" id="trace_malloc">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Memory tracing is only supported when launching an application.</property>
<property name="xalign">0</property>
<property name="margin-top">8</property>
<style>
<class name="caption"/>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Display &amp;amp; Graphics</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_compositor</property>
<property name="title" translatable="yes">Compositor Frame Timings</property>
<property name="subtitle" translatable="yes">Record frame-timing information from the GNOME Shell compositor</property>
<child type="suffix">
<object class="GtkSwitch" id="record_compositor">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="activatable-widget">detect_hangs</property>
<property name="title" translatable="yes">Detect Application Hangs</property>
<property name="subtitle" translatable="yes">Detect hangs in the application main loop</property>
<child type="suffix">
<object class="GtkSwitch" id="detect_hangs">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Hang detection is only supported when launching a GTK-based application.</property>
<property name="xalign">0</property>
<property name="margin-top">8</property>
<style>
<class name="caption"/>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">D-Bus Profiler</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_session_bus</property>
<property name="title" translatable="yes">D-Bus Session Bus</property>
<property name="subtitle" translatable="yes">Record messages on the D-Bus user session bus</property>
<child type="suffix">
<object class="GtkSwitch" id="record_session_bus">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_system_bus</property>
<property name="title" translatable="yes">D-Bus System Bus</property>
<property name="subtitle" translatable="yes">Record messages on the D-Bus system bus</property>
<child type="suffix">
<object class="GtkSwitch" id="record_system_bus">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Recording your session bus may include sensitive information such as keyboard usage.</property>
<property name="xalign">0</property>
<property name="margin-top">8</property>
<style>
<class name="caption"/>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Counters</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_disk_usage</property>
<property name="title" translatable="yes">Disk Usage</property>
<property name="subtitle" translatable="yes">Record coarse-grained counters about storage throughput</property>
<child type="suffix">
<object class="GtkSwitch" id="record_disk_usage">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_network_usage</property>
<property name="title" translatable="yes">Network Usage</property>
<property name="subtitle" translatable="yes">Record coarse-grained counters about network traffic</property>
<child type="suffix">
<object class="GtkSwitch" id="record_network_usage">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_energy_usage</property>
<property name="title" translatable="yes">Energy Usage</property>
<property name="subtitle" translatable="yes">Record coarse-grained counters about energy usage in Watts</property>
<child type="suffix">
<object class="GtkSwitch" id="record_energy_usage">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_battery_charge</property>
<property name="title" translatable="yes">Battery Charge</property>
<property name="subtitle" translatable="yes">Record coarse-grained counters about battery charge or discharge rates</property>
<child type="suffix">
<object class="GtkSwitch" id="record_battery_charge">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">System</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_system_logs</property>
<property name="title" translatable="yes">System Logs</property>
<property name="subtitle" translatable="yes">Watch the system log for new messages and record them</property>
<child type="suffix">
<object class="GtkSwitch" id="record_system_logs">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">bundle_symbols</property>
<property name="title" translatable="yes">Bundle Symbols</property>
<property name="subtitle" translatable="yes">Make recording shareable by bundling decoded symbols</property>
<child type="suffix">
<object class="GtkSwitch" id="bundle_symbols">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
<child>
<object class="GtkShortcut">
<property name="trigger">&lt;control&gt;w</property>
<property name="action">action(window.close)</property>
</object>
</child>
</object>
</child>
<property name="content">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="AdwHeaderBar">
<property name="show-end-title-buttons">false</property>
<property name="title-widget">
<object class="AdwWindowTitle">
<property name="title">New Session</property>
</object>
</property>
<child type="start">
<object class="GtkButton">
<property name="label" translatable="yes">Open…</property>
<property name="action-name">win.select-file</property>
<property name="width-request">100</property>
</object>
</child>
<child>
<object class="AdwViewStackPage">
<property name="icon-name">document-open-symbolic</property>
<property name="title" translatable="yes">_Open</property>
<property name="use-underline">true</property>
<property name="child">
<object class="AdwPreferencesPage" id="open_page">
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Open Recording</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">capture_file_button</property>
<property name="title" translatable="yes">Capture File</property>
<binding name="subtitle">
<closure type="gchararray" function="get_file_path">
<lookup name="file">SysprofGreeter</lookup>
</closure>
</binding>
<child type="suffix">
<object class="GtkButton" id="capture_file_button">
<property name="action-name">win.select-file</property>
<property name="icon-name">document-open-symbolic</property>
<property name="valign">center</property>
<style>
<class name="flat"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Symbols</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">ignore_bundled_symbols</property>
<property name="title" translatable="yes">Ignore Bundled Symbols</property>
<property name="subtitle" translatable="yes">Do not use embedded symbols that were resolved on the capture system</property>
<child type="suffix">
<object class="GtkSwitch" id="ignore_bundled_symbols">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="activatable-widget">kallsyms_button</property>
<property name="title" translatable="yes">Override Kernel Symbols</property>
<property name="subtitle" translatable="yes">Specify a “kallsyms” file overriding what is bundled with a recording</property>
<child type="suffix">
<object class="GtkButton" id="kallsyms_button">
<property name="icon-name">document-open-symbolic</property>
<property name="valign">center</property>
<style>
<class name="flat"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Symbol Directories</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Additional symbol directories to use when symbolizing stack traces.</property>
<property name="xalign">0</property>
<style>
<class name="capture"/>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkButton">
<property name="margin-top">12</property>
<property name="label" translatable="yes">Add Symbol Directory</property>
<property name="halign">end</property>
</object>
</child>
</object>
</child>
</object>
</property>
<child type="end">
<object class="GtkButton">
<property name="label" translatable="yes">Record</property>
<property name="action-name">win.record-to-memory</property>
<property name="width-request">100</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</object>
</property>
<child type="bottom">
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="AdwClamp" id="record_buttons">
<property name="maximum-size">500</property>
<child>
<object class="GtkBox">
<style>
<class name="toolbar"/>
</style>
<property name="hexpand">true</property>
<property name="homogeneous">true</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Record to _File…</property>
<property name="action-name">win.record-to-file</property>
<property name="use-underline">true</property>
<property name="hexpand">true</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Record to _Memory</property>
<property name="action-name">win.record-to-memory</property>
<property name="use-underline">true</property>
<property name="hexpand">true</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwClamp" id="open_buttons">
<property name="maximum-size">500</property>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="visible">false</property>
<child>
<object class="GtkBox">
<object class="GtkListBox" id="sidebar_list_box">
<style>
<class name="toolbar"/>
<class name="navigation-sidebar"/>
</style>
<property name="hexpand">true</property>
<property name="homogeneous">true</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">_Open Capture…</property>
<property name="action-name">win.open-capture</property>
<property name="use-underline">true</property>
<property name="hexpand">true</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
<signal name="row-activated" handler="sidebar_row_activated_cb" swapped="true"/>
</object>
</child>
</object>
</child>
<child>
<object class="AdwViewStack" id="view_stack">
<property name="vexpand">true</property>
<child>
<object class="AdwViewStackPage">
<property name="icon-name">org.gnome.Sysprof-symbolic</property>
<property name="title" translatable="yes">Profiler</property>
<property name="child">
<object class="AdwPreferencesPage" id="record_page">
<property name="vexpand">true</property>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Sampling</property>
<child>
<object class="AdwActionRow" id="first_row">
<property name="activatable-widget">sample_native_stacks</property>
<property name="title" translatable="yes">Sample Native Stacks</property>
<property name="subtitle" translatable="yes">Record native stack traces using a sampling profiler</property>
<child type="suffix">
<object class="GtkSwitch" id="sample_native_stacks">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="activatable-widget">sample_javascript_stacks</property>
<property name="title" translatable="yes">Sample JavaScript Stacks</property>
<property name="subtitle" translatable="yes">Record JavaScript stack traces using a sampling profiler</property>
<child type="suffix">
<object class="GtkSwitch" id="sample_javascript_stacks">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Sysprof must launch your application to record JavaScript stacks using GJS.</property>
<property name="xalign">0</property>
<property name="margin-top">8</property>
<style>
<class name="caption"/>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Tracing</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">trace_malloc</property>
<property name="title" translatable="yes">Trace Memory Allocations</property>
<property name="subtitle" translatable="yes">Record a strack trace when &lt;tt&gt;malloc&lt;/tt&gt; or similar functions are used</property>
<child type="suffix">
<object class="GtkSwitch" id="trace_malloc">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Sysprof must launch your application to record memory allocations.</property>
<property name="xalign">0</property>
<property name="margin-top">8</property>
<style>
<class name="caption"/>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="AdwViewStackPage">
<property name="icon-name">application-x-executable-symbolic</property>
<property name="title" translatable="yes">Application</property>
<property name="child">
<object class="AdwPreferencesPage">
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Application</property>
<child>
<object class="AdwEntryRow" id="app_command_line">
<property name="title" translatable="yes">Command Line</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">The application will be run as a subprocess of Sysprof.</property>
<property name="xalign">0</property>
<property name="margin-top">8</property>
<style>
<class name="caption"/>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Environment</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">clear_environment</property>
<property name="title" translatable="yes">Clear Environment</property>
<property name="subtitle" translatable="yes">Clear the environment before launching application</property>
<child type="suffix">
<object class="GtkSwitch" id="clear_environment">
<property name="active">false</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBox" id="app_environment">
<property name="margin-top">12</property>
<property name="selection-mode">none</property>
<property name="visible">false</property>
<style>
<class name="boxed-list"/>
</style>
</object>
</child>
<child>
<object class="GtkMenuButton">
<property name="direction">left</property>
<property name="margin-top">12</property>
<property name="halign">end</property>
<property name="child">
<object class="GtkLabel">
<property name="label" translatable="yes">Add _Variable</property>
<property name="use-underline">true</property>
</object>
</property>
<property name="popover">
<object class="SysprofEntryPopover">
<property name="title" translatable="yes">Add Variable</property>
<property name="button-text" translatable="yes">_Add</property>
<property name="width-request">400</property>
<signal name="changed" handler="on_env_entry_changed_cb" swapped="true" object="SysprofGreeter"/>
<signal name="activate" handler="on_env_entry_activate_cb" swapped="true" object="SysprofGreeter"/>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="AdwViewStackPage">
<property name="icon-name">mark-chart-symbolic</property>
<property name="title" translatable="yes">Counters</property>
<property name="child">
<object class="AdwPreferencesPage">
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Counters</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_memory_counters</property>
<property name="title" translatable="yes">Memory Usage</property>
<property name="subtitle" translatable="yes">Record coarse-grained counters about system memory usage</property>
<child type="suffix">
<object class="GtkSwitch" id="record_memory_counters">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_disk_usage</property>
<property name="title" translatable="yes">Disk Usage</property>
<property name="subtitle" translatable="yes">Record coarse-grained counters about storage throughput</property>
<child type="suffix">
<object class="GtkSwitch" id="record_disk_usage">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_network_usage</property>
<property name="title" translatable="yes">Network Usage</property>
<property name="subtitle" translatable="yes">Record coarse-grained counters about network traffic</property>
<child type="suffix">
<object class="GtkSwitch" id="record_network_usage">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_energy_usage</property>
<property name="title" translatable="yes">Energy Usage</property>
<property name="subtitle" translatable="yes">Record coarse-grained counters about energy usage in Watts</property>
<child type="suffix">
<object class="GtkSwitch" id="record_energy_usage">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_battery_charge</property>
<property name="title" translatable="yes">Battery Charge</property>
<property name="subtitle" translatable="yes">Record coarse-grained counters about battery charge or discharge rates</property>
<child type="suffix">
<object class="GtkSwitch" id="record_battery_charge">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="AdwViewStackPage">
<property name="icon-name">dbus-symbolic</property>
<property name="title" translatable="yes">D-Bus</property>
<property name="child">
<object class="AdwPreferencesPage">
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">D-Bus</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_system_bus</property>
<property name="title" translatable="yes">Record System Bus</property>
<property name="subtitle" translatable="yes">Record messages on the D-Bus system bus</property>
<child type="suffix">
<object class="GtkSwitch" id="record_system_bus">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_session_bus</property>
<property name="title" translatable="yes">Record Session Bus</property>
<property name="subtitle" translatable="yes">Record messages on the D-Bus user session bus</property>
<child type="suffix">
<object class="GtkSwitch" id="record_session_bus">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">The session bus may contain sensitive information such as keyboard usage and passwords.</property>
<property name="xalign">0</property>
<property name="margin-top">8</property>
<style>
<class name="caption"/>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="AdwViewStackPage">
<property name="icon-name">graphics-symbolic</property>
<property name="title" translatable="yes">Graphics</property>
<property name="child">
<object class="AdwPreferencesPage">
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Timings</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_compositor</property>
<property name="title" translatable="yes">Compositor Frame Timings</property>
<property name="subtitle" translatable="yes">Record frame-timing information from the GNOME Shell compositor</property>
<child type="suffix">
<object class="GtkSwitch" id="record_compositor">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Applications launched by Sysprof will automatically collect GTK frame timing information.</property>
<property name="xalign">0</property>
<property name="margin-top">8</property>
<style>
<class name="caption"/>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
<!--child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="activatable-widget">detect_hangs</property>
<property name="title" translatable="yes">Detect Application Hangs</property>
<property name="subtitle" translatable="yes">Detect hangs in the application main loop</property>
<child type="suffix">
<object class="GtkSwitch" id="detect_hangs">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Hang detection is only supported when launching a GTK-based application.</property>
<property name="xalign">0</property>
<property name="margin-top">8</property>
<style>
<class name="caption"/>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child-->
</object>
</property>
</object>
</child>
<child>
<object class="AdwViewStackPage">
<property name="icon-name">computer-symbolic</property>
<property name="title" translatable="yes">System</property>
<property name="child">
<object class="AdwPreferencesPage">
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Power Profile</property>
<child>
<object class="AdwComboRow">
<property name="title" translatable="yes">Record with Power Profile</property>
<property name="subtitle" translatable="yes">Hold the power profile for the duration of the recording and restore when finished</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Logging</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">record_system_logs</property>
<property name="title" translatable="yes">Record System Log</property>
<property name="subtitle" translatable="yes">Watch the system log for new messages and record them</property>
<child type="suffix">
<object class="GtkSwitch" id="record_system_logs">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Symbols</property>
<child>
<object class="AdwActionRow">
<property name="activatable-widget">bundle_symbols</property>
<property name="title" translatable="yes">Bundle Symbols</property>
<property name="subtitle" translatable="yes">Make recording shareable by symbolizing stack traces after recording</property>
<child type="suffix">
<object class="GtkSwitch" id="bundle_symbols">
<property name="active">true</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwViewSwitcherBar">
<property name="stack">view_stack</property>
<property name="reveal">true</property>
</object>
</child>
</object>
</property>
</template>
<menu id="primary_menu">
<section>
<item>
<attribute name="label" translatable="yes">Help</attribute>
<attribute name="accel">F1</attribute>
<attribute name="action">app.help</attribute>
</item>
<item>
<attribute name="label" translatable="yes">About Sysprof</attribute>
<attribute name="action">app.about</attribute>
</item>
</section>
</menu>
</interface>

View File

@ -15,6 +15,7 @@
<file preprocess="xml-stripblanks">icons/scalable/actions/metadata-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/process-mounts-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/storage-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/symbol-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/system-log-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/threads-symbolic.svg</file>
<file preprocess="xml-stripblanks">sysprof-callgraph-view.ui</file>
@ -25,6 +26,7 @@
<file preprocess="xml-stripblanks">sysprof-dbus-utility.ui</file>
<file preprocess="xml-stripblanks">sysprof-energy-section.ui</file>
<file preprocess="xml-stripblanks">sysprof-energy-section-counter.ui</file>
<file preprocess="xml-stripblanks">sysprof-entry-popover.ui</file>
<file preprocess="xml-stripblanks">sysprof-files-section.ui</file>
<file preprocess="xml-stripblanks">sysprof-frame-utility.ui</file>
<file preprocess="xml-stripblanks">sysprof-graphics-section.ui</file>