diff --git a/src/sysprof/sysprof-greeter.c b/src/sysprof/sysprof-greeter.c
index 5f44cb60..dc48c2d1 100644
--- a/src/sysprof/sysprof-greeter.c
+++ b/src/sysprof/sysprof-greeter.c
@@ -42,12 +42,14 @@ struct _SysprofGreeter
AdwWindow parent_instance;
GtkStringList *envvars;
+ GtkStringList *debugdirs;
SysprofRecordingTemplate *recording_template;
AdwViewStack *view_stack;
GtkListBox *sidebar_list_box;
AdwPreferencesPage *record_page;
GtkListBox *app_environment;
+ GtkListBox *debug_directories;
GtkSwitch *sample_native_stacks;
GtkSwitch *sample_javascript_stacks;
GtkSwitch *record_disk_usage;
@@ -109,6 +111,20 @@ on_env_items_changed_cb (SysprofGreeter *self,
g_list_model_get_n_items (model) > 0);
}
+static void
+on_debug_dir_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->debug_directories),
+ g_list_model_get_n_items (model) > 0);
+}
+
static void
on_env_entry_changed_cb (SysprofGreeter *self,
SysprofEntryPopover *popover)
@@ -155,6 +171,26 @@ failure:
sysprof_entry_popover_set_message (popover, errstr);
}
+static void
+on_debug_dir_entry_changed_cb (SysprofGreeter *self,
+ SysprofEntryPopover *popover)
+{
+ const char *errstr = NULL;
+ gboolean valid = FALSE;
+ const char *text;
+
+ g_assert (SYSPROF_IS_GREETER (self));
+ g_assert (SYSPROF_IS_ENTRY_POPOVER (popover));
+
+ text = sysprof_entry_popover_get_text (popover);
+
+ if (!(valid = g_file_test (text, G_FILE_TEST_IS_DIR)))
+ errstr = _("Directory does not exist");
+
+ 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,
@@ -168,6 +204,19 @@ on_env_entry_activate_cb (SysprofGreeter *self,
sysprof_entry_popover_set_text (popover, "");
}
+static void
+on_debug_dir_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->debugdirs));
+
+ gtk_string_list_append (self->debugdirs, text);
+ sysprof_entry_popover_set_text (popover, "");
+}
+
static void
sysprof_greeter_record_cb (GObject *object,
GAsyncResult *result,
@@ -205,6 +254,9 @@ sysprof_greeter_create_profiler (SysprofGreeter *self,
g_autoptr(GFile) dir = NULL;
GtkStringObject *strobj;
const char *str;
+ guint n_items;
+ g_autoptr(GStrvBuilder) builder = NULL;
+ g_auto(GStrv) debugdirs = NULL;
g_assert (SYSPROF_IS_GREETER (self));
@@ -232,6 +284,23 @@ sysprof_greeter_create_profiler (SysprofGreeter *self,
"power-profile", str,
NULL);
+ if ((n_items = g_list_model_get_n_items (G_LIST_MODEL (self->debugdirs))))
+ {
+ builder = g_strv_builder_new ();
+
+ for (guint i = 0; i < n_items; i++)
+ {
+ strobj = g_list_model_get_item (G_LIST_MODEL (self->debugdirs), i);
+ g_strv_builder_add (builder, gtk_string_object_get_string (strobj));
+ }
+
+ debugdirs = g_strv_builder_end (builder);
+
+ g_object_set (self->recording_template,
+ "debugdirs", debugdirs,
+ NULL);
+ }
+
if (!(profiler = sysprof_recording_template_apply (self->recording_template, error)))
return NULL;
@@ -453,6 +522,31 @@ delete_envvar_cb (SysprofGreeter *self,
}
}
+static void
+delete_debugdirs_cb (SysprofGreeter *self,
+ GtkButton *button)
+{
+ const char *debug_directory;
+ guint n_items;
+
+ g_assert (SYSPROF_IS_GREETER (self));
+ g_assert (GTK_IS_BUTTON (button));
+
+ debug_directory = g_object_get_data (G_OBJECT (button), "DEBUGDIR");
+ n_items = g_list_model_get_n_items (G_LIST_MODEL (self->debugdirs));
+
+ for (guint i = 0; i < n_items; i++)
+ {
+ g_autoptr(GtkStringObject) str = g_list_model_get_item (G_LIST_MODEL (self->debugdirs), i);
+
+ if (g_strcmp0 (debug_directory, gtk_string_object_get_string (str)) == 0)
+ {
+ gtk_string_list_remove (self->debugdirs, i);
+ break;
+ }
+ }
+}
+
static GtkWidget *
create_envvar_row_cb (gpointer item,
gpointer user_data)
@@ -493,6 +587,46 @@ create_envvar_row_cb (gpointer item,
return GTK_WIDGET (row);
}
+static GtkWidget *
+create_debugdirs_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 ("%s", 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),
+ "DEBUGDIR",
+ g_strdup (str),
+ g_free);
+ g_signal_connect_object (button,
+ "clicked",
+ G_CALLBACK (delete_debugdirs_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ adw_action_row_add_suffix (row, GTK_WIDGET (button));
+
+ return GTK_WIDGET (row);
+}
static char *
translate_power_profile (GtkStringObject *strobj)
@@ -542,6 +676,7 @@ sysprof_greeter_dispose (GObject *object)
gtk_widget_dispose_template (GTK_WIDGET (self), SYSPROF_TYPE_GREETER);
g_clear_object (&self->envvars);
+ g_clear_object (&self->debugdirs);
g_clear_object (&self->recording_template);
G_OBJECT_CLASS (sysprof_greeter_parent_class)->dispose (object);
@@ -558,9 +693,11 @@ 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, debug_directories);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, bundle_symbols);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, debuginfod);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, envvars);
+ gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, debugdirs);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, power_combo);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, record_compositor);
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, record_disk_usage);
@@ -582,6 +719,8 @@ sysprof_greeter_class_init (SysprofGreeterClass *klass)
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_bind_template_callback (widget_class, on_debug_dir_entry_changed_cb);
+ gtk_widget_class_bind_template_callback (widget_class, on_debug_dir_entry_activate_cb);
gtk_widget_class_bind_template_callback (widget_class, translate_power_profile);
gtk_widget_class_install_action (widget_class, "win.record-to-memory", NULL, sysprof_greeter_record_to_memory_action);
@@ -614,6 +753,13 @@ sysprof_greeter_init (SysprofGreeter *self)
G_CONNECT_SWAPPED);
on_env_items_changed_cb (self, 0, 0, 0, G_LIST_MODEL (self->envvars));
+ g_signal_connect_object (self->debugdirs,
+ "items-changed",
+ G_CALLBACK (on_debug_dir_items_changed_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ on_debug_dir_items_changed_cb (self, 0, 0, 0, G_LIST_MODEL (self->debugdirs));
+
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,
@@ -624,6 +770,11 @@ sysprof_greeter_init (SysprofGreeter *self)
create_envvar_row_cb,
self, NULL);
+ gtk_list_box_bind_model (self->debug_directories,
+ G_LIST_MODEL (self->debugdirs),
+ create_debugdirs_row_cb,
+ self, NULL);
+
if (self->recording_template)
{
g_auto(GStrv) environ = NULL;
diff --git a/src/sysprof/sysprof-greeter.ui b/src/sysprof/sysprof-greeter.ui
index e69e2658..5af1dcc5 100644
--- a/src/sysprof/sysprof-greeter.ui
+++ b/src/sysprof/sysprof-greeter.ui
@@ -636,6 +636,48 @@
+
+
+
@@ -706,6 +748,8 @@
+
+
diff --git a/src/sysprof/sysprof-recording-template.c b/src/sysprof/sysprof-recording-template.c
index 3d7646de..8b93b684 100644
--- a/src/sysprof/sysprof-recording-template.c
+++ b/src/sysprof/sysprof-recording-template.c
@@ -35,6 +35,7 @@ struct _SysprofRecordingTemplate
char *cwd;
char *power_profile;
char **environ;
+ char **debugdirs;
guint stack_size;
@@ -65,6 +66,7 @@ enum {
PROP_BATTERY_CHARGE,
PROP_BUNDLE_SYMBOLS,
PROP_DEBUGINFOD,
+ PROP_DEBUGDIRS,
PROP_CLEAR_ENVIRON,
PROP_COMMAND_LINE,
PROP_CPU_USAGE,
@@ -103,6 +105,7 @@ sysprof_recording_template_finalize (GObject *object)
g_clear_pointer (&self->cwd, g_free);
g_clear_pointer (&self->power_profile, g_free);
g_clear_pointer (&self->environ, g_free);
+ g_clear_pointer (&self->debugdirs, g_strfreev);
G_OBJECT_CLASS (sysprof_recording_template_parent_class)->finalize (object);
}
@@ -156,6 +159,10 @@ sysprof_recording_template_get_property (GObject *object,
case PROP_ENVIRON:
g_value_set_boxed (value, self->environ);
break;
+
+ case PROP_DEBUGDIRS:
+ g_value_set_boxed (value, self->debugdirs);
+ break;
case PROP_FRAME_TIMINGS:
g_value_set_boolean (value, self->frame_timings);
@@ -272,6 +279,11 @@ sysprof_recording_template_set_property (GObject *object,
g_clear_pointer (&self->environ, g_strfreev);
self->environ = g_value_dup_boxed (value);
break;
+
+ case PROP_DEBUGDIRS:
+ g_clear_pointer (&self->debugdirs, g_strfreev);
+ self->debugdirs = g_value_dup_boxed (value);
+ break;
case PROP_FRAME_TIMINGS:
self->frame_timings = g_value_get_boolean (value);
@@ -396,6 +408,11 @@ sysprof_recording_template_class_init (SysprofRecordingTemplateClass *klass)
g_param_spec_boxed ("environ", NULL, NULL,
G_TYPE_STRV,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ properties[PROP_DEBUGDIRS] =
+ g_param_spec_boxed ("debugdirs", NULL, NULL,
+ G_TYPE_STRV,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties[PROP_FRAME_TIMINGS] =
g_param_spec_boolean ("frame-timings", NULL, NULL,
@@ -783,9 +800,9 @@ sysprof_recording_template_create_loader (SysprofRecordingTemplate *self,
multi = sysprof_multi_symbolizer_new ();
elf = SYSPROF_ELF_SYMBOLIZER (sysprof_elf_symbolizer_new ());
- /* TODO: add extra-debug-directories property and use that to
- * call sysprof_elf_symbolizer_set_external_debug_dirs(elf,...)
- */
+
+ if (self->debugdirs)
+ sysprof_elf_symbolizer_set_external_debug_dirs (elf, (const char * const *)self->debugdirs);
/* Add in order of priority */
sysprof_multi_symbolizer_take (multi, sysprof_bundled_symbolizer_new ());