Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 129 additions & 12 deletions src/panel/widgets/battery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
#include <iostream>

#include "battery.hpp"

#define POWER_PROFILE_PATH "/org/freedesktop/UPower/PowerProfiles"
#define POWER_PROFILE_NAME "org.freedesktop.UPower.PowerProfiles"
#define UPOWER_NAME "org.freedesktop.UPower"
#define DISPLAY_DEVICE "/org/freedesktop/UPower/devices/DisplayDevice"

Expand All @@ -14,6 +15,10 @@
#define TIMETOEMPTY "TimeToEmpty"
#define SHOULD_DISPLAY "IsPresent"

#define DEGRADED "PerformanceDegraded"
#define PROFILES "Profiles"
#define ACTIVE_PROFILE "ActiveProfile"

static std::string get_device_type_description(uint32_t type)
{
if (type == 2)
Expand Down Expand Up @@ -139,14 +144,14 @@ void WayfireBatteryInfo::update_details()
description += ", " + uint_to_time(time_to_empty.get()) + " remaining";
}

box.set_tooltip_text(
box->set_tooltip_text(
get_device_type_description(type.get()) + description);

if (status_opt.value() == BATTERY_STATUS_PERCENT)
{
label.set_text(percentage_string);
overlay.remove_overlay(label);
box.append(label);
box->append(label);
} else if (status_opt.value() == BATTERY_STATUS_FULL)
{
label.set_text(description);
Expand All @@ -156,14 +161,14 @@ void WayfireBatteryInfo::update_details()
overlay.remove_overlay(label);
}

box.append(label);
box->append(label);
} else if (status_opt.value() == BATTERY_STATUS_OVERLAY)
{
label.set_text(percentage_string);
auto children = box.get_children();
auto children = box->get_children();
if (std::count(children.begin(), children.end(), &label))
{
box.remove(label);
box->remove(label);
}

overlay.add_overlay(label);
Expand Down Expand Up @@ -194,6 +199,31 @@ bool WayfireBatteryInfo::setup_dbus()
return false;
}

powerprofile_proxy = Gio::DBus::Proxy::create_sync(connection, POWER_PROFILE_NAME,
POWER_PROFILE_PATH,
POWER_PROFILE_NAME);
if (!powerprofile_proxy)
{
std::cout << "Unable to conect to Power Profiles. Continuing" << std::endl;
} else
{
powerprofile_proxy->signal_properties_changed().connect(
sigc::mem_fun(*this, &WayfireBatteryInfo::on_upower_properties_changed));
Glib::Variant<Glib::ustring> current_profile;
Glib::Variant<std::vector<std::map<Glib::ustring, Glib::VariantBase>>> profiles;
powerprofile_proxy->get_cached_property(current_profile, ACTIVE_PROFILE);
powerprofile_proxy->get_cached_property(profiles, PROFILES);

if (profiles && current_profile)
{
setup_profiles(profiles.get());
set_current_profile(current_profile.get());
} else
{
std::cout << "Unable to conect to Power Profiles. Continuing" << std::endl;
}
}

upower_proxy = Gio::DBus::Proxy::create_sync(connection, UPOWER_NAME,
"/org/freedesktop/UPower",
"org.freedesktop.UPower");
Expand Down Expand Up @@ -231,10 +261,10 @@ void WayfireBatteryInfo::update_layout()

if (panel_position.value() == PANEL_POSITION_LEFT or panel_position.value() == PANEL_POSITION_RIGHT)
{
box.set_orientation(Gtk::Orientation::VERTICAL);
box->set_orientation(Gtk::Orientation::VERTICAL);
} else
{
box.set_orientation(Gtk::Orientation::HORIZONTAL);
box->set_orientation(Gtk::Orientation::HORIZONTAL);
}
}

Expand All @@ -247,30 +277,117 @@ void WayfireBatteryInfo::handle_config_reload()

