Skip to content

Commit

Permalink
Set power profiles based on whether the device is running on battery (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
lenemter authored Feb 8, 2024
1 parent e1fed9f commit adf9fb1
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 1 deletion.
13 changes: 13 additions & 0 deletions data/io.elementary.settings-daemon.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,17 @@
<description>How often to check for updates in seconds.</description>
</key>
</schema>

<schema path="/io/elementary/settings-daemon/power/" id="io.elementary.settings-daemon.power">
<key type="s" name="profile-plugged-in">
<default>"balanced"</default>
<summary>Power profile to use when plugged in</summary>
<description></description>
</key>
<key type="s" name="profile-on-good-battery">
<default>"balanced"</default>
<summary>Power profile to use on battery</summary>
<description></description>
</key>
</schema>
</schemalist>
3 changes: 2 additions & 1 deletion src/Application.vala
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ public sealed class SettingsDaemon.Application : Gtk.Application {

private Backends.KeyboardSettings keyboard_settings;
private Backends.MouseSettings mouse_settings;

private Backends.InterfaceSettings interface_settings;
private Backends.NightLightSettings night_light_settings;
private Backends.PrefersColorSchemeSettings prefers_color_scheme_settings;
private Backends.AccentColorManager accent_color_manager;

private Backends.Housekeeping housekeeping;
private Backends.PowerProfilesSync power_profiles_sync;

private const string FDO_ACCOUNTS_NAME = "org.freedesktop.Accounts";
private const string FDO_ACCOUNTS_PATH = "/org/freedesktop/Accounts";
Expand Down Expand Up @@ -55,6 +55,7 @@ public sealed class SettingsDaemon.Application : Gtk.Application {
base.startup ();

housekeeping = new Backends.Housekeeping ();
power_profiles_sync = new Backends.PowerProfilesSync ();

var check_firmware_updates_action = new GLib.SimpleAction ("check-firmware-updates", null);
check_firmware_updates_action.activate.connect (check_firmware_updates);
Expand Down
111 changes: 111 additions & 0 deletions src/Backends/PowerProfilesSync.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright 2024 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-3.0-or-later
*/

public class SettingsDaemon.Backends.PowerProfilesSync : GLib.Object {
[DBus (name = "org.freedesktop.UPower")]
private interface UPower : GLib.DBusProxy {
public abstract bool on_battery { get; }
}

[DBus (name = "net.hadess.PowerProfiles")]
private interface PowerProfile : GLib.DBusProxy {
public abstract HashTable<string, Variant>[] profiles { owned get; }
public abstract string active_profile { owned get; set; }
}

private const string PROFILE_PLUGGED_IN = "profile-plugged-in";
private const string PROFILE_ON_BATTERY = "profile-on-good-battery";

private GLib.Settings settings;
private UPower? upower = null;
private PowerProfile? power_profiles_daemon = null;

construct {
settings = new GLib.Settings ("io.elementary.settings-daemon.power");

Bus.watch_name (BusType.SYSTEM, "org.freedesktop.UPower", BusNameWatcherFlags.NONE, on_upower_watch, on_upower_unwatch);
Bus.watch_name (BusType.SYSTEM, "net.hadess.PowerProfiles", BusNameWatcherFlags.NONE, on_ppd_watch, on_ppd_unwatch);

settings.changed.connect (update_profile);
}

private void on_upower_watch (GLib.DBusConnection connection) {
connection.get_proxy.begin<UPower> (
"org.freedesktop.UPower", "/org/freedesktop/UPower", NONE, null,
(obj, res) => {
try {
upower = ((GLib.DBusConnection) obj).get_proxy.end<UPower> (res);
debug ("Connected to UPower");

update_profile ();

upower.g_properties_changed.connect ((changed_properties) => {
for (int i = 0; i < changed_properties.n_children (); i++) {
unowned string property;
changed_properties.get_child (i, "{&sv}", out property, null);
if (property == "OnBattery") {
update_profile ();
break;
}
}
});
} catch (Error e) {
critical (e.message);
upower = null;
}
}
);
}

private void on_upower_unwatch (GLib.DBusConnection connection) {
upower = null;
critical ("Lost connection to UPower");
}

private void on_ppd_watch (GLib.DBusConnection connection) {
connection.get_proxy.begin<PowerProfile> (
"net.hadess.PowerProfiles", "/net/hadess/PowerProfiles", NONE, null,
(obj, res) => {
try {
power_profiles_daemon = ((GLib.DBusConnection) obj).get_proxy.end<PowerProfile> (res);
debug ("Connected to power profiles daemon");

update_profile ();
} catch (Error e) {
critical (e.message);
power_profiles_daemon = null;
}
}
);
}

private void on_ppd_unwatch (GLib.DBusConnection connection) {
power_profiles_daemon = null;
critical ("Lost connection to power profiles daemon");
}

private void update_profile () {
if (power_profiles_daemon == null || upower == null) {
return;
}

var profile_to_set = settings.get_string (upower.on_battery ? PROFILE_ON_BATTERY : PROFILE_PLUGGED_IN);

var found_profile = false;
var profiles = power_profiles_daemon.profiles;
for (int i = 0; i < profiles.length; i++) {
if (profiles[i].get ("Profile").get_string () == profile_to_set) {
found_profile = true;
break;
}
}

if (found_profile) {
power_profiles_daemon.active_profile = profile_to_set;
} else {
warning ("Couldn't set power profile to %s", profile_to_set);
}
}
}
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ sources = files(
'Backends/KeyboardSettings.vala',
'Backends/MouseSettings.vala',
'Backends/NightLightSettings.vala',
'Backends/PowerProfilesSync.vala',
'Backends/PrefersColorSchemeSettings.vala',
'Backends/SystemUpdate.vala',
'Utils/SunriseSunsetCalculator.vala',
Expand Down

0 comments on commit adf9fb1

Please sign in to comment.