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 @@ + + + + + + image/svg+xml + + + + + + + + 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 @@ + + + + + + image/svg+xml + + + + + + + + + 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'