Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cs_power: Add Power Profile options to the power module #12523

Merged
merged 9 commits into from
Nov 27, 2024
47 changes: 29 additions & 18 deletions files/usr/share/cinnamon/applets/[email protected]/applet.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ const Settings = imports.ui.settings;

const BrightnessBusName = "org.cinnamon.SettingsDaemon.Power.Screen";
const KeyboardBusName = "org.cinnamon.SettingsDaemon.Power.Keyboard";
const PowerProfilesBusName = "net.hadess.PowerProfiles";
const PowerProfilesBusPath = "/net/hadess/PowerProfiles";

const CSD_BACKLIGHT_NOT_SUPPORTED_CODE = 1;

Expand All @@ -32,17 +30,6 @@ const POWER_PROFILES = {
"performance": _("Performance")
};

const PowerProfilesInterface = `<node>
<interface name="${PowerProfilesBusName}">
<property name="ActiveProfile" type="s" access="readwrite" />
<property name="PerformanceDegraded" type="s" access="read" />
<property name="Profiles" type="aa{sv}" access="read" />
<property name="ActiveProfileHolds" type="aa{sv}" access="read" />
</interface>
</node>`;

const PowerProfilesProxy = Gio.DBusProxy.makeProxyWrapper(PowerProfilesInterface);

