# HG changeset patch
# Node ID ade6af14aa20
# Parent  2c943710bb7f
diff --git a/gplugin/gplugin-manager.c b/gplugin/gplugin-manager.c
--- a/gplugin/gplugin-manager.c
+++ b/gplugin/gplugin-manager.c
@@ -57,6 +57,8 @@
 	SIG_UNLOADING,
 	SIG_UNLOADED,
 	SIG_UNLOAD_FAILED,
+	SIG_LOADER_REGISTERED,
+	SIG_LOADER_UNREGISTERED,
 	N_SIGNALS,
 };
 
@@ -435,6 +437,50 @@
 		G_TYPE_NONE,
 		1,
 		G_TYPE_OBJECT);
+
+	/**
+	 * GPluginManager::loader-registered:
+	 * @manager: The [class@GPlugin.Manager] instance.
+	 * @loader: The [class@GPlugin.Loader] instance that was registered.
+	 *
+	 * Emitted when @loader has been registered with @manager via
+	 * [method@GPlugin.Manager.register_loader].
+	 *
+	 * Since: 0.39.0
+	 */
+	signals[SIG_LOADER_REGISTERED] = g_signal_new_class_handler(
+		"loader-registered",
+		G_OBJECT_CLASS_TYPE(klass),
+		G_SIGNAL_RUN_LAST,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		G_TYPE_NONE,
+		1,
+		G_TYPE_OBJECT);
+
+	/**
+	 * GPluginManager::loader-unregistered:
+	 * @manager: The [class@GPlugin.Manager] instance.
+	 * @loader: The [class@GPlugin.Loader] instance that was unregistered.
+	 *
+	 * Emitted when @loader has been unregistered from @manager via
+	 * [method@GPlugin.Manager.unregister_loader].
+	 *
+	 * Since: 0.39.0
+	 */
+	signals[SIG_LOADER_UNREGISTERED] = g_signal_new_class_handler(
+		"loader-unregistered",
+		G_OBJECT_CLASS_TYPE(klass),
+		G_SIGNAL_RUN_LAST,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		G_TYPE_NONE,
+		1,
+		G_TYPE_OBJECT);
 }
 
 static void
@@ -813,6 +859,8 @@
 	/* make a note that we need to refresh */
 	manager->refresh_needed = TRUE;
 
+	g_signal_emit(manager, signals[SIG_LOADER_REGISTERED], 0, loader);
+
 	return TRUE;
 }
 
@@ -894,7 +942,16 @@
 	}
 	g_slist_free(exts);
 
-	g_hash_table_remove(manager->loaders, id);
+	/* Temporarily add a reference to loader so we can emit the signal if it
+	 * was removed from our table correctly.
+	 */
+	g_object_ref(loader);
+
+	if(g_hash_table_remove(manager->loaders, id)) {
+		g_signal_emit(manager, signals[SIG_LOADER_UNREGISTERED], 0, loader);
+	}
+
+	g_clear_object(&loader);
 
 	return TRUE;
 }
diff --git a/gplugin/tests/test-loader-registration.c b/gplugin/tests/test-loader-registration.c
--- a/gplugin/tests/test-loader-registration.c
+++ b/gplugin/tests/test-loader-registration.c
@@ -99,6 +99,21 @@
 		NULL));
 	/* clang-format on */
 }
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+test_gplugin_manager_loader_registration_counter(
+	G_GNUC_UNUSED GPluginManager *manager,
+	G_GNUC_UNUSED GPluginLoader *loader,
+	gpointer data)
+{
+	gint *counter = data;
+
+	*counter = *counter + 1;
+}
+
 /******************************************************************************
  * Tests
  *****************************************************************************/
@@ -109,11 +124,22 @@
 	GPluginLoader *loader = NULL;
 	GError *error = NULL;
 	gboolean ret;
+	gint registrations = 0, unregistrations = 0;
 
 	gplugin_manager_private_uninit();
 	gplugin_manager_private_init(TRUE);
 
 	manager = gplugin_manager_get_default();
+	g_signal_connect(
+		manager,
+		"loader-registered",
+		G_CALLBACK(test_gplugin_manager_loader_registration_counter),
+		&registrations);
+	g_signal_connect(
+		manager,
+		"loader-unregistered",
+		G_CALLBACK(test_gplugin_manager_loader_registration_counter),
+		&unregistrations);
 
 	loader = test_gplugin_loader_new();
 
@@ -125,6 +151,9 @@
 	g_assert_no_error(error);
 	g_assert_true(ret);
 
+	g_assert_cmpuint(registrations, ==, 1);
+	g_assert_cmpuint(unregistrations, ==, 1);
+
 	g_clear_object(&loader);
 }
 
@@ -135,11 +164,22 @@
 	GPluginLoader *loader = NULL;
 	GError *error = NULL;
 	gboolean ret;
+	guint registrations = 0, unregistrations = 0;
 
 	gplugin_manager_private_uninit();
 	gplugin_manager_private_init(TRUE);
 
 	manager = gplugin_manager_get_default();
+	g_signal_connect(
+		manager,
+		"loader-registered",
+		G_CALLBACK(test_gplugin_manager_loader_registration_counter),
+		&registrations);
+	g_signal_connect(
+		manager,
+		"loader-unregistered",
+		G_CALLBACK(test_gplugin_manager_loader_registration_counter),
+		&unregistrations);
 
 	loader = test_gplugin_loader_new();
 
@@ -156,6 +196,9 @@
 	g_assert_no_error(error);
 	g_assert_true(ret);
 
+	g_assert_cmpuint(registrations, ==, 1);
+	g_assert_cmpuint(unregistrations, ==, 1);
+
 	g_clear_object(&loader);
 }
 
@@ -166,11 +209,22 @@
 	GPluginLoader *loader = NULL;
 	GError *error = NULL;
 	gboolean ret;
+	guint registrations = 0, unregistrations = 0;
 
 	gplugin_manager_private_uninit();
 	gplugin_manager_private_init(TRUE);
 
 	manager = gplugin_manager_get_default();
+	g_signal_connect(
+		manager,
+		"loader-registered",
+		G_CALLBACK(test_gplugin_manager_loader_registration_counter),
+		&registrations);
+	g_signal_connect(
+		manager,
+		"loader-unregistered",
+		G_CALLBACK(test_gplugin_manager_loader_registration_counter),
+		&unregistrations);
 
 	loader = test_gplugin_loader_new();
 
@@ -187,6 +241,9 @@
 	g_assert_error(error, GPLUGIN_DOMAIN, 0);
 	g_clear_error(&error);
 
+	g_assert_cmpuint(registrations, ==, 1);
+	g_assert_cmpuint(unregistrations, ==, 1);
+
 	g_clear_object(&loader);
 }
 
