[gnome-settings-daemon/wip/hadess/low-device-warn-once: 11/11] power: Don't warn more than once per warning level for devices
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon/wip/hadess/low-device-warn-once: 11/11] power: Don't warn more than once per warning level for devices
- Date: Fri, 20 Nov 2020 16:59:11 +0000 (UTC)
commit 566d56b6f791cb617e869d5bbd4d21bc6108d9f4
Author: Bastien Nocera <hadess hadess net>
Date: Fri Nov 20 17:44:09 2020 +0100
power: Don't warn more than once per warning level for devices
A lot of wireless input devices, such as Logitech mice and touchpads, or
Bluetooth LE input devices, will disconnect and reconnect frequently
from the computer when unused.
This causes a problem when the battery on the device is low because
a new notification will be generated each time the device reconnects, as
if it was the first time it connected.
Saving the last warning-level for every external peripheral ensures that
we only emit one low battery notification for each warning-level, when
the threshold is crossed, rather than at every reconnect.
The last warning-level is not stored, so a new session, or a reboot will
cause devices to warn again once.
Closes: #108
plugins/power/gsd-power-manager.c | 57 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
---
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
index e45a24e7..f4a92d8c 100644
--- a/plugins/power/gsd-power-manager.c
+++ b/plugins/power/gsd-power-manager.c
@@ -161,6 +161,7 @@ struct _GsdPowerManager
NotifyNotification *notification_low;
NotifyNotification *notification_sleep_warning;
GsdPowerActionType sleep_action_type;
+ GHashTable *devices_notified_ht; /* key = serial str, value = UpDeviceLevel */
gboolean battery_is_low; /* laptop battery low, or UPS discharging */
/* Brightness */
@@ -256,16 +257,28 @@ static void
engine_device_add (GsdPowerManager *manager, UpDevice *device)
{
UpDeviceKind kind;
+ UpDeviceLevel warning_level;
+ g_autofree char *serial = NULL;
/* Batteries and UPSes are already handled through
* the composite battery */
- g_object_get (device, "kind", &kind, NULL);
+ g_object_get (device,
+ "kind", &kind,
+ "warning-level", &warning_level,
+ "serial", &serial,
+ NULL);
if (kind == UP_DEVICE_KIND_BATTERY ||
kind == UP_DEVICE_KIND_UPS ||
kind == UP_DEVICE_KIND_LINE_POWER)
return;
g_ptr_array_add (manager->devices_array, g_object_ref (device));
+ if (serial != NULL &&
+ warning_level != UP_DEVICE_LEVEL_UNKNOWN) {
+ g_hash_table_insert (manager->devices_notified_ht,
+ g_strdup (serial),
+ GINT_TO_POINTER (warning_level));
+ }
g_signal_connect (device, "notify::warning-level",
G_CALLBACK (engine_device_warning_changed_cb), manager);
@@ -449,6 +462,40 @@ manager_critical_action_stop_sound_cb (GsdPowerManager *manager)
return FALSE;
}
+static gboolean
+engine_device_should_warn (GsdPowerManager *manager,
+ UpDeviceKind kind,
+ UpDeviceLevel warning,
+ const char *serial)
+{
+ gpointer last_warning_ptr;
+ UpDeviceLevel last_warning;
+ gboolean ret = TRUE;
+
+ if (!serial)
+ return TRUE;
+
+ if (kind == UP_DEVICE_KIND_BATTERY ||
+ kind == UP_DEVICE_KIND_UPS)
+ return TRUE;
+
+ if (!g_hash_table_lookup_extended (manager->devices_notified_ht, serial,
+ NULL, &last_warning_ptr))
+ return TRUE;
+
+ last_warning = GPOINTER_TO_INT (last_warning_ptr);
+
+ if (last_warning >= warning)
+ ret = FALSE;
+
+ if (warning != UP_DEVICE_LEVEL_UNKNOWN)
+ g_hash_table_insert (manager->devices_notified_ht,
+ g_strdup (serial),
+ GINT_TO_POINTER (warning));
+
+ return ret;
+}
+
static void
engine_charge_low (GsdPowerManager *manager, UpDevice *device)
{
@@ -894,14 +941,19 @@ engine_charge_action (GsdPowerManager *manager, UpDevice *device)
static void
engine_device_warning_changed_cb (UpDevice *device, GParamSpec *pspec, GsdPowerManager *manager)
{
+ g_autofree char *serial = NULL;
UpDeviceLevel warning;
UpDeviceKind kind;
g_object_get (device,
+ "serial", &serial,
"warning-level", &warning,
"kind", &kind,
NULL);
+ if (!engine_device_should_warn (manager, kind, warning, serial))
+ return;
+
if (warning == UP_DEVICE_LEVEL_DISCHARGING) {
g_debug ("** EMIT: discharging");
engine_ups_discharging (manager, device);
@@ -2571,6 +2623,8 @@ on_rr_screen_acquired (GObject *object,
manager);
manager->devices_array = g_ptr_array_new_with_free_func (g_object_unref);
+ manager->devices_notified_ht = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
/* create a fake virtual composite battery */
manager->device_composite = up_client_get_display_device (manager->up_client);
@@ -2815,6 +2869,7 @@ gsd_power_manager_stop (GsdPowerManager *manager)
g_clear_pointer (&manager->devices_array, g_ptr_array_unref);
g_clear_object (&manager->device_composite);
+ g_clear_pointer (&manager->devices_notified_ht, g_hash_table_destroy);
g_clear_object (&manager->screensaver_proxy);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]