void WayfireBatteryInfo::init(Gtk::Box *container)
{
profiles_menu = Gio::Menu::create();
state_action = Gio::SimpleAction::create_radio_string("set_profile", "");
box = std::make_unique<WayfireMenuWidget>("panel", "battery");

if (!setup_dbus())
{
return;
}

box.append(overlay);
box->append(overlay);
overlay.set_child(icon);
icon.add_css_class("widget-icon");
box.add_css_class("battery");

status_opt.set_callback([=] () { update_details(); });

update_details();
update_icon();
auto actions = Gio::SimpleActionGroup::create();

state_action->signal_activate().connect([=] (Glib::VariantBase vb)
{
// User has requested a change of state. Don't change the UI choice, let the dbus roundtrip happen to
// be sure.
if (vb.is_of_type(Glib::VariantType("s")))
{
// Couldn't seem to make proxy send property back, so this will have to do
Glib::VariantContainerBase params = Glib::Variant<std::tuple<Glib::ustring, Glib::ustring,
Glib::VariantBase>>::create({POWER_PROFILE_NAME, ACTIVE_PROFILE, vb});

connection->call_sync(
POWER_PROFILE_PATH,
"org.freedesktop.DBus.Properties",
"Set",
params,
NULL,
POWER_PROFILE_NAME,
-1,
Gio::DBus::CallFlags::NONE,
{});
}
});

container->append(box);
box.set_spacing(5);
box->open_on(1);

actions->add_action(state_action);
box->insert_action_group("actions", actions);
container->append(*box);
box->set_spacing(5);
box->set_menu_model(profiles_menu);

icon.property_scale_factor().signal_changed()
.connect(sigc::mem_fun(*this, &WayfireBatteryInfo::update_icon));

update_layout();
}

void WayfireBatteryInfo::on_upower_properties_changed(
const Gio::DBus::Proxy::MapChangedProperties& properties,
const std::vector<Glib::ustring>& invalidated)
{
for (auto& prop : properties)
{
if (prop.first == ACTIVE_PROFILE)
{
if (prop.second.is_of_type(Glib::VariantType("s")))
{
auto value_string =
Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring>>(prop.second).get();
set_current_profile(value_string);
}
} else if (prop.first == PROFILES)
{
// I've been unable to find a way to change possible profiles on the fly, so cannot confirm this
// works at all.
auto value = Glib::VariantBase::cast_dynamic<Glib::Variant<std::vector<std::map<Glib::ustring,
Glib::VariantBase>>>>(prop.second);
setup_profiles(value.get());
}

// TODO Consider watching for "Performance Degraded" events too, but we currently have no way to
// output this additional information
}
}

void WayfireBatteryInfo::set_current_profile(Glib::ustring profile)
{
state_action->set_state(Glib::Variant<Glib::ustring>::create(profile));
}

void WayfireBatteryInfo::setup_profiles(std::vector<std::map<Glib::ustring, Glib::VariantBase>> profiles)
{
profiles_menu->remove_all();
for (auto profile : profiles)
{
if (profile.count("Profile") == 1)
{
Glib::VariantBase value = profile.at("Profile");
if (value.is_of_type(Glib::VariantType("s")))
{
auto value_string =
Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring>>(value).get();
auto item = Gio::MenuItem::create(value_string, "noactionyet");

item->set_action_and_target("actions.set_profile",
Glib::Variant<Glib::ustring>::create(value_string));
profiles_menu->append_item(item);
}
}
}
}

WayfireBatteryInfo::~WayfireBatteryInfo()
{
btn_sig.disconnect();
Expand Down
19 changes: 15 additions & 4 deletions src/panel/widgets/battery.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@

#include <giomm/dbusproxy.h>
#include <giomm/dbusconnection.h>
#include <giomm/simpleactiongroup.h>

#include <sigc++/connection.h>

#include "../widget.hpp"
#include "widget.hpp"
#include "wf-popover.hpp"

using DBusConnection = Glib::RefPtr<Gio::DBus::Connection>;
using DBusProxy = Glib::RefPtr<Gio::DBus::Proxy>;
Expand All @@ -29,13 +31,13 @@ class WayfireBatteryInfo : public WayfireWidget
sigc::connection btn_sig, disp_dev_sig;

Gtk::Label label;
Gtk::Box box;
std::unique_ptr<WayfireMenuWidget> box;
Gtk::Overlay overlay;

std::shared_ptr<Gio::Menu> profiles_menu;
Gtk::Image icon;

DBusConnection connection;
DBusProxy upower_proxy, display_device;
DBusProxy upower_proxy, powerprofile_proxy, display_device;

bool setup_dbus();

Expand All @@ -50,6 +52,15 @@ class WayfireBatteryInfo : public WayfireWidget
const Gio::DBus::Proxy::MapChangedProperties& properties,
const std::vector<Glib::ustring>& invalidated);

void on_upower_properties_changed(
const Gio::DBus::Proxy::MapChangedProperties& properties,
const std::vector<Glib::ustring>& invalidated);

void set_current_profile(Glib::ustring profile);
void setup_profiles(std::vector<std::map<Glib::ustring, Glib::VariantBase>> profiles);

std::shared_ptr<Gio::SimpleAction> state_action;

public:
virtual void init(Gtk::Box *container);
virtual ~WayfireBatteryInfo();
Expand Down
Loading