Skip to content

Commit

Permalink
power-indicator: add popover controls for power-profiles-daemon
Browse files Browse the repository at this point in the history
  • Loading branch information
justchen1369 committed Jul 7, 2023
1 parent 87c035b commit e9bc02f
Showing 1 changed file with 154 additions and 1 deletion.
155 changes: 154 additions & 1 deletion src/panel/applets/status/PowerIndicator.vala
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,130 @@ public class BatteryIcon : Gtk.Box {
}
}

const string POWER_PROFILES_DBUS_NAME = "net.hadess.PowerProfiles";
const string POWER_PROFILES_DBUS_OBJECT_NAME = "/net/hadess/PowerProfiles";

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

public class PowerProfilesSelector : Gtk.Box {
// Power profile toggles
private Gtk.RadioButton radio_power_save;
private Gtk.RadioButton radio_power_balanced;
private Gtk.RadioButton radio_power_performance;

// these are used to temporarily block signals and prevent an infinite loop
private ulong radio_power_save_id;
private ulong radio_power_balanced_id;
private ulong radio_power_performance_id;

public PowerProfilesSelector(PowerProfilesDBus profiles_proxy) {
orientation = Gtk.Orientation.VERTICAL;

var profiles = new GenericSet<string>(str_hash, str_equal);

foreach (HashTable<string, Variant> profile in profiles_proxy.profiles) {
var profile_value = profile.get("Profile");

if (!profile_value.is_of_type(VariantType.STRING)) {
warning("unexpected type for power profile: is not of VariantType.STRING");
continue;
}

profiles.add(profile_value.get_string());
}

if (profiles.length < 2) {
// need at least two options for it to be meaningful
warning("Fewer than two power profile options");
return;
}

// initialize state
on_active_profile_changed(profiles_proxy.active_profile);

((DBusProxy) profiles_proxy).g_properties_changed.connect(() => {
on_active_profile_changed(profiles_proxy.active_profile);
});

var sep = new Gtk.Separator(Gtk.Orientation.HORIZONTAL);
pack_start(sep, false, false, 1);

var header = new Gtk.Label("");
header.set_markup("<b>%s</b>".printf(_("Power Mode")));
header.set_halign(Gtk.Align.CENTER);
pack_start(header);

var power_profiles_radio_box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 1);

if (profiles.contains("power-saver")) {
radio_power_save = new Gtk.RadioButton.with_label_from_widget(null, _("Power Saver"));
radio_power_save_id = radio_power_save.toggled.connect(() => {
if (radio_power_save.get_active()) {
profiles_proxy.active_profile = "power-saver";
}
});
power_profiles_radio_box.pack_start(radio_power_save, false, false, 1);
}

if (profiles.contains("balanced")) {
radio_power_balanced = new Gtk.RadioButton.with_label_from_widget(radio_power_save, _("Balanced"));
radio_power_balanced_id = radio_power_balanced.toggled.connect(() => {
if (radio_power_balanced.get_active()) {
profiles_proxy.active_profile = "balanced";
}
});
power_profiles_radio_box.pack_start(radio_power_balanced, false, false, 1);
}

if (profiles.contains("performance")) {
radio_power_performance = new Gtk.RadioButton.with_label_from_widget(radio_power_save, _("Performance"));
radio_power_performance_id = radio_power_performance.toggled.connect(() => {
if (radio_power_performance.get_active()) {
profiles_proxy.active_profile = "performance";
}
});
power_profiles_radio_box.pack_start(radio_power_performance, false, false, 1);
}

pack_start(power_profiles_radio_box);
}

void on_active_profile_changed(string active_profile) {
SignalHandler.block(radio_power_save, radio_power_save_id);
SignalHandler.block(radio_power_balanced, radio_power_balanced_id);
SignalHandler.block(radio_power_performance, radio_power_performance_id);

switch(active_profile) {
case "power-saver":
radio_power_save.set_active(true);
break;
case "balanced":
radio_power_balanced.set_active(true);
break;
case "performance":
radio_power_performance.set_active(true);
break;
}

SignalHandler.unblock(radio_power_save, radio_power_save_id);
SignalHandler.unblock(radio_power_balanced, radio_power_balanced_id);
SignalHandler.unblock(radio_power_performance, radio_power_performance_id);
}
}

public class PowerIndicator : Gtk.Bin {
/** Widget containing battery icons to display */
public Gtk.EventBox? ebox = null;
public Budgie.Popover? popover = null;
private Gtk.Box widget = null;
private Gtk.Box box = null;

private PowerProfilesDBus profiles_proxy;
private PowerProfilesSelector power_profiles_selector;

/** Our upower client */
public Up.Client client { protected set; public get; }
Expand All @@ -170,7 +289,7 @@ public class PowerIndicator : Gtk.Bin {
ebox.add(widget);

popover = new Budgie.Popover(ebox);
var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 1);
box = new Gtk.Box(Gtk.Orientation.VERTICAL, 1);
box.border_width = 6;
popover.add(box);

Expand All @@ -196,12 +315,46 @@ public class PowerIndicator : Gtk.Bin {

client = new Up.Client();

Bus.watch_name(BusType.SYSTEM, POWER_PROFILES_DBUS_NAME, BusNameWatcherFlags.NONE, has_power_profiles, lost_power_profiles);

this.sync_devices();
client.device_added.connect(this.on_device_added);
client.device_removed.connect(this.on_device_removed);
toggle_show();
}

void has_power_profiles() {
if (profiles_proxy == null) {
Bus.get_proxy.begin<PowerProfilesDBus>(BusType.SYSTEM, POWER_PROFILES_DBUS_NAME, POWER_PROFILES_DBUS_OBJECT_NAME, 0, null, on_proxy_get);
} else {
// already have a proxy object
create_power_profiles_options();
}
}

void lost_power_profiles() {
power_profiles_selector.destroy();
}

void on_proxy_get(Object? o, AsyncResult? res) {
try {
profiles_proxy = Bus.get_proxy.end(res);

if (profiles_proxy.active_profile != null) {
create_power_profiles_options();
}

} catch (Error e) {
warning("unable to connect to net.hadess.PowerProfiles: %s", e.message);
}
}

void create_power_profiles_options() {
power_profiles_selector = new PowerProfilesSelector(profiles_proxy);
box.pack_start(power_profiles_selector);
box.show_all();
}

public void change_orientation(Gtk.Orientation orient) {
int spacing = 0;
if (orient == Gtk.Orientation.VERTICAL) {
Expand Down

0 comments on commit e9bc02f

Please sign in to comment.