diff --git a/data/icons/powersaver-disabled.svg b/data/icons/powersaver-disabled.svg
new file mode 100644
index 0000000..87838bc
--- /dev/null
+++ b/data/icons/powersaver-disabled.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/data/icons/powersaver.svg b/data/icons/powersaver.svg
new file mode 100644
index 0000000..e9069d0
--- /dev/null
+++ b/data/icons/powersaver.svg
@@ -0,0 +1,34 @@
+
+
diff --git a/data/quick-settings.gresource.xml b/data/quick-settings.gresource.xml
index 8ed165f..75b9971 100644
--- a/data/quick-settings.gresource.xml
+++ b/data/quick-settings.gresource.xml
@@ -9,6 +9,8 @@
icons/dark-mode.svg
icons/system-suspend.svg
icons/quick-settings.svg
+ icons/powersaver-disabled.svg
+ icons/powersaver.svg
icons/rotation-allowed.svg
icons/rotation-locked.svg
diff --git a/src/DBus/PowerProfiles.vala b/src/DBus/PowerProfiles.vala
new file mode 100644
index 0000000..b202aca
--- /dev/null
+++ b/src/DBus/PowerProfiles.vala
@@ -0,0 +1,9 @@
+/*
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io)
+ */
+
+[DBus (name = "net.hadess.PowerProfiles")]
+public interface QuickSettings.PowerProfiles : Object {
+ public abstract string active_profile { owned get; set; }
+}
diff --git a/src/DBus/UPower.vala b/src/DBus/UPower.vala
new file mode 100644
index 0000000..4651864
--- /dev/null
+++ b/src/DBus/UPower.vala
@@ -0,0 +1,9 @@
+/*
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io)
+ */
+
+[DBus (name = "org.freedesktop.UPower")]
+public interface QuickSettings.UPower : Object {
+ public abstract bool on_battery { owned get; }
+}
diff --git a/src/PopoverWidget.vala b/src/PopoverWidget.vala
index 2cf9209..5ed4e35 100644
--- a/src/PopoverWidget.vala
+++ b/src/PopoverWidget.vala
@@ -21,6 +21,8 @@ public class QuickSettings.PopoverWidget : Gtk.Box {
}
construct {
+ var powermode_toggle = new PowerModeToggle ();
+
var toggle_box = new Gtk.FlowBox () {
column_spacing = 6,
homogeneous = true,
@@ -29,6 +31,7 @@ public class QuickSettings.PopoverWidget : Gtk.Box {
selection_mode = NONE
};
toggle_box.get_style_context ().add_class ("togglebox");
+ toggle_box.add (powermode_toggle);
var settings_button = new Gtk.Button.from_icon_name ("preferences-system-symbolic") {
tooltip_text = _("System Settingsā¦")
diff --git a/src/Widgets/PowerModeToggle.vala b/src/Widgets/PowerModeToggle.vala
new file mode 100644
index 0000000..1c0d633
--- /dev/null
+++ b/src/Widgets/PowerModeToggle.vala
@@ -0,0 +1,74 @@
+/*
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * SPDX-FileCopyrightText: 2023 elementary, Inc. (https://elementary.io)
+ */
+
+public class QuickSettings.PowerModeToggle: SettingsToggle {
+ public PowerModeToggle () {
+ Object (
+ icon: new ThemedIcon ("quick-settings-powersaver-symbolic"),
+ label: _("Power Saver")
+ );
+ }
+
+ construct {
+ settings_uri = "settings://power";
+
+ bind_property ("active", this, "icon", SYNC_CREATE, (binding, srcval, ref targetval) => {
+ if ((bool) srcval) {
+ targetval = new ThemedIcon ("quick-settings-powersaver-symbolic");
+ } else {
+ targetval = new ThemedIcon ("quick-settings-powersaver-disabled-symbolic");
+ }
+ return true;
+ });
+
+ setup_power_profiles.begin ((obj, res) => {
+ var power_profiles = setup_power_profiles.end (res);
+
+ ((DBusProxy) power_profiles).g_properties_changed.connect ((changed, invalid) => {
+ var active_profile = changed.lookup_value ("ActiveProfile", new VariantType ("s"));
+ if (active_profile != null) {
+ active = active_profile.get_string () == "power-saver";
+ }
+ });
+
+ active = power_profiles.active_profile == "power-saver";
+
+ setup_upower.begin ((obj, res) => {
+ var upower = setup_upower.end (res);
+
+ notify["active"].connect (() => {
+ if (active) {
+ power_profiles.active_profile = "power-saver";
+ } else {
+ var power_settings = new Settings ("io.elementary.settings-daemon.power");
+ if (upower.on_battery) {
+ power_profiles.active_profile = power_settings.get_string ("profile-on-good-battery");
+ } else {
+ power_profiles.active_profile = power_settings.get_string ("profile-plugged-in");
+ }
+ }
+ });
+ });
+ });
+ }
+
+ private async PowerProfiles? setup_power_profiles () {
+ try {
+ return yield Bus.get_proxy (BusType.SYSTEM, "net.hadess.PowerProfiles", "/net/hadess/PowerProfiles");
+ } catch (Error e) {
+ info ("Unable to connect to PowerProfiles: %s", e.message);
+ return null;
+ }
+ }
+
+ private async UPower? setup_upower () {
+ try {
+ return yield Bus.get_proxy (BusType.SYSTEM, "org.freedesktop.UPower", "/org/freedesktop/UPower");
+ } catch (Error e) {
+ info ("Unable to connect to Upower: %s", e.message);
+ return null;
+ }
+ }
+}
diff --git a/src/meson.build b/src/meson.build
index 7fca5e2..53db345 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -13,12 +13,15 @@ sources = [
'DBus' / 'AccountsService.vala',
'DBus' / 'EndSessionDialogServer.vala',
'DBus' / 'LockInterface.vala',
+ 'DBus' / 'PowerProfiles.vala',
'DBus' / 'SensorProxy.vala',
'DBus' / 'SessionInterface.vala',
'DBus' / 'SystemInterface.vala',
+ 'DBus' / 'UPower.vala',
'Views' / 'A11yView.vala',
'Widgets' / 'DarkModeToggle.vala',
'Widgets' / 'EndSessionDialog.vala',
+ 'Widgets' / 'PowerModeToggle.vala',
'Widgets' / 'RotationToggle.vala',
'Widgets' / 'SettingsToggle.vala',
'Widgets' / 'SessionBox.vala'