function deviceLevelToString(level) {
switch (level) {
case UPDeviceLevel.FULL:
Expand Down Expand Up @@ -402,12 +389,36 @@ class CinnamonPowerApplet extends Applet.TextIconApplet {
this.menu.addMenuItem(this.keyboard);

try {
this._profilesProxy = new PowerProfilesProxy(Gio.DBus.system, PowerProfilesBusName, PowerProfilesBusPath);
} catch (error) {
this._profilesProxy = null;
// Hadess interface
let PowerProfilesInterface = `<node>
<interface name="net.hadess.PowerProfiles">
<property name="ActiveProfile" type="s" access="readwrite" />
<property name="PerformanceDegraded" type="s" access="read" />
<property name="Profiles" type="aa{sv}" access="read" />
<property name="ActiveProfileHolds" type="aa{sv}" access="read" />
</interface>
</node>`;
let PowerProfilesProxy = Gio.DBusProxy.makeProxyWrapper(PowerProfilesInterface);
this._profilesProxy = new PowerProfilesProxy(Gio.DBus.system, "net.haess.PowerProfiles", "/net/hadess/PowerProfiles");
// Upower if hadess doesn't work..
if (!this._profilesProxy.Profiles) {
// UPower interface
let PowerProfilesInterface = `<node>
<interface name="org.freedesktop.UPower.PowerProfiles">
<property name="ActiveProfile" type="s" access="readwrite" />
<property name="PerformanceDegraded" type="s" access="read" />
<property name="Profiles" type="aa{sv}" access="read" />
<property name="ActiveProfileHolds" type="aa{sv}" access="read" />
</interface>
</node>`;
let PowerProfilesProxy = Gio.DBusProxy.makeProxyWrapper(PowerProfilesInterface);
this._profilesProxy = new PowerProfilesProxy(Gio.DBus.system, "org.freedesktop.UPower.PowerProfiles", "/org/freedesktop/UPower/PowerProfiles");
}
} catch {
this._profilesProxy = null;
}

if (this._profilesProxy.Profiles) {
if (this._profilesProxy && this._profilesProxy.Profiles) {
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.contentSection = new PopupMenu.PopupMenuSection();

Expand Down
96 changes: 94 additions & 2 deletions files/usr/share/cinnamon/cinnamon-settings/modules/cs_power.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@
(0, _("Never"))
]

POWER_PROFILES = {
"power-saver": _("Power Saver"),
"balanced": _("Balanced"),
"performance": _("Performance")
}

(UP_ID, UP_VENDOR, UP_MODEL, UP_TYPE, UP_ICON, UP_PERCENTAGE, UP_STATE, UP_BATTERY_LEVEL, UP_SECONDS) = range(9)

try:
Expand Down Expand Up @@ -140,7 +146,7 @@ def on_module_selected(self):

power_page = SettingsPage()

section = power_page.add_section(_("Power Options"))
section = power_page.add_section(_("Power options"))

lid_options, button_power_options, critical_options, can_suspend, can_hybrid_sleep, can_hibernate = get_available_options(self.up_client)

Expand Down Expand Up @@ -198,6 +204,26 @@ def on_module_selected(self):
self.sth_switch.content_widget.connect("notify::active", self.on_sth_toggled)
section.add_row(self.sth_switch)

# Power mode
connection = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
proxy = None
profiles = None
for dbus_name in ["net.hadess.PowerProfiles", "org.freedesktop.UPower.PowerProfiles"]:
try:
dbus_path = "/" + dbus_name.replace(".", "/")
proxy = Gio.DBusProxy.new_sync(connection, Gio.DBusProxyFlags.NONE, None,
dbus_name, dbus_path, "org.freedesktop.DBus.Properties", None)
profiles = proxy.Get('(ss)', dbus_name, "Profiles")
print(f"Found power profiles on Dbus at {dbus_name}")
break
except:
pass

if profiles:
combo = PowerModeComboBox(proxy, dbus_name, profiles)
combo.set_tooltip_text(_("Power mode controls the power usage of your computer. It can impact performance, battery life and fan noise."))
section.add_row(combo)

# Batteries

self.battery_page = SettingsPage()
Expand Down Expand Up @@ -294,7 +320,6 @@ def build_battery_page(self, *args):
# UPowerGlib segfaults when trying to get device. Use CSD instead
devices = self.csd_power_proxy.GetDevices()

have_primary = False
ups_as_primary = False

have_keyboard = False
Expand Down Expand Up @@ -817,3 +842,70 @@ def on_my_setting_changed2(self, *args):
def add_to_size_group(self, group):
group.add_widget(self.content_widget1)
group.add_widget(self.content_widget2)


class PowerModeComboBox(SettingsWidget):
def __init__(self, proxy, dbus_name, profiles, dep_key=None, size_group=None):
super(PowerModeComboBox, self).__init__(dep_key=dep_key)

self.proxy = proxy
self.dbus_name = dbus_name

try:
profiles_options = []
for profile in profiles:
name = profile["Profile"]
label = name
if name in POWER_PROFILES.keys():
label = POWER_PROFILES[name]
profiles_options.append([name, label])

self.option_map = {}

self.label = Gtk.Label.new(_("Power mode"))
self.model = Gtk.ListStore(str, str)

for option in profiles_options:
iter = self.model.insert_before(None, None)
self.model.set_value(iter, 0, option[0])
self.model.set_value(iter, 1, option[1])
self.option_map[option[0]] = iter

self.content_widget = Gtk.ComboBox.new_with_model(self.model)
renderer_text = Gtk.CellRendererText()
self.content_widget.pack_start(renderer_text, True)
self.content_widget.add_attribute(renderer_text, "text", 1)

self.pack_start(self.label, False, False, 0)
self.pack_end(self.content_widget, False, True, 0)

self.content_widget.connect('changed', self.on_my_value_changed)
self.proxy.connect('g-signal', self.on_dbus_changed)
self.on_my_setting_changed()

if size_group:
self.add_to_size_group(size_group)
except GLib.Error as e:
print(f"Power profiles options not available: {e.message}")

def on_my_value_changed(self, widget):
tree_iter = widget.get_active_iter()
if tree_iter is not None:
profile = self.model[tree_iter][0]
value = GLib.Variant.new_string(profile)
self.proxy.Set('(ssv)', self.dbus_name, "ActiveProfile", value)

def on_dbus_changed(self, proxy, sender, signal, params):
if signal == "PropertiesChanged":
self.on_my_setting_changed()

def on_my_setting_changed(self):
try:
active_profile = self.proxy.Get('(ss)', self.dbus_name, "ActiveProfile")
self.content_widget.set_active_iter(self.option_map[active_profile])
except Exception as e:
print(e)
self.content_widget.set_active_iter(None)

def add_to_size_group(self, group):
group.add_widget(self.content_widget)
Loading