Skip to content
Open
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
15 changes: 15 additions & 0 deletions metadata/panel.xml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@
<_short>Battery Font</_short>
<default>default</default>
</option>
<option name="battery_settings" type="string">
<_short>Battery Settings</_short>
<_long>The command to run to show a Battery/Power settings window. Leave blank to attempt to automatically choose</_long>
<default></default>
</option>
</group>
<group>
<_short>Network</_short>
Expand Down Expand Up @@ -231,6 +236,11 @@
<_short>Switch User Button Command</_short>
<default>dm-tool switch-to-greeter</default>
</option>
<option name="menu_right_click" type="string">
<_short>Right click command</_short>
<_long>The command to run when the menu is right clicked</_long>
<default></default>
</option>
</group>
<group>
<_short>Volume</_short>
Expand All @@ -247,6 +257,11 @@
<_short>Volume Scroll Sensitivity</_short>
<default>0.05</default>
</option>
<option name="volume_settings" type="string">
<_short>Volume Settings</_short>
<_long>The command to run to show a volume settings window. Leave blank to attempt to automatically choose</_long>
<default></default>
</option>
</group>
<group>
<_short>Notifications</_short>
Expand Down
157 changes: 157 additions & 0 deletions src/panel/widgets/battery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
#include <gtk-utils.hpp>
#include <iostream>
#include <algorithm>
#include <glibmm.h>
#include "../../util/gtk-utils.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 +18,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 @@ -165,6 +173,33 @@ void WayfireBatteryInfo::update_state()
"\n\tWayfireBatteryInfo::update_state()" << std::endl;
}

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);
}
}
}
}

/*
Change the selected radio button.
*/
void WayfireBatteryInfo::set_current_profile(Glib::ustring profile)
{
state_action->set_state(Glib::Variant<Glib::ustring>::create(profile));
}

bool WayfireBatteryInfo::setup_dbus()
{
auto cancellable = Gio::Cancellable::create();
Expand All @@ -175,6 +210,30 @@ 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 @@ -206,10 +265,36 @@ bool WayfireBatteryInfo::setup_dbus()
return false;
}

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
}
}

// TODO: simplify config loading

void WayfireBatteryInfo::init(Gtk::Box *container)
{
profiles_menu = Gio::Menu::create();
state_action = Gio::SimpleAction::create_radio_string("set_profile", "");
settings_action = Gio::SimpleAction::create("settings");

if (!setup_dbus())
{
return;
Expand All @@ -231,4 +316,76 @@ void WayfireBatteryInfo::init(Gtk::Box *container)
button.set_child(button_box);
button.property_scale_factor().signal_changed()
.connect(sigc::mem_fun(*this, &WayfireBatteryInfo::update_icon));

menu = Gio::Menu::create();
auto item = Gio::MenuItem::create("Settings", "actions.settings");
menu->append_item(item);

menu->append_section("Profiles", profiles_menu);

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,
{}
);
}
});

settings_action->signal_activate().connect([=] (Glib::VariantBase vb)
{
std::vector<std::string> battery_programs = {"mate-power-statistics", "xfce4-power-manager"};

Glib::RefPtr<Gio::DesktopAppInfo> app_info;
std::string value = battery_settings;
if (value == "")
{
// Auto guess
for(auto program : battery_programs)
{
if(executable_exists(program))
{
auto keyfile = Glib::KeyFile::create();
keyfile->set_string("Desktop Entry", "Type", "Application");
keyfile->set_string("Desktop Entry", "Exec", "/bin/sh -c \"" + program + "\"");
app_info = Gio::DesktopAppInfo::create_from_keyfile(keyfile);
break;
}
}

} else
{
auto keyfile = Glib::KeyFile::create();
keyfile->set_string("Desktop Entry", "Type", "Application");
keyfile->set_string("Desktop Entry", "Exec", "/bin/sh -c \"" + value + "\"");
app_info = Gio::DesktopAppInfo::create_from_keyfile(keyfile);
}

if (app_info)
{
auto ctx = Gdk::Display::get_default()->get_app_launch_context();
app_info->launch(std::vector<Glib::RefPtr<Gio::File>>(), ctx);
}
});
actions->add_action(state_action);
actions->add_action(settings_action);

button.insert_action_group("actions", actions);

button.set_menu_model(menu);
}
29 changes: 26 additions & 3 deletions src/panel/widgets/battery.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
#ifndef WIDGETS_BATTERY_HPP
#define WIDGETS_BATTERY_HPP

#include <gtkmm/button.h>
#include <gtkmm/menubutton.h>
#include <gtkmm/image.h>
#include <gtkmm/box.h>
#include <gtkmm/label.h>
#include <gtkmm/popovermenu.h>


#include <giomm/dbusproxy.h>
#include <giomm/dbusconnection.h>
#include <giomm/menu.h>
#include <giomm/simpleaction.h>
#include <giomm/simpleactiongroup.h>
#include <giomm/file.h>
#include <giomm/desktopappinfo.h>

#include "../widget.hpp"

Expand All @@ -22,15 +29,23 @@ class wayfire_config;
class WayfireBatteryInfo : public WayfireWidget
{
WfOption<std::string> status_opt{"panel/battery_status"};
WfOption<std::string> battery_settings{"panel/battery_settings"};

Gtk::Button button;
Gtk::MenuButton button;
Gtk::Label label;
Gtk::Box button_box;

Gtk::Image icon;
Gtk::PopoverMenu popover;

std::shared_ptr<Gio::Menu> menu;
std::shared_ptr<Gio::Menu> profiles_menu;

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


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

bool setup_dbus();

Expand All @@ -42,6 +57,14 @@ 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);

public:
virtual void init(Gtk::Box *container);
virtual ~WayfireBatteryInfo() = default;
Expand Down
20 changes: 20 additions & 0 deletions src/panel/widgets/menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,26 @@ void WayfireMenu::init(Gtk::Box *container)
return;
}

auto click_gesture = Gtk::GestureClick::create();
click_gesture->set_button(3); // Only use right-click for this callback
click_gesture->signal_pressed().connect([=] (int count, double x, double y)
{
std::string value = menu_alternative_launch;
if (value != "")
{
auto keyfile = Glib::KeyFile::create();
keyfile->set_string("Desktop Entry", "Type", "Application");
keyfile->set_string("Desktop Entry", "Exec", "/bin/sh -c \"" + value + "\"");
AppInfo app_info = Gio::DesktopAppInfo::create_from_keyfile(keyfile);
if (app_info)
{
auto ctx = Gdk::Display::get_default()->get_app_launch_context();
app_info->launch(std::vector<Glib::RefPtr<Gio::File>>(), ctx);
}
}
});
button->add_controller(click_gesture);

button->property_scale_factor().signal_changed().connect(
[=] () {update_icon(); });

Expand Down
1 change: 1 addition & 0 deletions src/panel/widgets/menu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class WayfireMenu : public WayfireWidget
WfOption<int> menu_min_category_width{"panel/menu_min_category_width"};
WfOption<int> menu_min_content_height{"panel/menu_min_content_height"};
WfOption<bool> menu_show_categories{"panel/menu_show_categories"};
WfOption<std::string> menu_alternative_launch{"panel/menu_right_click"};
void update_popover_layout();
void update_category_width();
void update_content_height();
Expand Down
Loading