This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository enlightenment.
View the commit online.
commit 48d4dbbb209bfc4cbffcf45bf5ac8377b83a1eed
Author: Carsten Haitzler <ras...@rasterman.com>
AuthorDate: Fri Apr 4 12:00:56 2025 +0100
battery - support charge limit control for battery life improvement
support newish controls for setting maximum battery charge which is
used to improve battery life. add a slider that shows it and allow
user to change it.
@feat
---
src/bin/system/e_system.h | 3 +
src/bin/system/e_system_battery.c | 136 +++++++++++++++++++++++++++++++++++++
src/bin/system/e_system_main.c | 2 +
src/bin/system/meson.build | 1 +
src/modules/battery/e_mod_main.c | 69 ++++++++++++++-----
src/modules/battery/e_mod_main.h | 1 +
src/modules/battery/e_mod_sysctl.c | 2 +
src/modules/battery/e_mod_udev.c | 9 +++
src/modules/battery/e_mod_upower.c | 1 +
9 files changed, 207 insertions(+), 17 deletions(-)
diff --git a/src/bin/system/e_system.h b/src/bin/system/e_system.h
index 4eb4a5c33..b78cdb06d 100644
--- a/src/bin/system/e_system.h
+++ b/src/bin/system/e_system.h
@@ -129,6 +129,9 @@ void e_system_ddc_shutdown(void);
void e_system_acpi_init(void);
void e_system_acpi_shutdown(void);
+void e_system_battery_init(void);
+void e_system_battery_shutdown(void);
+
extern Ecore_Exe *e_system_run(const char *exe);
#endif
diff --git a/src/bin/system/e_system_battery.c b/src/bin/system/e_system_battery.c
new file mode 100644
index 000000000..8ebbe7f85
--- /dev/null
+++ b/src/bin/system/e_system_battery.c
@@ -0,0 +1,136 @@
+#include "e_system.h"
+#if defined __OpenBSD__
+// no local funcs
+#elif defined __FreeBSD__
+// no local funcs
+#else
+
+typedef struct
+{
+ char *syspath;
+} Dev;
+
+static Eina_List *devices = NULL;
+static Eeze_Udev_Watch *watch = NULL;
+
+static Dev *
+dev_find(const char *syspath)
+{
+ Eina_List *l;
+ Dev *d;
+
+ EINA_LIST_FOREACH(devices, l, d)
+ {
+ if (!strcmp(syspath, d->syspath)) return d;
+ }
+ return NULL;
+}
+
+static Eina_Bool
+dev_have(const char *file)
+{
+ if (dev_find(file)) return EINA_TRUE;
+ return EINA_FALSE;
+}
+
+static void
+dev_del(Dev *d)
+{
+ if (!d) return;
+ devices = eina_list_remove(devices, d);
+ free(d->syspath);
+ free(d);
+}
+
+static Dev *
+dev_add(const char *syspath)
+{
+ Dev *d = NULL;
+
+ fprintf(stderr, "BAT: ADD BAT [%s]\n", syspath);
+ d = calloc(1, sizeof(Dev));
+ if (!d) return NULL;
+ d->syspath = strdup(syspath);
+ if (!d->syspath)
+ {
+ free(d);
+ return NULL;
+ }
+ devices = eina_list_append(devices, d);
+ return d;
+}
+
+static void
+_cb_eeze(const char *syspath, Eeze_Udev_Event ev,
+ void *data EINA_UNUSED, Eeze_Udev_Watch *w EINA_UNUSED)
+{
+ if ((ev & EEZE_UDEV_EVENT_ADD) ||
+ (ev & EEZE_UDEV_EVENT_ONLINE))
+ {
+ if (!dev_have(syspath)) dev_add(syspath);
+ }
+ else if ((ev & EEZE_UDEV_EVENT_REMOVE) ||
+ (ev & EEZE_UDEV_EVENT_OFFLINE))
+ {
+ dev_del(dev_find(syspath));
+ }
+ // else - some update but we don't care here
+
+}
+
+static void
+_cb_battery_lim_set(void *data EINA_UNUSED, const char *params EINA_UNUSED)
+{ // reply = "dev1 -|p dev2 -|p ..."
+ char dev[1024] = "", buf2[32];
+ int val = 0;
+ Dev *d;
+ int fd;
+
+ if (sscanf(params, "%1023s %i", dev, &val) != 2) return;
+ if (val < 1) val = 1;
+ else if (val > 100) val = 100;
+ d = dev_find(dev);
+ fprintf(stderr, "BAT: device = %p for [%s]\n", d, dev);
+ if (!d) return;
+ snprintf(dev, sizeof(dev), "%s/charge_control_end_threshold", d->syspath);
+ snprintf(buf2, sizeof(buf2), "%i", val);
+ fd = open(dev, O_WRONLY);
+ fprintf(stderr, "BAT: device [%s] fd = %i -> [%s]\n", dev, fd, buf2);
+ if (fd >= 0)
+ {
+ if (write(fd, buf2, strlen(buf2)) <= 0)
+ ERR("Write failed of [%s] to [%s]\n", buf2, dev);
+ close(fd);
+ }
+}
+#endif
+
+void
+e_system_battery_init(void)
+{
+#if defined __OpenBSD__
+// no local funcs
+#elif defined __FreeBSD__
+// no local funcs
+#else
+ Eina_List *devs;
+ const char *dev;
+
+ devs = eeze_udev_find_by_type(EEZE_UDEV_TYPE_POWER_BAT, NULL);
+ fprintf(stderr, "BAT: devices = %p\n", devs);
+ EINA_LIST_FREE(devs, dev)
+ {
+ if (!dev_have(dev)) dev_add(dev);
+ }
+
+ watch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_BAT, EEZE_UDEV_EVENT_NONE,
+ _cb_eeze, NULL);
+#endif
+ e_system_inout_command_register("battery-lim-set", _cb_battery_lim_set, NULL);
+}
+
+void
+e_system_battery_shutdown(void)
+{
+ // only shutdown things we really have to - no need to free mem etc.
+}
diff --git a/src/bin/system/e_system_main.c b/src/bin/system/e_system_main.c
index 2c789d150..f2ac0abe4 100644
--- a/src/bin/system/e_system_main.c
+++ b/src/bin/system/e_system_main.c
@@ -174,6 +174,7 @@ main(int argc EINA_UNUSED, const char **argv EINA_UNUSED)
CONF_INIT_CHECK("l2ping", e_system_l2ping_init, init_l2ping);
CONF_INIT_CHECK("cpufreq", e_system_cpufreq_init, init_cpufreq);
CONF_INIT_CHECK("acpi", e_system_acpi_init, init_acpi);
+ CONF_INIT_CHECK("battery", e_system_battery_init, init_battery);
if (systems == 0)
{
@@ -185,6 +186,7 @@ main(int argc EINA_UNUSED, const char **argv EINA_UNUSED)
ecore_main_loop_begin();
+ CONF_SHUTDOWN(e_system_battery_shutdown, init_battery);
CONF_SHUTDOWN(e_system_acpi_shutdown, init_acpi);
CONF_SHUTDOWN(e_system_cpufreq_shutdown, init_cpufreq);
CONF_SHUTDOWN(e_system_l2ping_shutdown, init_l2ping);
diff --git a/src/bin/system/meson.build b/src/bin/system/meson.build
index d4c9fe17b..d3008e659 100644
--- a/src/bin/system/meson.build
+++ b/src/bin/system/meson.build
@@ -9,6 +9,7 @@ src = [
'e_system_l2ping.c',
'e_system_cpufreq.c',
'e_system_acpi.c',
+ 'e_system_battery.c',
'e_system.h',
]
executable('enlightenment_system', src,
diff --git a/src/modules/battery/e_mod_main.c b/src/modules/battery/e_mod_main.c
index 88b34ec94..0bfb0cff8 100644
--- a/src/modules/battery/e_mod_main.c
+++ b/src/modules/battery/e_mod_main.c
@@ -34,6 +34,8 @@ typedef struct _Instance Instance;
typedef struct __Popup_Widgets
{
+ Battery *bat;
+
Evas_Object *pb_usage;
Evas_Object *state;
Evas_Object *remaining;
@@ -43,6 +45,7 @@ typedef struct __Popup_Widgets
Evas_Object *drain;
Evas_Object *full;
Evas_Object *power;
+ Evas_Object *charge_lim;
Evas_Object *gr_bat;
Evas_Object *gr_pow;
@@ -373,6 +376,9 @@ _battery_popup_usage_content_update_cb(void *data)
else
elm_object_text_set(w->power, _("Unknown"));
+ if ((w->charge_lim) && (bat->charge_lim >= 0))
+ elm_slider_value_set(w->charge_lim, bat->charge_lim);
+
{
int *v_full, *v_pow, *v_crg, age;
unsigned int vals_num;
@@ -470,6 +476,16 @@ _icon_get(void *data EINA_UNUSED, Evas_Object *obj, const char *part)
return ic;
}
+static void
+_cb_charge_lim_change(void *data, Evas_Object *obj, void *info EINA_UNUSED)
+{
+ _Popup_Widgets *w = data;
+ double v = elm_slider_value_get(obj);
+
+ w->bat->charge_lim = (int)v;
+ e_system_send("battery-lim-set", "%s %i\n", w->bat->udi, (int)v);
+}
+
static Evas_Object *
_content_get(void *data, Evas_Object *obj, const char *part)
{
@@ -599,32 +615,49 @@ _content_get(void *data, Evas_Object *obj, const char *part)
elm_table_pack(tb, o, 1, 3, 1, 1);
evas_object_show(o);
+ if (w->bat->charge_lim >= 0)
+ {
+ w->charge_lim = o = elm_slider_add(obj);
+ evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(o, 1.0, 1.0);
+ elm_object_text_set(o, _("Charge Limit"));
+ elm_slider_unit_format_set(o, "%1.0f%%");
+ elm_slider_indicator_format_set(o, "%1.0f%%");
+ elm_slider_min_max_set(o, 10, 100);
+ elm_slider_step_set(o, 5);
+ elm_slider_value_set(o, w->bat->charge_lim);
+ evas_object_smart_callback_add(o, "changed", _cb_charge_lim_change, w);
+ elm_table_pack(tb, o, 0, 4, 8, 1);
+ evas_object_show(o);
+ }
+ else w->charge_lim = NULL;
+
w->gr_pow = o = e_graph_add(obj);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(o, 1.0, 1.0);
evas_object_size_hint_min_set(o, ELM_SCALE_SIZE(80), ELM_SCALE_SIZE(40));
- elm_table_pack(tb, o, 0, 4, 8, 1);
- evas_object_show(o);
-
- o = elm_label_add(obj);
- elm_object_text_set(o, _("Energy"));
- evas_object_size_hint_align_set(o, 0.0, 0.0);
- evas_object_size_hint_weight_set(o, 1.0, 0);
- elm_table_pack(tb, o, 1, 4, 1, 1);
- evas_object_show(o);
-
- w->gr_crg = o = e_graph_add(obj);
- evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_size_hint_weight_set(o, 1.0, 1.0);
- evas_object_size_hint_min_set(o, ELM_SCALE_SIZE(80), ELM_SCALE_SIZE(40));
elm_table_pack(tb, o, 0, 5, 8, 1);
evas_object_show(o);
+ o = elm_label_add(obj);
+ elm_object_text_set(o, _("Energy"));
+ evas_object_size_hint_align_set(o, 0.0, 0.0);
+ evas_object_size_hint_weight_set(o, 1.0, 0);
+ elm_table_pack(tb, o, 1, 6, 1, 1);
+ evas_object_show(o);
+
+ w->gr_crg = o = e_graph_add(obj);
+ evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(o, 1.0, 1.0);
+ evas_object_size_hint_min_set(o, ELM_SCALE_SIZE(80), ELM_SCALE_SIZE(40));
+ elm_table_pack(tb, o, 0, 7, 8, 1);
+ evas_object_show(o);
+
o = elm_label_add(obj);
elm_object_text_set(o, _("(Dis)charge"));
evas_object_size_hint_align_set(o, 0.0, 0.0);
evas_object_size_hint_weight_set(o, 1.0, 0);
- elm_table_pack(tb, o, 1, 5, 1, 1);
+ elm_table_pack(tb, o, 1, 8, 1, 1);
evas_object_show(o);
return tb;
@@ -657,8 +690,8 @@ _battery_popup_usage_new(Instance *inst)
evas_object_show(tb);
rec = evas_object_rectangle_add(evas_object_evas_get(base));
- evas_object_size_hint_min_set(rec, ELM_SCALE_SIZE(400), ELM_SCALE_SIZE(280));
- evas_object_size_hint_max_set(rec, ELM_SCALE_SIZE(560), ELM_SCALE_SIZE(450));
+ evas_object_size_hint_min_set(rec, ELM_SCALE_SIZE(400), ELM_SCALE_SIZE(330));
+ evas_object_size_hint_max_set(rec, ELM_SCALE_SIZE(560), ELM_SCALE_SIZE(480));
elm_table_pack(tb, rec, 0, 0, 1, 1);
glist = elm_genlist_add(base);
@@ -687,6 +720,8 @@ _battery_popup_usage_new(Instance *inst)
EINA_LIST_FOREACH(device_batteries, l, bat)
{
_Popup_Widgets *w = &pd->widgets[i++];
+
+ w->bat = bat;
if ((bat->vendor) && (bat->model))
snprintf(buf, sizeof(buf), _("Battery: %s (%s)"), bat->vendor, bat->model);
else if (bat->vendor)
diff --git a/src/modules/battery/e_mod_main.h b/src/modules/battery/e_mod_main.h
index 716b47b71..2a9999595 100644
--- a/src/modules/battery/e_mod_main.h
+++ b/src/modules/battery/e_mod_main.h
@@ -117,6 +117,7 @@ struct _Battery
const char *technology;
const char *model;
const char *vendor;
+ int charge_lim;
int history_power_now_max;
Eina_Bool got_prop E_BITFIELD;
Eldbus_Proxy *proxy;
diff --git a/src/modules/battery/e_mod_sysctl.c b/src/modules/battery/e_mod_sysctl.c
index 7a800b11d..713329ea3 100644
--- a/src/modules/battery/e_mod_sysctl.c
+++ b/src/modules/battery/e_mod_sysctl.c
@@ -62,6 +62,7 @@ _battery_sysctl_start(void)
bat->technology = eina_stringshare_add("Unknown");
bat->model = eina_stringshare_add("Unknown");
bat->vendor = eina_stringshare_add("Unknown");
+ bat->charge_lim = -1;
bat->timer = ecore_timer_add(10.0, _battery_sysctl_battery_update_poll, NULL);
device_batteries = eina_list_append(device_batteries, bat);
}
@@ -105,6 +106,7 @@ _battery_sysctl_start(void)
bat->model = eina_stringshare_add(battio.bix.model);
bat->design_charge = battio.bix.dcap;
bat->last_full_charge = battio.bix.lfcap;
+ bat->charge_lim = -1;
bat->timer = ecore_timer_add(10.0, _battery_sysctl_battery_update_poll, NULL);
bat->unit = i;
device_batteries = eina_list_append(device_batteries, bat);
diff --git a/src/modules/battery/e_mod_udev.c b/src/modules/battery/e_mod_udev.c
index b8c907364..127f704d2 100644
--- a/src/modules/battery/e_mod_udev.c
+++ b/src/modules/battery/e_mod_udev.c
@@ -163,6 +163,10 @@ _battery_udev_battery_add(const char *syspath)
bat->last_update = ecore_time_get();
bat->udi = eina_stringshare_add(syspath);
bat->timer = ecore_timer_add(10.0, _battery_udev_battery_update_poll, bat);
+
+ test = eeze_udev_syspath_get_sysattr(syspath, "charge_control_end_threshold");
+ if (!test) bat->charge_lim = -1;
+ else bat->charge_lim = atoi(test);
device_batteries = eina_list_append(device_batteries, bat);
_battery_udev_battery_update(syspath, bat);
}
@@ -330,6 +334,11 @@ _battery_udev_battery_update(const char *syspath, Battery *bat)
}
else
bat->charging = 0;
+
+ test = eeze_udev_syspath_get_sysattr(bat->udi, "charge_control_end_threshold");
+ if (!test) bat->charge_lim = -1;
+ else bat->charge_lim = atoi(test);
+
test = eeze_udev_syspath_get_property(bat->udi, "POWER_SUPPLY_ENERGY_NOW");
if (!test)
test = eeze_udev_syspath_get_property(bat->udi, "POWER_SUPPLY_CHARGE_NOW");
diff --git a/src/modules/battery/e_mod_upower.c b/src/modules/battery/e_mod_upower.c
index 5826ed3f5..d817d2fbc 100644
--- a/src/modules/battery/e_mod_upower.c
+++ b/src/modules/battery/e_mod_upower.c
@@ -227,6 +227,7 @@ _process_battery(Eldbus_Proxy *proxy)
bat->udi = eina_stringshare_add(eldbus_object_path_get(eldbus_proxy_object_get(proxy)));
eldbus_proxy_property_get_all(proxy, _bat_get_all_cb, bat);
eldbus_proxy_signal_handler_add(upower_proxy_bat, "PropertiesChanged", _bat_changed_cb, bat);
+ bat->charge_lim = -1;
device_batteries = eina_list_append(device_batteries, bat);
_battery_device_update();
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.