gplugin/gplugin

Merged in feature/plugin-errors (pull request #77)
develop
2020-05-21, Gary Kramlich
f7de83d8ea56
Merged in feature/plugin-errors (pull request #77)

Add an error property to GPluginPlugin and fix the ui/tests/etc that were affected by it.

Approved-by: Elliott Sales de Andrade
--- a/ChangeLog Tue May 12 05:21:57 2020 +0000
+++ b/ChangeLog Thu May 21 07:53:56 2020 +0000
@@ -18,7 +18,15 @@
* Renamed the GPluginManager::load-failed signal to
GPluginManager::load-plugin-failed and added the error, if any, that the
plugin returned. (Gary Kramlich)
- * Added gplugin_manager_find_plugin_with_newest_version.
+ * Added gplugin_manager_find_plugin_with_newest_version. (Gary Kramlich)
+ * Added an "error" property to GPluginPlugin with a getter. (Gary Kramlich)
+ * Removed the error parameter from the "plugin-load-failed" and
+ "plugin-unload-failed" signals. Call gplugin_plugin_get_error instead.
+ (Gary Kramlich)
+ * Updated the GPluginGtkView widget to disable entries if there are in the
+ GPLUGIN_PLUGIN_STATE_LOAD_FAILED state. (Gary Kramlich)
+ * Updated the GPluginGtkPluginInfo widget to display the "error" property if
+ it is set, or "(none)". (Gary Kramlich)
Lua Loader
* Removed the moonscript support from the Lua loader. (Gary Kramlich)
--- a/gplugin-gtk/data/plugin-info.ui Tue May 12 05:21:57 2020 +0000
+++ b/gplugin-gtk/data/plugin-info.ui Thu May 21 07:53:56 2020 +0000
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.22.1 -->
+<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<template class="GPluginGtkPluginInfo" parent="GtkBox">
@@ -208,7 +208,7 @@
<property name="yalign">0</property>
</object>
<packing>
- <property name="expand">True</property>
+ <property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
@@ -260,6 +260,45 @@
</packing>
</child>
<child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="error_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Error</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="error">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkExpander">
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -517,7 +556,7 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">7</property>
+ <property name="position">8</property>
</packing>
</child>
</template>
@@ -535,6 +574,7 @@
<widget name="loader_label"/>
<widget name="internal_label"/>
<widget name="load_on_query_label"/>
+ <widget name="error_label"/>
</widgets>
</object>
</interface>
--- a/gplugin-gtk/gplugin-gtk-plugin-info.c Tue May 12 05:21:57 2020 +0000
+++ b/gplugin-gtk/gplugin-gtk-plugin-info.c Thu May 21 07:53:56 2020 +0000
@@ -45,6 +45,7 @@
GtkBox parent;
GPluginPlugin *plugin;
+ gulong signal_id;
GtkWidget *name;
GtkWidget *version;
@@ -53,6 +54,7 @@
GtkWidget *summary;
GtkWidget *description;
GtkWidget *dependencies;
+ GtkWidget *error;
GtkWidget *expander;
GtkWidget *id;
GtkWidget *filename;
@@ -94,11 +96,10 @@
* Helpers
*****************************************************************************/
static void
-_gplugin_gtk_plugin_info_refresh(
- GPluginGtkPluginInfo *info,
- GPluginPlugin *plugin)
+_gplugin_gtk_plugin_info_refresh(GPluginGtkPluginInfo *info)
{
GtkWidget *widget = NULL;
+ GError *error = NULL;
GList *children = NULL, *iter = NULL;
gchar *markup = NULL;
gchar *name = NULL, *version = NULL, *website = NULL;
@@ -116,11 +117,12 @@
g_list_free(children);
/* now get the info if we can */
- if(GPLUGIN_IS_PLUGIN(plugin)) {
- GPluginPluginInfo *plugin_info = gplugin_plugin_get_info(plugin);
- GPluginLoader *plugin_loader = gplugin_plugin_get_loader(plugin);
+ if(GPLUGIN_IS_PLUGIN(info->plugin)) {
+ GPluginPluginInfo *plugin_info = gplugin_plugin_get_info(info->plugin);
+ GPluginLoader *plugin_loader = gplugin_plugin_get_loader(info->plugin);
- filename = gplugin_plugin_get_filename(plugin);
+ filename = gplugin_plugin_get_filename(info->plugin);
+ error = gplugin_plugin_get_error(info->plugin);
if(plugin_loader && GPLUGIN_IS_LOADER(plugin_loader)) {
const char *loader_name = G_OBJECT_TYPE_NAME(plugin_loader);
@@ -176,6 +178,9 @@
GTK_LABEL(info->description),
(description) ? description : "");
gtk_label_set_text(GTK_LABEL(info->id), (id) ? id : "");
+ gtk_label_set_text(
+ GTK_LABEL(info->error),
+ (error) ? error->message : "(none)");
gtk_label_set_text(GTK_LABEL(info->filename), (filename) ? filename : "");
gtk_label_set_text(
GTK_LABEL(info->abi_version),
@@ -190,6 +195,7 @@
g_free(version);
g_free(website);
g_free(loader);
+ g_clear_error(&error);
/* set the authors */
if(authors) {
@@ -212,6 +218,15 @@
}
/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static void
+gplugin_gtk_plugin_info_state_cb(GObject *obj, GParamSpec *pspec, gpointer data)
+{
+ _gplugin_gtk_plugin_info_refresh(GPLUGIN_GTK_PLUGIN_INFO(data));
+}
+
+/******************************************************************************
* GObject Stuff
*****************************************************************************/
static void
@@ -257,6 +272,10 @@
{
GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(obj);
+ if(info->signal_id != 0) {
+ g_signal_handler_disconnect(G_OBJECT(info->plugin), info->signal_id);
+ }
+
g_clear_object(&info->plugin);
G_OBJECT_CLASS(gplugin_gtk_plugin_info_parent_class)->finalize(obj);
@@ -266,6 +285,8 @@
gplugin_gtk_plugin_info_init(GPluginGtkPluginInfo *info)
{
gtk_widget_init_template(GTK_WIDGET(info));
+
+ info->signal_id = 0;
}
static void
@@ -322,6 +343,11 @@
gtk_widget_class_bind_template_child(
widget_class,
GPluginGtkPluginInfo,
+ error);
+
+ gtk_widget_class_bind_template_child(
+ widget_class,
+ GPluginGtkPluginInfo,
expander);
gtk_widget_class_bind_template_child(
widget_class,
@@ -387,8 +413,26 @@
{
g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_INFO(info));
+ if(info->signal_id != 0 && GPLUGIN_IS_PLUGIN(info->plugin)) {
+ g_signal_handler_disconnect(info->plugin, info->signal_id);
+ info->signal_id = 0;
+ }
+
if(g_set_object(&info->plugin, plugin)) {
- _gplugin_gtk_plugin_info_refresh(info, plugin);
+ _gplugin_gtk_plugin_info_refresh(info);
+
+ /* Connect a signal to refresh when the plugin's state changes. We
+ * can't use g_signal_connect_object because the plugin object never
+ * gets destroyed, as the manager and the loader both keep a reference
+ * to it and the GPluginGtkPluginInfo widget is reused for all plugins
+ * so that all means that we just have to manage the callback
+ * ourselves.
+ */
+ info->signal_id = g_signal_connect(
+ G_OBJECT(plugin),
+ "notify::state",
+ G_CALLBACK(gplugin_gtk_plugin_info_state_cb),
+ info);
}
}
--- a/gplugin-gtk/gplugin-gtk-store.c Tue May 12 05:21:57 2020 +0000
+++ b/gplugin-gtk/gplugin-gtk-store.c Thu May 21 07:53:56 2020 +0000
@@ -34,6 +34,9 @@
/**
* GPluginGtkStoreColumns:
+ * @GPLUGIN_GTK_STORE_ENABLED_COLUMN: The disabled column. This is used when a
+ * plugin is in a state that can't be
+ * changed. So the row should be disabled.
* @GPLUGIN_GTK_STORE_LOADED_COLUMN: The loaded column.
* @GPLUGIN_GTK_STORE_PLUGIN_COLUMN: The plugin column.
* @GPLUGIN_GTK_STORE_MARKUP_COLUMN: The markup column.
@@ -58,6 +61,7 @@
*****************************************************************************/
static const GType column_types[] = {
G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN,
G_TYPE_OBJECT,
G_TYPE_STRING,
};
@@ -75,6 +79,7 @@
GPluginPluginState state = gplugin_plugin_get_state(plugin);
GString *str = g_string_new("");
gchar *name = NULL, *summary = NULL;
+ gboolean loaded = FALSE, enabled = TRUE;
/* clang-format off */
g_object_get(
@@ -96,12 +101,20 @@
g_free(name);
g_free(summary);
+ loaded = (state == GPLUGIN_PLUGIN_STATE_LOADED);
+ if(state == GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED) {
+ loaded = TRUE;
+ enabled = FALSE;
+ }
+
gtk_list_store_append(GTK_LIST_STORE(store), &iter);
gtk_list_store_set(
GTK_LIST_STORE(store),
&iter,
GPLUGIN_GTK_STORE_LOADED_COLUMN,
- state == GPLUGIN_PLUGIN_STATE_LOADED,
+ loaded,
+ GPLUGIN_GTK_STORE_ENABLED_COLUMN,
+ enabled,
GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
g_object_ref(plugin),
GPLUGIN_GTK_STORE_MARKUP_COLUMN,
@@ -142,14 +155,22 @@
-1);
if(plugin_a == plugin_b) {
- gboolean loaded =
- gplugin_plugin_get_state(plugin_a) == GPLUGIN_PLUGIN_STATE_LOADED;
+ GPluginPluginState state = gplugin_plugin_get_state(plugin_a);
+ gboolean loaded = (state == GPLUGIN_PLUGIN_STATE_LOADED);
+ gboolean enabled = TRUE;
+
+ if(state == GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED) {
+ loaded = TRUE;
+ enabled = FALSE;
+ }
gtk_list_store_set(
GTK_LIST_STORE(model),
iter,
GPLUGIN_GTK_STORE_LOADED_COLUMN,
loaded,
+ GPLUGIN_GTK_STORE_ENABLED_COLUMN,
+ enabled,
-1);
/* tell gplugin_gtk_store_update_plugin_state that we're done */
@@ -193,6 +214,15 @@
gplugin_gtk_store_update_plugin_state(GPLUGIN_GTK_STORE(data), plugin);
}
+static void
+gplugin_gtk_store_plugin_unload_failed_cb(
+ G_GNUC_UNUSED GObject *manager,
+ GPluginPlugin *plugin,
+ gpointer data)
+{
+ gplugin_gtk_store_update_plugin_state(GPLUGIN_GTK_STORE(data), plugin);
+}
+
/******************************************************************************
* GObject Implementation
*****************************************************************************/
@@ -222,6 +252,11 @@
"unloaded-plugin",
G_CALLBACK(gplugin_gtk_store_plugin_unloaded_cb),
obj);
+ g_signal_connect(
+ manager,
+ "unload-plugin-failed",
+ G_CALLBACK(gplugin_gtk_store_plugin_unload_failed_cb),
+ obj);
}
static void
--- a/gplugin-gtk/gplugin-gtk-store.h Tue May 12 05:21:57 2020 +0000
+++ b/gplugin-gtk/gplugin-gtk-store.h Thu May 21 07:53:56 2020 +0000
@@ -39,6 +39,7 @@
GtkListStore)
typedef enum {
+ GPLUGIN_GTK_STORE_ENABLED_COLUMN,
GPLUGIN_GTK_STORE_LOADED_COLUMN,
GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
GPLUGIN_GTK_STORE_MARKUP_COLUMN,
--- a/gplugin-gtk/gplugin-gtk-view.c Tue May 12 05:21:57 2020 +0000
+++ b/gplugin-gtk/gplugin-gtk-view.c Thu May 21 07:53:56 2020 +0000
@@ -199,11 +199,14 @@
view);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
- gtk_tree_view_column_add_attribute(
+ gtk_tree_view_column_set_attributes(
col,
rend,
"active",
- GPLUGIN_GTK_STORE_LOADED_COLUMN);
+ GPLUGIN_GTK_STORE_LOADED_COLUMN,
+ "sensitive",
+ GPLUGIN_GTK_STORE_ENABLED_COLUMN,
+ NULL);
/* create the markup column */
col = gtk_tree_view_column_new();
@@ -214,11 +217,14 @@
gtk_tree_view_column_pack_start(col, rend, TRUE);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
- gtk_tree_view_column_add_attribute(
+ gtk_tree_view_column_set_attributes(
col,
rend,
"markup",
- GPLUGIN_GTK_STORE_MARKUP_COLUMN);
+ GPLUGIN_GTK_STORE_MARKUP_COLUMN,
+ "sensitive",
+ GPLUGIN_GTK_STORE_ENABLED_COLUMN,
+ NULL);
}
static void
--- a/gplugin/gplugin-loader-tests.c Tue May 12 05:21:57 2020 +0000
+++ b/gplugin/gplugin-loader-tests.c Thu May 21 07:53:56 2020 +0000
@@ -112,13 +112,18 @@
g_assert_false(ret);
g_assert_error(error, GPLUGIN_DOMAIN, 0);
- g_error_free(error);
+ g_clear_error(&error);
g_assert_cmpint(
gplugin_plugin_get_state(plugin),
==,
GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
+ /* make sure that the plugin's error was set */
+ error = gplugin_plugin_get_error(plugin);
+ g_assert_error(error, GPLUGIN_DOMAIN, 0);
+ g_clear_error(&error);
+
g_object_unref(G_OBJECT(plugin));
}
@@ -139,13 +144,18 @@
g_assert_false(ret);
g_assert_error(error, GPLUGIN_DOMAIN, 0);
- g_error_free(error);
+ g_clear_error(&error);
g_assert_cmpint(
gplugin_plugin_get_state(plugin),
==,
GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
+ /* make sure that the plugin's error was set */
+ error = gplugin_plugin_get_error(plugin);
+ g_assert_error(error, GPLUGIN_DOMAIN, 0);
+ g_clear_error(&error);
+
g_object_unref(G_OBJECT(plugin));
}
@@ -174,13 +184,18 @@
g_assert_false(ret);
g_assert_error(error, GPLUGIN_DOMAIN, 0);
- g_error_free(error);
+ g_clear_error(&error);
g_assert_cmpint(
gplugin_plugin_get_state(plugin),
==,
GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED);
+ /* make sure that the plugin's error was set */
+ error = gplugin_plugin_get_error(plugin);
+ g_assert_error(error, GPLUGIN_DOMAIN, 0);
+ g_clear_error(&error);
+
g_object_unref(G_OBJECT(plugin));
}
--- a/gplugin/gplugin-manager.c Tue May 12 05:21:57 2020 +0000
+++ b/gplugin/gplugin-manager.c Thu May 21 07:53:56 2020 +0000
@@ -125,16 +125,13 @@
GPluginPlugin *plugin,
GError **error);
void (*loaded_plugin)(GObject *manager, GPluginPlugin *plugin);
- void (*load_failed)(GObject *manager, GPluginPlugin *plugin, GError *error);
+ void (*load_failed)(GObject *manager, GPluginPlugin *plugin);
gboolean (*unloading_plugin)(
GObject *manager,
GPluginPlugin *plugin,
GError **error);
void (*unloaded_plugin)(GObject *manager, GPluginPlugin *plugin);
- void (*unload_plugin_failed)(
- GObject *manager,
- GPluginPlugin *plugin,
- GError *error);
+ void (*unload_plugin_failed)(GObject *manager, GPluginPlugin *plugin);
} GPluginManagerClass;
#define GPLUGIN_TYPE_MANAGER (gplugin_manager_get_type())
@@ -961,6 +958,9 @@
g_signal_emit(manager, signals[SIG_LOADING], 0, plugin, &error, &ret);
if(!ret) {
+ /* Set the plugin's error. */
+ g_object_set(G_OBJECT(plugin), "error", error, NULL);
+
g_propagate_error(ret_error, error);
gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
@@ -970,16 +970,28 @@
ret = gplugin_loader_load_plugin(loader, plugin, &error);
if(ret) {
+ /* If the plugin successfully loaded but returned an error, ignore the
+ * error.
+ */
+ g_clear_error(&error);
+
+ /* Likewise, make sure the plugin's error is set to NULL. */
+ g_object_set(G_OBJECT(plugin), "error", NULL, NULL);
+
gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOADED);
g_signal_emit(manager, signals[SIG_LOADED], 0, plugin);
-
- /* just in case a plugin returns TRUE with and error message, free the
- * error message.
+ } else {
+ /* Set the error on the plugin as well. This has to be before we
+ * propagate the error, because error is invalidate at that point.
*/
- g_clear_error(&error);
- } else {
+ g_object_set(G_OBJECT(plugin), "error", error, NULL);
+
+ /* Set the state after the error is set, because people might connect
+ * to the notify signal on the state property.
+ */
gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
- g_signal_emit(manager, signals[SIG_LOAD_FAILED], 0, plugin, error);
+
+ g_signal_emit(manager, signals[SIG_LOAD_FAILED], 0, plugin);
g_propagate_error(ret_error, error);
}
@@ -1015,6 +1027,9 @@
g_signal_emit(manager, signals[SIG_UNLOADING], 0, plugin, &error, &ret);
if(!ret) {
+ /* Set the plugin's error. */
+ g_object_set(G_OBJECT(plugin), "error", error, NULL);
+
g_propagate_error(ret_error, error);
return ret;
@@ -1022,16 +1037,28 @@
ret = gplugin_loader_unload_plugin(loader, plugin, &error);
if(ret) {
- gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_QUERIED);
- g_signal_emit(manager, signals[SIG_UNLOADED], 0, plugin);
-
- /* if the plugin successfully loaded but returned an error, ignore the
+ /* If the plugin successfully loaded but returned an error, ignore the
* error.
*/
g_clear_error(&error);
+
+ /* Like, make sure the plugin's error is set to NULL. */
+ g_object_set(G_OBJECT(plugin), "error", NULL, NULL);
+
+ gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_QUERIED);
+ g_signal_emit(manager, signals[SIG_UNLOADED], 0, plugin);
} else {
+ /* Set the error on the plugin as well. This has to be before we
+ * propagate the error, because error is invalidate at that point.
+ */
+ g_object_set(G_OBJECT(plugin), "error", error, NULL);
+
+ /* Set the state after the error is set, because people might connect
+ * to the notify signal on the state property.
+ */
gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED);
- g_signal_emit(manager, signals[SIG_UNLOAD_FAILED], 0, plugin, error);
+
+ g_signal_emit(manager, signals[SIG_UNLOAD_FAILED], 0, plugin);
g_propagate_error(ret_error, error);
}
@@ -1194,9 +1221,8 @@
NULL,
NULL,
G_TYPE_NONE,
- 2,
- G_TYPE_OBJECT,
- G_TYPE_ERROR);
+ 1,
+ G_TYPE_OBJECT);
/**
* GPluginManager::unloading-plugin:
@@ -1257,9 +1283,8 @@
NULL,
NULL,
G_TYPE_NONE,
- 2,
- G_TYPE_OBJECT,
- G_TYPE_ERROR);
+ 1,
+ G_TYPE_OBJECT);
}
static void
--- a/gplugin/gplugin-manager.h Tue May 12 05:21:57 2020 +0000
+++ b/gplugin/gplugin-manager.h Thu May 21 07:53:56 2020 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
--- a/gplugin/gplugin-native-plugin.c Tue May 12 05:21:57 2020 +0000
+++ b/gplugin/gplugin-native-plugin.c Thu May 21 07:53:56 2020 +0000
@@ -51,6 +51,7 @@
GPluginLoader *loader;
GPluginPluginInfo *info;
GPluginPluginState state;
+ GError *error;
};
/******************************************************************************
@@ -66,7 +67,8 @@
PROP_FILENAME = N_PROPERTIES,
PROP_LOADER,
PROP_INFO,
- PROP_STATE
+ PROP_STATE,
+ PROP_ERROR,
};
static GParamSpec *properties[N_PROPERTIES] = {
NULL,
@@ -141,6 +143,10 @@
case PROP_STATE:
g_value_set_enum(value, plugin->state);
break;
+ case PROP_ERROR:
+ g_value_set_boxed(value, plugin->error);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
break;
@@ -180,6 +186,9 @@
case PROP_STATE:
plugin->state = g_value_get_enum(value);
break;
+ case PROP_ERROR:
+ plugin->error = g_value_dup_boxed(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -195,6 +204,7 @@
g_clear_pointer(&plugin->filename, g_free);
g_clear_object(&plugin->loader);
g_clear_object(&plugin->info);
+ g_clear_error(&plugin->error);
g_module_close(plugin->module);
@@ -259,6 +269,7 @@
g_object_class_override_property(obj_class, PROP_LOADER, "loader");
g_object_class_override_property(obj_class, PROP_INFO, "info");
g_object_class_override_property(obj_class, PROP_STATE, "state");
+ g_object_class_override_property(obj_class, PROP_ERROR, "error");
}
/******************************************************************************
--- a/gplugin/gplugin-plugin.c Tue May 12 05:21:57 2020 +0000
+++ b/gplugin/gplugin-plugin.c Thu May 21 07:53:56 2020 +0000
@@ -139,6 +139,19 @@
g_object_interface_install_property(iface, pspec);
/**
+ * GPluginPlugin:error:
+ *
+ * A #GError returned the plugin if it failed to load or unload.
+ */
+ pspec = g_param_spec_boxed(
+ "error",
+ "error",
+ "A GError returned from the load or unload function",
+ G_TYPE_ERROR,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_interface_install_property(iface, pspec);
+
+ /**
* GPluginPlugin::state-changed:
* @plugin: The #GPluginPlugin that changed states.
* @oldstate: The old #GPluginPluginState.
@@ -267,3 +280,24 @@
g_signal_emit(plugin, signals[SIG_STATE_CHANGED], 0, oldstate, state);
}
+
+/**
+ * gplugin_plugin_get_error:
+ * @plugin: The #GPluginPlugin instance.
+ *
+ * Gets the #GError, if any, that the plugin returned during load or unload.
+ *
+ * Returns: (transfer full): The #GError the plugin returned during load or
+ * unload, or %NULL if no error occurred.
+ */
+GError *
+gplugin_plugin_get_error(GPluginPlugin *plugin)
+{
+ GError *error = NULL;
+
+ g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
+
+ g_object_get(G_OBJECT(plugin), "error", &error, NULL);
+
+ return error;
+}
--- a/gplugin/gplugin-plugin.h Tue May 12 05:21:57 2020 +0000
+++ b/gplugin/gplugin-plugin.h Thu May 21 07:53:56 2020 +0000
@@ -70,6 +70,8 @@
GPluginPluginState gplugin_plugin_get_state(GPluginPlugin *plugin);
void gplugin_plugin_set_state(GPluginPlugin *plugin, GPluginPluginState state);
+GError *gplugin_plugin_get_error(GPluginPlugin *plugin);
+
G_END_DECLS
#endif /* GPLUGIN_PLUGIN_H */
--- a/gplugin/tests/test-signals.c Tue May 12 05:21:57 2020 +0000
+++ b/gplugin/tests/test-signals.c Thu May 21 07:53:56 2020 +0000
@@ -117,7 +117,6 @@
test_gplugin_manager_signals_load_failed(
G_GNUC_UNUSED GObject *manager,
G_GNUC_UNUSED GPluginPlugin *plugin,
- G_GNUC_UNUSED GError *error,
gpointer d)
{
TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
@@ -129,7 +128,6 @@
test_gplugin_manager_signals_unload_failed(
G_GNUC_UNUSED GObject *manager,
G_GNUC_UNUSED GPluginPlugin *plugin,
- G_GNUC_UNUSED GError *error,
gpointer d)
{
TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
--- a/lua/gplugin-lua-plugin.c Tue May 12 05:21:57 2020 +0000
+++ b/lua/gplugin-lua-plugin.c Thu May 21 07:53:56 2020 +0000
@@ -31,6 +31,7 @@
GPluginLoader *loader;
GPluginPluginInfo *info;
GPluginPluginState state;
+ GError *error;
};
/******************************************************************************
@@ -44,7 +45,8 @@
PROP_FILENAME = N_PROPERTIES,
PROP_LOADER,
PROP_INFO,
- PROP_STATE
+ PROP_STATE,
+ PROP_ERROR,
};
static GParamSpec *properties[N_PROPERTIES] = {
NULL,
@@ -98,6 +100,9 @@
case PROP_STATE:
g_value_set_enum(value, plugin->state);
break;
+ case PROP_ERROR:
+ g_value_set_boxed(value, plugin->error);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -132,6 +137,9 @@
case PROP_STATE:
plugin->state = g_value_get_enum(value);
break;
+ case PROP_ERROR:
+ plugin->error = g_value_dup_boxed(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -148,6 +156,7 @@
g_clear_pointer(&plugin->filename, g_free);
g_clear_object(&plugin->loader);
g_clear_object(&plugin->info);
+ g_clear_error(&plugin->error);
G_OBJECT_CLASS(gplugin_lua_plugin_parent_class)->finalize(obj);
}
@@ -184,6 +193,7 @@
g_object_class_override_property(obj_class, PROP_LOADER, "loader");
g_object_class_override_property(obj_class, PROP_INFO, "info");
g_object_class_override_property(obj_class, PROP_STATE, "state");
+ g_object_class_override_property(obj_class, PROP_ERROR, "error");
}
/******************************************************************************
--- a/perl/gplugin-perl-plugin.c Tue May 12 05:21:57 2020 +0000
+++ b/perl/gplugin-perl-plugin.c Thu May 21 07:53:56 2020 +0000
@@ -30,6 +30,7 @@
GPluginLoader *loader;
GPluginPluginInfo *info;
GPluginPluginState state;
+ GError *error;
};
/******************************************************************************
@@ -43,7 +44,8 @@
PROP_FILENAME = N_PROPERTIES,
PROP_LOADER,
PROP_INFO,
- PROP_STATE
+ PROP_STATE,
+ PROP_ERROR,
};
static GParamSpec *properties[N_PROPERTIES] = {
NULL,
@@ -99,6 +101,9 @@
case PROP_STATE:
g_value_set_enum(value, plugin->state);
break;
+ case PROP_ERROR:
+ g_value_set_boxed(value, plugin->error);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -133,6 +138,9 @@
case PROP_STATE:
plugin->state = g_value_get_enum(value);
break;
+ case PROP_ERROR:
+ plugin->error = g_value_dup_boxed(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -151,6 +159,7 @@
g_clear_pointer(&plugin->filename, g_free);
g_clear_object(&plugin->loader);
g_clear_object(&plugin->info);
+ g_clear_error(&plugin->error);
G_OBJECT_CLASS(gplugin_perl_plugin_parent_class)->finalize(obj);
}
@@ -187,6 +196,7 @@
g_object_class_override_property(obj_class, PROP_LOADER, "loader");
g_object_class_override_property(obj_class, PROP_INFO, "info");
g_object_class_override_property(obj_class, PROP_STATE, "state");
+ g_object_class_override_property(obj_class, PROP_ERROR, "error");
}
/******************************************************************************
--- a/python/gplugin-python3-plugin.c Tue May 12 05:21:57 2020 +0000
+++ b/python/gplugin-python3-plugin.c Thu May 21 07:53:56 2020 +0000
@@ -35,6 +35,7 @@
GPluginLoader *loader;
GPluginPluginInfo *info;
GPluginPluginState state;
+ GError *error;
};
/******************************************************************************
@@ -50,7 +51,8 @@
PROP_FILENAME = N_PROPERTIES,
PROP_LOADER,
PROP_INFO,
- PROP_STATE
+ PROP_STATE,
+ PROP_ERROR,
};
static GParamSpec *properties[N_PROPERTIES] = {
NULL,
@@ -174,6 +176,9 @@
case PROP_STATE:
g_value_set_enum(value, plugin->state);
break;
+ case PROP_ERROR:
+ g_value_set_boxed(value, plugin->error);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -220,6 +225,9 @@
case PROP_STATE:
plugin->state = g_value_get_enum(value);
break;
+ case PROP_ERROR:
+ plugin->error = g_value_dup_boxed(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -239,6 +247,7 @@
g_clear_pointer(&plugin->filename, g_free);
g_clear_object(&plugin->loader);
g_clear_object(&plugin->info);
+ g_clear_error(&plugin->error);
G_OBJECT_CLASS(gplugin_python3_plugin_parent_class)->finalize(obj);
}
@@ -288,6 +297,7 @@
g_object_class_override_property(obj_class, PROP_LOADER, "loader");
g_object_class_override_property(obj_class, PROP_INFO, "info");
g_object_class_override_property(obj_class, PROP_STATE, "state");
+ g_object_class_override_property(obj_class, PROP_ERROR, "error");
}
/******************************************************************************