From bf7f275ec23c1513c9a43d9ddc517124b07467c4 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Sun, 6 Aug 2023 17:42:20 -0700 Subject: [PATCH] sysprof: allow selecting a power porofile --- src/sysprof/meson.build | 1 + src/sysprof/sysprof-greeter.c | 53 ++++++++++++++++- src/sysprof/sysprof-greeter.ui | 7 ++- src/sysprof/sysprof-power-profiles.c | 88 ++++++++++++++++++++++++++++ src/sysprof/sysprof-power-profiles.h | 29 +++++++++ 5 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 src/sysprof/sysprof-power-profiles.c create mode 100644 src/sysprof/sysprof-power-profiles.h diff --git a/src/sysprof/meson.build b/src/sysprof/meson.build index 7308cee2..eaa6c720 100644 --- a/src/sysprof/meson.build +++ b/src/sysprof/meson.build @@ -40,6 +40,7 @@ sysprof_sources = [ 'sysprof-process-dialog.c', 'sysprof-processes-section.c', 'sysprof-progress-cell.c', + 'sysprof-power-profiles.c', 'sysprof-recording-pad.c', 'sysprof-recording-template.c', 'sysprof-samples-section.c', diff --git a/src/sysprof/sysprof-greeter.c b/src/sysprof/sysprof-greeter.c index 6f2cd0f2..6e6269df 100644 --- a/src/sysprof/sysprof-greeter.c +++ b/src/sysprof/sysprof-greeter.c @@ -28,6 +28,7 @@ #include "sysprof-entry-popover.h" #include "sysprof-greeter.h" +#include "sysprof-power-profiles.h" #include "sysprof-recording-pad.h" #include "sysprof-recording-template.h" @@ -54,6 +55,7 @@ struct _SysprofGreeter GtkSwitch *record_system_bus; GtkSwitch *bundle_symbols; GtkButton *record_to_memory; + AdwComboRow *power_combo; SysprofRecordingTemplate *recording_template; }; @@ -176,6 +178,28 @@ sysprof_greeter_record_cb (GObject *object, gtk_window_destroy (GTK_WINDOW (self)); } +static SysprofProfiler * +sysprof_greeter_create_profiler (SysprofGreeter *self, + GError **error) +{ + g_autoptr(SysprofProfiler) profiler = NULL; + GtkStringObject *strobj; + const char *str; + + g_assert (SYSPROF_IS_GREETER (self)); + + if ((strobj = adw_combo_row_get_selected_item (self->power_combo)) && + (str = gtk_string_object_get_string (strobj))) + g_object_set (self->recording_template, + "power-profile", str, + NULL); + + if (!(profiler = sysprof_recording_template_apply (self->recording_template, error))) + return NULL; + + return g_steal_pointer (&profiler); +} + static void sysprof_greeter_record_to_memory_action (GtkWidget *widget, const char *action_name, @@ -192,7 +216,7 @@ sysprof_greeter_record_to_memory_action (GtkWidget *widget, fd = sysprof_memfd_create ("[sysprof-profile]"); /* TODO: Handle recording error */ - if (!(profiler = sysprof_recording_template_apply (self->recording_template, &error))) + if (!(profiler = sysprof_greeter_create_profiler (self, &error))) return; writer = sysprof_capture_writer_new_from_fd (g_steal_fd (&fd), 0); @@ -228,7 +252,7 @@ sysprof_greeter_choose_file_for_record_cb (GObject *object, g_autoptr(SysprofProfiler) profiler = NULL; /* TODO: Handle recording error */ - if (!(profiler = sysprof_recording_template_apply (self->recording_template, &error))) + if (!(profiler = sysprof_greeter_create_profiler (self, &error))) return; writer = sysprof_capture_writer_new (g_file_peek_path (file), 0); @@ -479,6 +503,26 @@ create_envvar_row_cb (gpointer item, return GTK_WIDGET (row); } +static char * +translate_power_profile (GtkStringObject *strobj) +{ + const char *str = gtk_string_object_get_string (strobj); + + if (g_str_equal (str, "")) + return g_strdup (_("No Change")); + + if (g_str_equal (str, "balanced")) + return g_strdup (_("Balanced")); + + if (g_str_equal (str, "power-saver")) + return g_strdup (_("Power Saver")); + + if (g_str_equal (str, "performance")) + return g_strdup (_("Performance")); + + return g_strdup (str); +} + static void sysprof_greeter_dispose (GObject *object) { @@ -551,6 +595,7 @@ sysprof_greeter_class_init (SysprofGreeterClass *klass) 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, envvars); + 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); gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, record_network_usage); @@ -569,6 +614,7 @@ 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, translate_power_profile); 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); @@ -581,10 +627,13 @@ sysprof_greeter_class_init (SysprofGreeterClass *klass) static void sysprof_greeter_init (SysprofGreeter *self) { + g_autoptr(GListModel) power_profiles = sysprof_power_profiles_new (); GtkListBoxRow *row; gtk_widget_init_template (GTK_WIDGET (self)); + adw_combo_row_set_model (self->power_combo, power_profiles); + g_signal_connect_object (self->envvars, "items-changed", G_CALLBACK (on_env_items_changed_cb), diff --git a/src/sysprof/sysprof-greeter.ui b/src/sysprof/sysprof-greeter.ui index 87fd4e0e..c0e5127e 100644 --- a/src/sysprof/sysprof-greeter.ui +++ b/src/sysprof/sysprof-greeter.ui @@ -467,9 +467,12 @@ Power Profile - + Record with Power Profile - Hold the power profile for the duration of the recording and restore when finished + Switch to power profile while recording + + + diff --git a/src/sysprof/sysprof-power-profiles.c b/src/sysprof/sysprof-power-profiles.c new file mode 100644 index 00000000..bdf5ae13 --- /dev/null +++ b/src/sysprof/sysprof-power-profiles.c @@ -0,0 +1,88 @@ +/* sysprof-power-profiles.c + * + * Copyright 2023 Christian Hergert + * + * 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 . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "config.h" + +#include + +#include "sysprof-power-profiles.h" + +static const char *fallback[] = { "", "power-saver", "performance", "balanced", NULL }; + +static void +free_string (gpointer strptr) +{ + char **str = strptr; + g_clear_pointer (str, g_free); +} + +GListModel * +sysprof_power_profiles_new (void) +{ + g_autoptr(GVariant) result = NULL; + g_autoptr(GVariant) child = NULL; + g_autoptr(GVariant) grandchild = NULL; + g_autoptr(GVariant) vdict = NULL; + g_autoptr(GDBusConnection) bus = NULL; + g_autoptr(GArray) strings = NULL; + char *empty; + GVariantIter iter; + + bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); + if (bus == NULL) + goto failure; + + result = g_dbus_connection_call_sync (bus, + "net.hadess.PowerProfiles", + "/net/hadess/PowerProfiles", + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new ("(ss)", + "net.hadess.PowerProfiles", + "Profiles"), + G_VARIANT_TYPE ("(v)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL); + if (result == NULL) + goto failure; + + strings = g_array_new (TRUE, FALSE, sizeof (char*)); + empty = g_strdup (""); + g_array_append_val (strings, empty); + + g_array_set_clear_func (strings, free_string); + child = g_variant_get_child_value (result, 0); + grandchild = g_variant_get_child_value (child, 0); + g_variant_iter_init (&iter, grandchild); + while (g_variant_iter_loop (&iter, "@a{sv}", &vdict)) + { + char *name = NULL; + + if (g_variant_lookup (vdict, "Profile", "s", &name)) + g_array_append_val (strings, name); + } + + return G_LIST_MODEL (gtk_string_list_new ((const char * const *)(gpointer)strings->data)); + +failure: + return G_LIST_MODEL (gtk_string_list_new (fallback)); +} diff --git a/src/sysprof/sysprof-power-profiles.h b/src/sysprof/sysprof-power-profiles.h new file mode 100644 index 00000000..87e0ae50 --- /dev/null +++ b/src/sysprof/sysprof-power-profiles.h @@ -0,0 +1,29 @@ +/* sysprof-power-profiles.h + * + * Copyright 2023 Christian Hergert + * + * 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 . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +GListModel *sysprof_power_profiles_new (void); + +G_END_DECLS