[gnome-bluetooth/wip/hadess/fix-shell-menu: 4/5] lib: Merge device removal with adapter removal
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-bluetooth/wip/hadess/fix-shell-menu: 4/5] lib: Merge device removal with adapter removal
- Date: Wed, 23 Feb 2022 17:54:19 +0000 (UTC)
commit a675f0902bc4c2b468fe60773c386ca204a8ba95
Author: Bastien Nocera <hadess hadess net>
Date: Wed Feb 23 18:38:56 2022 +0100
lib: Merge device removal with adapter removal
When an adapter is removed while bluetoothd is still running (eg. not
crashing as we also want to handle), suppress the emission of
device-removed so that front-ends don't think that every device is
removed.
We implement this by queue device-removed signals until the next
mainloop iteration instead of sending it straight away.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1426
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5058
lib/bluetooth-client.c | 69 ++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 55 insertions(+), 14 deletions(-)
---
diff --git a/lib/bluetooth-client.c b/lib/bluetooth-client.c
index bd138c02..64773333 100644
--- a/lib/bluetooth-client.c
+++ b/lib/bluetooth-client.c
@@ -65,6 +65,8 @@ struct _BluetoothClient {
gboolean discovery_started;
UpClient *up_client;
gboolean bluez_devices_coldplugged;
+ GList *removed_devices_queue;
+ guint removed_devices_queue_id;
};
enum {
@@ -343,26 +345,55 @@ device_added (GDBusObjectManager *manager,
g_signal_emit (G_OBJECT (client), signals[DEVICE_ADDED], 0, device_obj);
}
-static void
-device_removed (const char *path,
- BluetoothClient *client)
+static gboolean
+unqueue_device_removal (BluetoothClient *client)
{
- guint i, n_items;
+ GList *l;
- g_debug ("Removing device '%s'", path);
+ if (!client->removed_devices_queue)
+ return G_SOURCE_REMOVE;
- n_items = g_list_model_get_n_items (G_LIST_MODEL (client->list_store));
- for (i = 0; i < n_items; i++) {
- g_autoptr(BluetoothDevice) device = NULL;
+ for (l = client->removed_devices_queue; l != NULL; l = l->next) {
+ char *path = l->data;
+ guint i, n_items;
- device = g_list_model_get_item (G_LIST_MODEL (client->list_store), i);
- if (g_str_equal (path, bluetooth_device_get_object_path (device))) {
- g_signal_emit (G_OBJECT (client), signals[DEVICE_REMOVED], 0, path);
- g_list_store_remove (client->list_store, i);
- return;
+ n_items = g_list_model_get_n_items (G_LIST_MODEL (client->list_store));
+ for (i = 0; i < n_items; i++) {
+ g_autoptr(BluetoothDevice) device = NULL;
+
+ device = g_list_model_get_item (G_LIST_MODEL (client->list_store), i);
+ if (g_str_equal (path, bluetooth_device_get_object_path (device))) {
+ g_signal_emit (G_OBJECT (client), signals[DEVICE_REMOVED], 0, path);
+ g_list_store_remove (client->list_store, i);
+ g_free (path);
+ continue;
+ }
}
+ g_debug ("Device %s was not known, so not removed", path);
+ g_free (path);
}
- g_debug ("Device %s was not known, so not removed", path);
+ g_clear_pointer (&client->removed_devices_queue, g_list_free);
+
+ client->removed_devices_queue_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static void
+queue_device_removal (BluetoothClient *client,
+ const char *path)
+{
+ client->removed_devices_queue = g_list_prepend (client->removed_devices_queue,
+ g_strdup (path));
+ client->removed_devices_queue_id = g_idle_add ((GSourceFunc) unqueue_device_removal, client);
+}
+
+static void
+device_removed (const char *path,
+ BluetoothClient *client)
+{
+
+ g_debug ("Device '%s' was removed", path);
+ queue_device_removal (client, g_strdup (path));
}
static void
@@ -655,6 +686,7 @@ adapter_removed (GDBusObjectManager *manager,
g_autoptr(GDBusProxy) new_default_adapter = NULL;
GList *object_list, *l;
gboolean was_default = FALSE;
+ DefaultAdapterChangeType change_type;
if (g_strcmp0 (path, g_dbus_proxy_get_object_path (G_DBUS_PROXY (client->default_adapter))) == 0)
was_default = TRUE;
@@ -679,6 +711,14 @@ adapter_removed (GDBusObjectManager *manager,
}
g_list_free_full (object_list, g_object_unref);
+ /* Removal? */
+ change_type = new_default_adapter ? NEW_DEFAULT : REMOVAL;
+ if (change_type == REMOVAL) {
+ /* Clear out the removed_devices queue */
+ g_clear_handle_id (&client->removed_devices_queue_id, g_source_remove);
+ g_list_free_full (client->removed_devices_queue, g_free);
+ }
+
default_adapter_changed (manager,
new_default_adapter,
new_default_adapter ? NEW_DEFAULT : REMOVAL,
@@ -1209,6 +1249,7 @@ static void bluetooth_client_finalize(GObject *object)
g_cancellable_cancel (client->cancellable);
g_clear_object (&client->cancellable);
}
+ g_clear_handle_id (&client->removed_devices_queue_id, g_source_remove);
g_clear_object (&client->manager);
g_object_unref (client->list_store);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]