[Xfce4-commits] [apps/xfdashboard] 01/01: Implement file monitor to Gnome-Shell search provider plugin to get notified about new, modified or removed providers during run-time.

noreply at xfce.org noreply at xfce.org
Sat Feb 13 09:19:23 CET 2016


This is an automated email from the git hooks/post-receive script.

nomad pushed a commit to branch master
in repository apps/xfdashboard.

commit 5ecd8226869bba767401f757da33cf28edc6a9ef
Author: Stephan Haller <nomad at froevel.de>
Date:   Sat Feb 13 09:18:37 2016 +0100

    Implement file monitor to Gnome-Shell search provider plugin to get notified about new, modified or removed providers during run-time.
---
 .../gnome-shell-search-provider.c                  | 401 ++++++++++++++-------
 plugins/gnome-shell-search-provider/plugin.c       | 280 ++++++++++++--
 2 files changed, 517 insertions(+), 164 deletions(-)

diff --git a/plugins/gnome-shell-search-provider/gnome-shell-search-provider.c b/plugins/gnome-shell-search-provider/gnome-shell-search-provider.c
index ec0a303..f8c9dd6 100644
--- a/plugins/gnome-shell-search-provider/gnome-shell-search-provider.c
+++ b/plugins/gnome-shell-search-provider/gnome-shell-search-provider.c
@@ -33,6 +33,7 @@
 #include "application-database.h"
 #include "button.h"
 
+
 /* Define this class in GObject system */
 G_DEFINE_DYNAMIC_TYPE(XfdashboardGnomeShellSearchProvider,
 						xfdashboard_gnome_shell_search_provider,
@@ -49,8 +50,8 @@ struct _XfdashboardGnomeShellSearchProviderPrivate
 {
 	/* Instance related */
 	gchar			*gnomeShellID;
-	gchar			*filename;
-	gchar			*fileFullPath;
+	GFile			*file;
+	GFileMonitor	*fileMonitor;
 
 	gchar			*desktopID;
 	gchar			*dbusBusName;
@@ -67,200 +68,348 @@ struct _XfdashboardGnomeShellSearchProviderPrivate
 
 /* IMPLEMENTATION: XfdashboardSearchProvider */
 
-/* One-time initialization of search provider */
-static void _xfdashboard_gnome_shell_search_provider_initialize(XfdashboardSearchProvider *inProvider)
+/* Update information about Gnome-Shell search provider from file */
+static gboolean _xfdashboard_gnome_shell_search_provider_update_from_file(XfdashboardGnomeShellSearchProvider *self,
+																			GError **outError)
 {
-	XfdashboardGnomeShellSearchProvider				*self;
 	XfdashboardGnomeShellSearchProviderPrivate		*priv;
-	GError											*error;
+	gchar											*filePath;
 	GKeyFile										*providerKeyFile;
 	XfdashboardApplicationDatabase					*appDB;
 	GAppInfo										*appInfo;
+	gchar											*desktopID;
+	gchar											*dbusBusName;
+	gchar											*dbusObjectPath;
+	gint											searchProviderVersion;
+	gchar											*providerName;
+	gchar											*providerIcon;
+	GError											*error;
 
-	g_return_if_fail(XFDASHBOARD_IS_GNOME_SHELL_SEARCH_PROVIDER(inProvider));
+	g_return_val_if_fail(XFDASHBOARD_IS_GNOME_SHELL_SEARCH_PROVIDER(self), FALSE);
+	g_return_val_if_fail(outError==NULL || *outError==NULL, FALSE);
 
-	self=XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER(inProvider);
 	priv=self->priv;
 	error=NULL;
 
-	/* Get ID of Gnome-Shell search provider */
-	if(!priv->gnomeShellID)
-	{
-		const gchar									*providerID;
-
-		providerID=xfdashboard_search_provider_get_id(inProvider);
-		priv->gnomeShellID=g_strdup(providerID+strlen(XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_PREFIX)+1);
-	}
-	g_debug("Initializing search provider '%s' of type %s for Gnome-Shell search provider ID '%s'",
-				xfdashboard_search_provider_get_id(inProvider),
-				G_OBJECT_TYPE_NAME(self),
-				priv->gnomeShellID);
-
-	/* Get file basename of Gnome-Shell search provider's data file */
-	if(!priv->filename) priv->filename=g_strdup_printf("%s.ini", priv->gnomeShellID);
-
-	/* Get full path of Gnome-Shell search provider's data file */
-	if(!priv->fileFullPath) priv->fileFullPath=g_build_filename(GNOME_SHELL_PROVIDERS_PATH, priv->filename, NULL);
-	g_debug("Initializing search provider '%s' of type %s from data file at %s (path=%s and basename=%s)",
-				xfdashboard_search_provider_get_id(inProvider),
-				G_OBJECT_TYPE_NAME(self),
-				priv->fileFullPath,
-				GNOME_SHELL_PROVIDERS_PATH,
-				priv->filename);
+	/* Get path to Gnome-Shell search provider's data file */
+	filePath=g_file_get_path(priv->file);
 
 	/* Get data about search provider */
 	providerKeyFile=g_key_file_new();
 	if(!g_key_file_load_from_file(providerKeyFile,
-									priv->fileFullPath,
+									filePath,
 									G_KEY_FILE_NONE,
 									&error))
 	{
-		/* Show error message */
-		g_warning(_("Cannot load information from '%s' for gnome-shell search provider '%s': %s"),
-					priv->fileFullPath,
-					priv->gnomeShellID,
-					(error && error->message) ? error->message : _("Unknown error"));
+		/* Propagate error */
+		g_propagate_error(outError, error);
 
 		/* Release allocated resources */
-		if(error) g_error_free(error);
 		if(providerKeyFile) g_key_file_free(providerKeyFile);
+		if(filePath) g_free(filePath);
 
-		return;
+		return(FALSE);
 	}
 
 	/* Get desktop ID from search provider's data file */
-	priv->desktopID=g_key_file_get_string(providerKeyFile,
-											XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_KEYFILE_GROUP,
-											"DesktopId",
-											&error);
-	if(!priv->desktopID)
+	desktopID=g_key_file_get_string(providerKeyFile,
+									XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_KEYFILE_GROUP,
+									"DesktopId",
+									&error);
+	if(!desktopID)
 	{
-		/* Show error message */
-		g_warning(_("Incomplete information at '%s' for gnome-shell search provider '%s': %s"),
-					priv->fileFullPath,
-					priv->gnomeShellID,
-					(error && error->message) ? error->message : _("Unknown error"));
+		/* Propagate error */
+		g_propagate_error(outError, error);
 
 		/* Release allocated resources */
-		if(error) g_error_free(error);
 		if(providerKeyFile) g_key_file_free(providerKeyFile);
+		if(filePath) g_free(filePath);
 
-		return;
+		return(FALSE);
 	}
 
 	/* Get bus name from search provider's data file */
-	priv->dbusBusName=g_key_file_get_string(providerKeyFile,
-											XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_KEYFILE_GROUP,
-											"BusName",
-											&error);
-	if(!priv->dbusBusName)
+	dbusBusName=g_key_file_get_string(providerKeyFile,
+										XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_KEYFILE_GROUP,
+										"BusName",
+										&error);
+	if(!dbusBusName)
 	{
-		/* Show error message */
-		g_warning(_("Incomplete information at '%s' for gnome-shell search provider '%s': %s"),
-					priv->fileFullPath,
-					priv->gnomeShellID,
-					(error && error->message) ? error->message : _("Unknown error"));
+		/* Propagate error */
+		g_propagate_error(outError, error);
 
 		/* Release allocated resources */
-		if(error) g_error_free(error);
+		if(desktopID) g_free(desktopID);
 		if(providerKeyFile) g_key_file_free(providerKeyFile);
+		if(filePath) g_free(filePath);
 
-		return;
+		return(FALSE);
 	}
 
 	/* Get object path from search provider's data file */
-	priv->dbusObjectPath=g_key_file_get_string(providerKeyFile,
-												XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_KEYFILE_GROUP,
-												"ObjectPath",
-												&error);
-	if(!priv->dbusObjectPath)
+	dbusObjectPath=g_key_file_get_string(providerKeyFile,
+											XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_KEYFILE_GROUP,
+											"ObjectPath",
+											&error);
+	if(!dbusObjectPath)
 	{
-		/* Show error message */
-		g_warning(_("Incomplete information at '%s' for gnome-shell search provider '%s': %s"),
-					priv->fileFullPath,
-					priv->gnomeShellID,
-					(error && error->message) ? error->message : _("Unknown error"));
+		/* Propagate error */
+		g_propagate_error(outError, error);
 
 		/* Release allocated resources */
-		if(error) g_error_free(error);
+		if(dbusBusName) g_free(dbusBusName);
+		if(desktopID) g_free(desktopID);
 		if(providerKeyFile) g_key_file_free(providerKeyFile);
+		if(filePath) g_free(filePath);
 
-		return;
+		return(FALSE);
 	}
 
 	/* Get version from search provider's data file */
-	priv->searchProviderVersion=g_key_file_get_integer(providerKeyFile,
-														XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_KEYFILE_GROUP,
-														"Version",
-														&error);
-	if(!priv->searchProviderVersion)
+	searchProviderVersion=g_key_file_get_integer(providerKeyFile,
+													XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_KEYFILE_GROUP,
+													"Version",
+													&error);
+	if(!searchProviderVersion)
 	{
-		/* Show error message */
-		g_warning(_("Incomplete information at '%s' for gnome-shell search provider '%s': %s"),
-					priv->fileFullPath,
-					priv->gnomeShellID,
-					(error && error->message) ? error->message : _("Unknown error"));
+		/* Propagate error */
+		g_propagate_error(outError, error);
 
 		/* Release allocated resources */
-		if(error) g_error_free(error);
+		if(dbusObjectPath) g_free(dbusObjectPath);
+		if(dbusBusName) g_free(dbusBusName);
+		if(desktopID) g_free(desktopID);
 		if(providerKeyFile) g_key_file_free(providerKeyFile);
+		if(filePath) g_free(filePath);
 
-		return;
+		return(FALSE);
 	}
 
 	/* Get display name and icon from desktop file returned from application
 	 * database by lookup of desktop ID.
 	 */
+	providerName=NULL;
+	providerIcon=NULL;
+
 	appDB=xfdashboard_application_database_get_default();
 
-	appInfo=xfdashboard_application_database_lookup_desktop_id(appDB, priv->desktopID);
+	appInfo=xfdashboard_application_database_lookup_desktop_id(appDB, desktopID);
 	if(appInfo)
 	{
-		GIcon										*providerIcon;
+		GIcon										*appIcon;
 
 		/* Get name */
-		priv->providerName=g_strdup(g_app_info_get_display_name(appInfo));
+		providerName=g_strdup(g_app_info_get_display_name(appInfo));
 
 		/* Get icon */
-		providerIcon=g_app_info_get_icon(appInfo);
-		if(providerIcon)
+		appIcon=g_app_info_get_icon(appInfo);
+		if(appIcon)
 		{
-			priv->providerIcon=g_icon_to_string(providerIcon);
-			g_object_unref(providerIcon);
+			providerIcon=g_icon_to_string(appIcon);
+			g_object_unref(appIcon);
 		}
 	}
 		else
 		{
 			/* Show error message */
-			g_warning(_("Unknown application '%s' for gnome-shell search provider '%s'"),
-						priv->desktopID,
+			g_warning(_("Unknown application '%s' for Gnome-Shell search provider '%s'"),
+						desktopID,
 						priv->gnomeShellID);
 		}
 
-	/* Set default values for display name and icon where the data could
-	 * not be retrieved from desktop file.
+	/* We got all data from search provider's data file so update now.
+	 * Set default values where appropiate (display name and icon).
 	 */
-	if(!priv->providerIcon) priv->providerIcon=g_strdup("image-missing");
-	if(!priv->providerName) priv->providerName=g_strdup(priv->gnomeShellID);
+	if(priv->desktopID) g_free(priv->desktopID);
+	priv->desktopID=g_strdup(desktopID);
+
+	if(priv->dbusBusName) g_free(priv->dbusBusName);
+	priv->dbusBusName=g_strdup(dbusBusName);
+
+	if(priv->dbusObjectPath) g_free(priv->dbusObjectPath);
+	priv->dbusObjectPath=g_strdup(dbusObjectPath);
+
+	priv->searchProviderVersion=searchProviderVersion;
+
+	if(priv->providerName) g_free(priv->providerName);
+	if(providerName) priv->providerName=g_strdup(providerName);
+		else priv->providerName=g_strdup(priv->gnomeShellID);
+
+	if(priv->providerIcon) g_free(priv->providerIcon);
+	if(providerIcon) priv->providerIcon=g_strdup(providerIcon);
+		else priv->providerIcon=g_strdup("image-missing");
 
 	/* Release allocated resources */
 	if(appInfo) g_object_unref(appInfo);
 	if(appDB) g_object_unref(appDB);
+	if(providerIcon) g_free(providerIcon);
+	if(providerName) g_free(providerName);
+	if(dbusObjectPath) g_free(dbusObjectPath);
+	if(dbusBusName) g_free(dbusBusName);
+	if(desktopID) g_free(desktopID);
 	if(providerKeyFile) g_key_file_free(providerKeyFile);
+	if(filePath) g_free(filePath);
 
-	g_debug("Initialized search provider '%s' of type %s for GnomeShell search provider interface version %d using DBUS name '%s' and object path '%s'",
-				xfdashboard_search_provider_get_id(inProvider),
+	/* If we get here we could update from file successfully */
+	g_debug("Updated search provider '%s' of type %s for Gnome-Shell search provider interface version %d using DBUS name '%s' and object path '%s' displayed as '%s' with icon '%s' from desktop ID '%s'",
+				xfdashboard_search_provider_get_id(XFDASHBOARD_SEARCH_PROVIDER(self)),
 				G_OBJECT_TYPE_NAME(self),
 				priv->searchProviderVersion,
 				priv->dbusBusName,
-				priv->dbusObjectPath);
-
-	g_debug("Initialized search provider '%s' of type %s displayed as '%s' with icon '%s' from desktop ID '%s'",
-				xfdashboard_search_provider_get_id(inProvider),
-				G_OBJECT_TYPE_NAME(self),
+				priv->dbusObjectPath,
 				priv->providerName,
 				priv->providerIcon,
 				priv->desktopID);
+
+	return(TRUE);
+}
+
+/* The data file of Gnome-Shell search provider has changed */
+static void _xfdashboard_gnome_shell_search_provider_on_data_file_changed(XfdashboardGnomeShellSearchProvider *self,
+																			GFile *inFile,
+																			GFile *inOtherFile,
+																			GFileMonitorEvent inEventType,
+																			gpointer inUserData)
+{
+	XfdashboardGnomeShellSearchProviderPrivate		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_GNOME_SHELL_SEARCH_PROVIDER(self));
+	g_return_if_fail(G_IS_FILE_MONITOR(inUserData));
+
+	priv=self->priv;
+
+	/* Check if a search provider was added */
+	if(inEventType==G_FILE_MONITOR_EVENT_CHANGED &&
+		g_file_equal(inFile, priv->file))
+	{
+		GError										*error;
+
+		error=NULL;
+
+		/* Update information about Gnome-Shell search provider from modified data file */
+		if(!_xfdashboard_gnome_shell_search_provider_update_from_file(self, &error))
+		{
+			/* Show warning message */
+			g_warning(_("Cannot update information about Gnome-Shell search provider '%s': %s"),
+						priv->gnomeShellID,
+						(error && error->message) ? error->message : _("Unknown error"));
+
+			/* Release allocated resources */
+			if(error)
+			{
+				g_error_free(error);
+				error=NULL;
+			}
+		}
+			else
+			{
+				g_debug("Updated Gnome-Shell search provider '%s' of type %s with ID '%s' from modified data file successfully",
+							priv->gnomeShellID,
+							G_OBJECT_TYPE_NAME(self),
+							xfdashboard_search_provider_get_id(XFDASHBOARD_SEARCH_PROVIDER(self)));
+			}
+	}
+}
+
+/* One-time initialization of search provider */
+static void _xfdashboard_gnome_shell_search_provider_initialize(XfdashboardSearchProvider *inProvider)
+{
+	XfdashboardGnomeShellSearchProvider				*self;
+	XfdashboardGnomeShellSearchProviderPrivate		*priv;
+	GError											*error;
+
+	g_return_if_fail(XFDASHBOARD_IS_GNOME_SHELL_SEARCH_PROVIDER(inProvider));
+
+	self=XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER(inProvider);
+	priv=self->priv;
+	error=NULL;
+
+	/* Get ID of Gnome-Shell search provider */
+	if(!priv->gnomeShellID)
+	{
+		const gchar									*providerID;
+
+		providerID=xfdashboard_search_provider_get_id(inProvider);
+		priv->gnomeShellID=g_strdup(providerID+strlen(XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_PREFIX)+1);
+	}
+	g_debug("Initializing search provider '%s' of type %s for Gnome-Shell search provider ID '%s'",
+				xfdashboard_search_provider_get_id(inProvider),
+				G_OBJECT_TYPE_NAME(self),
+				priv->gnomeShellID);
+
+	/* Get Gnome-Shell search provider's data file */
+	if(!priv->file)
+	{
+		gchar										*filename;
+		gchar										*filePath;
+
+		/* Get path to Gnome-Shell search provider's data file */
+		filename=g_strdup_printf("%s.ini", priv->gnomeShellID);
+		filePath=g_build_filename(GNOME_SHELL_PROVIDERS_PATH, filename, NULL);
+
+		/* Get Gnome-Shell search provider's data file */
+		priv->file=g_file_new_for_path(filePath);
+
+		/* Release allocated resources */
+		g_free(filename);
+		g_free(filePath);
+	}
+
+	/* Get file monitor to detect changes at Gnome-Shell search provider's data file.
+	 * It is not fatal if file monitor could not be initialized because we just do not
+	 * get notified about any changes to the data file. But print a warning.
+	 */
+	if(!priv->fileMonitor)
+	{
+		priv->fileMonitor=g_file_monitor_file(priv->file, 0, NULL, &error);
+		if(priv->fileMonitor)
+		{
+			g_debug("Created file monitor to watch for changes at Gnome-Shell search provider '%s'",
+					priv->gnomeShellID);
+
+			g_signal_connect_swapped(priv->fileMonitor,
+										"changed",
+										G_CALLBACK(_xfdashboard_gnome_shell_search_provider_on_data_file_changed),
+										self);
+		}
+			else
+			{
+				/* Show warning message */
+				g_warning(_("Cannot initialize file monitor to detect changes for Gnome-Shell search provider '%s': %s"),
+							priv->gnomeShellID,
+							(error && error->message) ? error->message : _("Unknown error"));
+
+				/* Release allocated resources */
+				if(error)
+				{
+					g_error_free(error);
+					error=NULL;
+				}
+			}
+	}
+
+	/* Get information about Gnome-Shell search provider from file */
+	if(!_xfdashboard_gnome_shell_search_provider_update_from_file(self, &error))
+	{
+		/* Show warning message */
+		g_warning(_("Cannot load information about Gnome-Shell search provider '%s': %s"),
+					priv->gnomeShellID,
+					(error && error->message) ? error->message : _("Unknown error"));
+
+		/* Release allocated resources */
+		if(error)
+		{
+			g_error_free(error);
+			error=NULL;
+		}
+	}
+		else
+		{
+			g_debug("Initialized Gnome-Shell search provider '%s' of type %s with ID '%s' successfully",
+						priv->gnomeShellID,
+						G_OBJECT_TYPE_NAME(self),
+						xfdashboard_search_provider_get_id(inProvider));
+		}
 }
 
 /* Get display name for this search provider */
@@ -325,7 +474,7 @@ static XfdashboardSearchResultSet* _xfdashboard_gnome_shell_search_provider_get_
 	if(!proxy)
 	{
 		/* Show error message */
-		g_warning(_("Could not create dbus connection for gnome-shell search provider '%s': %s"),
+		g_warning(_("Could not create dbus connection for Gnome-Shell search provider '%s': %s"),
 					priv->gnomeShellID,
 					(error && error->message) ? error->message : _("Unknown error"));
 
@@ -398,7 +547,7 @@ static XfdashboardSearchResultSet* _xfdashboard_gnome_shell_search_provider_get_
 	if(!proxyResult)
 	{
 		/* Show error message */
-		g_warning(_("Could get result set from dbus connection for gnome-shell search provider '%s': %s"),
+		g_warning(_("Could get result set from dbus connection for Gnome-Shell search provider '%s': %s"),
 					priv->gnomeShellID,
 					(error && error->message) ? error->message : _("Unknown error"));
 
@@ -488,7 +637,7 @@ static ClutterActor* _xfdashboard_gnome_shell_search_provider_create_result_acto
 	if(!proxy)
 	{
 		/* Show error message */
-		g_warning(_("Could not create dbus connection for gnome-shell search provider '%s': %s"),
+		g_warning(_("Could not create dbus connection for Gnome-Shell search provider '%s': %s"),
 					priv->gnomeShellID,
 					(error && error->message) ? error->message : _("Unknown error"));
 
@@ -511,7 +660,7 @@ static ClutterActor* _xfdashboard_gnome_shell_search_provider_create_result_acto
 	if(!proxyResult)
 	{
 		/* Show error message */
-		g_warning(_("Could get meta data for '%s' from dbus connection for gnome-shell search provider '%s': %s"),
+		g_warning(_("Could get meta data for '%s' from dbus connection for Gnome-Shell search provider '%s': %s"),
 					identifier[0],
 					priv->gnomeShellID,
 					(error && error->message) ? error->message : _("Unknown error"));
@@ -570,7 +719,7 @@ static ClutterActor* _xfdashboard_gnome_shell_search_provider_create_result_acto
 				if(!icon)
 				{
 					/* Show error message */
-					g_warning(_("Could get icon for '%s' of key '%s' for gnome-shell search provider '%s': %s"),
+					g_warning(_("Could get icon for '%s' of key '%s' for Gnome-Shell search provider '%s': %s"),
 								identifier[0],
 								"icon",
 								priv->gnomeShellID,
@@ -589,7 +738,7 @@ static ClutterActor* _xfdashboard_gnome_shell_search_provider_create_result_acto
 				if(!icon)
 				{
 					/* Show error message */
-					g_warning(_("Could get icon for '%s' of key '%s' for gnome-shell search provider '%s': %s"),
+					g_warning(_("Could get icon for '%s' of key '%s' for Gnome-Shell search provider '%s': %s"),
 								identifier[0],
 								"gicon",
 								priv->gnomeShellID,
@@ -691,7 +840,7 @@ static gboolean _xfdashboard_gnome_shell_search_provider_activate_result(Xfdashb
 	if(!proxy)
 	{
 		/* Show error message */
-		g_warning(_("Could not create dbus connection for gnome-shell search provider '%s': %s"),
+		g_warning(_("Could not create dbus connection for Gnome-Shell search provider '%s': %s"),
 					priv->gnomeShellID,
 					(error && error->message) ? error->message : _("Unknown error"));
 
@@ -715,7 +864,7 @@ static gboolean _xfdashboard_gnome_shell_search_provider_activate_result(Xfdashb
 	if(!proxyResult)
 	{
 		/* Show error message */
-		g_warning(_("Could activate result item '%s' over dbus connection for gnome-shell search provider '%s': %s"),
+		g_warning(_("Could activate result item '%s' over dbus connection for Gnome-Shell search provider '%s': %s"),
 					identifier,
 					priv->gnomeShellID,
 					(error && error->message) ? error->message : _("Unknown error"));
@@ -765,7 +914,7 @@ static gboolean _xfdashboard_gnome_shell_search_provider_launch_search(Xfdashboa
 	if(!proxy)
 	{
 		/* Show error message */
-		g_warning(_("Could not create dbus connection for gnome-shell search provider '%s': %s"),
+		g_warning(_("Could not create dbus connection for Gnome-Shell search provider '%s': %s"),
 					priv->gnomeShellID,
 					(error && error->message) ? error->message : _("Unknown error"));
 
@@ -788,7 +937,7 @@ static gboolean _xfdashboard_gnome_shell_search_provider_launch_search(Xfdashboa
 	if(!proxyResult)
 	{
 		/* Show error message */
-		g_warning(_("Could not launch search over dbus connection for gnome-shell search provider '%s': %s"),
+		g_warning(_("Could not launch search over dbus connection for Gnome-Shell search provider '%s': %s"),
 					priv->gnomeShellID,
 					(error && error->message) ? error->message : _("Unknown error"));
 
@@ -823,16 +972,16 @@ static void _xfdashboard_gnome_shell_search_provider_dispose(GObject *inObject)
 		priv->gnomeShellID=NULL;
 	}
 
-	if(priv->filename)
+	if(priv->file)
 	{
-		g_free(priv->filename);
-		priv->filename=NULL;
+		g_object_unref(priv->file);
+		priv->file=NULL;
 	}
 
-	if(priv->fileFullPath)
+	if(priv->fileMonitor)
 	{
-		g_free(priv->fileFullPath);
-		priv->fileFullPath=NULL;
+		g_object_unref(priv->fileMonitor);
+		priv->fileMonitor=NULL;
 	}
 
 	if(priv->desktopID)
@@ -909,8 +1058,8 @@ void xfdashboard_gnome_shell_search_provider_init(XfdashboardGnomeShellSearchPro
 
 	/* Set up default values */
 	priv->gnomeShellID=NULL;
-	priv->filename=NULL;
-	priv->fileFullPath=NULL;
+	priv->file=NULL;
+	priv->fileMonitor=NULL;
 	priv->desktopID=NULL;
 	priv->dbusBusName=NULL;
 	priv->dbusObjectPath=NULL;
diff --git a/plugins/gnome-shell-search-provider/plugin.c b/plugins/gnome-shell-search-provider/plugin.c
index 77f81a0..f8ac0c9 100644
--- a/plugins/gnome-shell-search-provider/plugin.c
+++ b/plugins/gnome-shell-search-provider/plugin.c
@@ -34,7 +34,13 @@
 
 
 /* IMPLEMENTATION: Private variables and methods */
-static GList		*xfdashboard_gnome_shell_search_provider_registered_providers=NULL;
+typedef struct _XfdashboardGnomeShellSearchProviderPluginPrivate	XfdashboardGnomeShellSearchProviderPluginPrivate;
+struct _XfdashboardGnomeShellSearchProviderPluginPrivate
+{
+	/* Private structure */
+	GList			*providers;
+	GFileMonitor	*fileMonitor;
+};
 
 
 /* IMPLEMENTATION: XfdashboardPlugin */
@@ -42,16 +48,160 @@ static GList		*xfdashboard_gnome_shell_search_provider_registered_providers=NULL
 /* Forward declarations */
 G_MODULE_EXPORT void plugin_init(XfdashboardPlugin *self);
 
+/* Get provider name (ID) from file */
+static gchar* _xfdashboard_gnome_shell_search_provider_plugin_get_provider_name_from_file(GFile *inFile,
+																							GError **outError)
+{
+	const gchar					*filename;
+	gchar						*pluginID;
+	gchar						*providerName;
+
+	g_return_val_if_fail(G_IS_FILE(inFile), NULL);
+	g_return_val_if_fail(outError==NULL || *outError==NULL, NULL);
+
+	/* Get file name of Gnome-Shell search provider */
+	filename=g_file_get_basename(inFile);
+	if(!g_str_has_suffix(filename, ".ini"))
+	{
+		/* Set error */
+		g_set_error_literal(outError,
+							G_IO_ERROR,
+							G_IO_ERROR_INVALID_FILENAME,
+							_("Gnome-Shell search provider filename has wrong file extension."));
+
+		return(NULL);
+	}
+
+	/* Build unique provider name for Gnome-Shell search provider
+	 * using this plugin from file name without file extension.
+	 */
+	providerName=g_strndup(filename, strlen(filename)-4);
+	pluginID=g_strdup_printf("%s.%s", XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_PREFIX, providerName);
+	g_free(providerName);
+
+	/* Return provider name (ID) found */
+	return(pluginID);
+}
+
+/* The directory containing Gnome-Shell search providers has changed */
+static void _xfdashboard_gnome_shell_search_provider_plugin_on_file_monitor_changed(GFileMonitor *self,
+																					GFile *inFile,
+																					GFile *inOtherFile,
+																					GFileMonitorEvent inEventType,
+																					gpointer inUserData)
+{
+	XfdashboardGnomeShellSearchProviderPluginPrivate	*priv;
+	XfdashboardSearchManager							*searchManager;
+	gchar												*filePath;
+	gchar												*providerName;
+	GError												*error;
+	gboolean											success;
+
+	g_return_if_fail(G_IS_FILE_MONITOR(self));
+	g_return_if_fail(inUserData);
+
+	priv=(XfdashboardGnomeShellSearchProviderPluginPrivate*)inUserData;
+	error=NULL;
+
+	/* Get search manager where search providers were registered at */
+	searchManager=xfdashboard_search_manager_get_default();
+
+	/* Get file path */
+	filePath=g_file_get_path(inFile);
+
+	/* Check if a search provider was added */
+	if(inEventType==G_FILE_MONITOR_EVENT_CREATED &&
+		g_file_query_file_type(inFile, G_FILE_QUERY_INFO_NONE, NULL)==G_FILE_TYPE_REGULAR &&
+		g_str_has_suffix(filePath, ".ini"))
+	{
+		providerName=_xfdashboard_gnome_shell_search_provider_plugin_get_provider_name_from_file(inFile, &error);
+		if(providerName)
+		{
+			/* Register search provider */
+			success=xfdashboard_search_manager_register(searchManager, providerName, XFDASHBOARD_TYPE_GNOME_SHELL_SEARCH_PROVIDER);
+			if(success)
+			{
+				priv->providers=g_list_prepend(priv->providers, g_strdup(providerName));
+				g_debug("Successfully registered Gnome-Shell search provider at file '%s' with ID '%s'", filePath, providerName);
+			}
+				else
+				{
+					g_debug("Failed to register Gnome-Shell search provider at file '%s' with ID '%s'", filePath, providerName);
+				}
+		}
+			else
+			{
+				/* Show warning */
+				g_warning(_("Could not register Gnome-Shell search provider at file '%s': %s"),
+							filePath,
+							(error && error->message) ? error->message : _("Unknown error"));
+			}
+
+		/* Release allocated resources */
+		if(providerName) g_free(providerName);
+	}
+
+	/* Check if an existing search provider was removed */
+	if(inEventType==G_FILE_MONITOR_EVENT_DELETED &&
+		g_str_has_suffix(filePath, ".ini"))
+	{
+		providerName=_xfdashboard_gnome_shell_search_provider_plugin_get_provider_name_from_file(inFile, NULL);
+		if(providerName)
+		{
+			/* Unregister search provider */
+			success=xfdashboard_search_manager_unregister(searchManager, providerName);
+			if(success)
+			{
+				GList									*iter;
+				gchar									*iterName;
+
+				/* Iterate through list of registered providers by this plugin
+				 * and remove any matching the provider name.
+				 */
+				for(iter=priv->providers; iter; iter=g_list_next(iter))
+				{
+					iterName=(gchar*)iter->data;
+					if(g_strcmp0(iterName, providerName)==0)
+					{
+						/* Free list data at iterator */
+						g_free(iterName);
+
+						/* Remove and free list element iterator */
+						priv->providers=g_list_delete_link(priv->providers, iter);
+					}
+				}
+
+				g_debug("Successfully unregistered Gnome-Shell search provider at file '%s' with ID '%s'", filePath, providerName);
+			}
+				else
+				{
+					g_debug("Failed to unregister Gnome-Shell search provider at file '%s' with ID '%s'", filePath, providerName);
+				}
+		}
+
+		/* Release allocated resources */
+		if(providerName) g_free(providerName);
+	}
+
+	/* Release allocated resources */
+	if(filePath) g_free(filePath);
+	if(searchManager) g_object_unref(searchManager);
+}
+
 /* Plugin enable function */
 static gboolean plugin_enable(XfdashboardPlugin *self, gpointer inUserData)
 {
-	XfdashboardSearchManager	*searchManager;
-	GFile						*gnomeShellSearchProvidersPath;
-	GFileEnumerator				*enumerator;
-	GFileInfo					*info;
-	GError						*error;
-	gchar						*pluginID;
+	XfdashboardGnomeShellSearchProviderPluginPrivate	*priv;
+	XfdashboardSearchManager							*searchManager;
+	GFile												*gnomeShellSearchProvidersPath;
+	GFileEnumerator										*enumerator;
+	GFileInfo											*info;
+	GError												*error;
+	gchar												*pluginID;
+
+	g_return_val_if_fail(inUserData, XFDASHBOARD_PLUGIN_ACTION_HANDLED);
 
+	priv=(XfdashboardGnomeShellSearchProviderPluginPrivate*)inUserData;
 	error=NULL;
 
 	/* Get plugin's ID */
@@ -90,6 +240,7 @@ static gboolean plugin_enable(XfdashboardPlugin *self, gpointer inUserData)
 		return(XFDASHBOARD_PLUGIN_ACTION_HANDLED);
 	}
 
+
 	/* Iterate through files in search providers path and for each
 	 * ".ini" file found register a search provider
 	 */
@@ -101,36 +252,46 @@ static gboolean plugin_enable(XfdashboardPlugin *self, gpointer inUserData)
 		if(g_file_info_get_file_type(info)==G_FILE_TYPE_REGULAR &&
 			g_str_has_suffix(g_file_info_get_name(info), ".ini"))
 		{
-			const gchar			*filename;
-			gchar				*gnomeShellSearchProviderName;
+			const gchar			*infoFilename;
+			GFile				*infoFile;
+			GError				*infoError;
 			gchar				*providerName;
 			gboolean			success;
 
-			filename=g_file_info_get_name(info);
-			gnomeShellSearchProviderName=g_strndup(filename, strlen(filename)-4);
-			if(gnomeShellSearchProviderName)
-			{
-				/* Build unique provider name for Gnome-Shell search provider
-				 * using this plugin.
-				 */
-				providerName=g_strdup_printf("%s.%s", XFDASHBOARD_GNOME_SHELL_SEARCH_PROVIDER_PREFIX, gnomeShellSearchProviderName);
-				g_debug("Register gnome shell search provider '%s' from file %s", providerName, filename);
+			infoError=NULL;
+
+			/* Get file for current one from enumerator */
+			infoFilename=g_file_info_get_name(info);
+			infoFile=g_file_get_child(g_file_enumerator_get_container(enumerator), infoFilename);
 
+			/* Get provider name for file and register Gnome-Shell search provider */
+			providerName=_xfdashboard_gnome_shell_search_provider_plugin_get_provider_name_from_file(infoFile, &infoError);
+			if(providerName)
+			{
 				/* Register search provider */
 				success=xfdashboard_search_manager_register(searchManager, providerName, XFDASHBOARD_TYPE_GNOME_SHELL_SEARCH_PROVIDER);
 				if(success)
 				{
-					xfdashboard_gnome_shell_search_provider_registered_providers=g_list_prepend(xfdashboard_gnome_shell_search_provider_registered_providers, g_strdup(providerName));
-					g_debug("Successfully registered Gnome-Shell search provider '%s' with ID '%s'", gnomeShellSearchProviderName, providerName);
+					priv->providers=g_list_prepend(priv->providers, g_strdup(providerName));
+					g_debug("Successfully registered Gnome-Shell search provider at file '%s' with ID '%s'", infoFilename, providerName);
 				}
 					else
 					{
-						g_debug("Failed to register Gnome-Shell search provider '%s' with ID '%s'", gnomeShellSearchProviderName, providerName);
+						g_debug("Failed to register Gnome-Shell search provider at file '%s' with ID '%s'", infoFilename, providerName);
 					}
-
-				g_free(providerName);
-				g_free(gnomeShellSearchProviderName);
 			}
+				else
+				{
+					/* Show warning */
+					g_warning(_("Could not register Gnome-Shell search provider at file '%s': %s"),
+								infoFilename,
+								(infoError && infoError->message) ? infoError->message : _("Unknown error"));
+				}
+
+			/* Release allocated resources */
+			if(infoError) g_error_free(infoError);
+			if(infoFile) g_object_unref(infoFile);
+			if(providerName) g_free(providerName);
 		}
 
 		/* Release allocated resources */
@@ -155,12 +316,38 @@ static gboolean plugin_enable(XfdashboardPlugin *self, gpointer inUserData)
 	}
 
 	/* Create monitor to get notified about new, changed and removed search providers */
-	// TODO:
+	priv->fileMonitor=g_file_monitor_directory(gnomeShellSearchProvidersPath, G_FILE_MONITOR_NONE, NULL, &error);
+	if(priv->fileMonitor)
+	{
+		g_debug("Created file monitor to watch for changed Gnome-Shell search providers at %s",
+					GNOME_SHELL_PROVIDERS_PATH);
+
+		g_signal_connect(priv->fileMonitor,
+							"changed",
+							G_CALLBACK(_xfdashboard_gnome_shell_search_provider_plugin_on_file_monitor_changed),
+							priv);
+	}
+		else
+		{
+			/* Just print a warning but do not fail. We will just not get notified
+			 * about changes at path where the providers are stored.
+			 */
+			g_warning(_("Unable to create file monitor for Gnome-Shell search providers at '%s': %s"),
+						GNOME_SHELL_PROVIDERS_PATH,
+						error ? error->message : _("Unknown error"));
+
+			/* Release allocated resources */
+			if(error)
+			{
+				g_error_free(error);
+				error=NULL;
+			}
+		}
 
 	/* Release allocated resources */
 	g_debug("Enabled plugin '%s' with %d search providers",
 				pluginID,
-				g_list_length(xfdashboard_gnome_shell_search_provider_registered_providers));
+				g_list_length(priv->providers));
 
 	if(pluginID) g_free(pluginID);
 	if(enumerator) g_object_unref(enumerator);
@@ -174,23 +361,38 @@ static gboolean plugin_enable(XfdashboardPlugin *self, gpointer inUserData)
 /* Plugin disable function */
 static gboolean plugin_disable(XfdashboardPlugin *self, gpointer inUserData)
 {
-	XfdashboardSearchManager	*searchManager;
-	GList						*iter;
-	const gchar					*providerName;
-	gboolean					success;
-	gchar						*pluginID;
+	XfdashboardGnomeShellSearchProviderPluginPrivate	*priv;
+	XfdashboardSearchManager							*searchManager;
+	GList												*iter;
+	const gchar											*providerName;
+	gboolean											success;
+	gchar												*pluginID;
+
+	g_return_val_if_fail(inUserData, XFDASHBOARD_PLUGIN_ACTION_HANDLED);
+
+	priv=(XfdashboardGnomeShellSearchProviderPluginPrivate*)inUserData;
 
 	/* Get plugin's ID */
 	g_object_get(G_OBJECT(self), "id", &pluginID, NULL);
 	g_debug("Disabling plugin '%s' with %d search providers",
 				pluginID,
-				g_list_length(xfdashboard_gnome_shell_search_provider_registered_providers));
+				g_list_length(priv->providers));
+
+	/* At first remove file monitor for path where search providers are stored */
+	if(priv->fileMonitor)
+	{
+		g_object_unref(priv->fileMonitor);
+		priv->fileMonitor=NULL;
+
+		g_debug("Removed file monitor to watch for changed Gnome-Shell search providers at %s",
+					GNOME_SHELL_PROVIDERS_PATH);
+	}
 
 	/* Get search manager where search providers were registered at */
 	searchManager=xfdashboard_search_manager_get_default();
 
 	/* Unregister registered search providers */
-	for(iter=xfdashboard_gnome_shell_search_provider_registered_providers; iter; iter=g_list_next(iter))
+	for(iter=priv->providers; iter; iter=g_list_next(iter))
 	{
 		providerName=(const gchar*)iter->data;
 
@@ -214,10 +416,10 @@ static gboolean plugin_disable(XfdashboardPlugin *self, gpointer inUserData)
 	g_debug("Disabled plugin '%s'", pluginID);
 
 	if(pluginID) g_free(pluginID);
-	if(xfdashboard_gnome_shell_search_provider_registered_providers)
+	if(priv->providers)
 	{
-		g_list_free_full(xfdashboard_gnome_shell_search_provider_registered_providers, g_free);
-		xfdashboard_gnome_shell_search_provider_registered_providers=NULL;
+		g_list_free_full(priv->providers, g_free);
+		priv->providers=NULL;
 	}
 
 	/* All done */
@@ -227,6 +429,8 @@ static gboolean plugin_disable(XfdashboardPlugin *self, gpointer inUserData)
 /* Plugin initialization function */
 G_MODULE_EXPORT void plugin_init(XfdashboardPlugin *self)
 {
+	static XfdashboardGnomeShellSearchProviderPluginPrivate		priv={ 0, };
+
 	/* Set up localization */
 	xfce_textdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
 
@@ -242,6 +446,6 @@ G_MODULE_EXPORT void plugin_init(XfdashboardPlugin *self)
 	XFDASHBOARD_REGISTER_PLUGIN_TYPE(self, xfdashboard_gnome_shell_search_provider);
 
 	/* Connect plugin action handlers */
-	g_signal_connect(self, "enable", G_CALLBACK(plugin_enable), NULL);
-	g_signal_connect(self, "disable", G_CALLBACK(plugin_disable), NULL);
+	g_signal_connect(self, "enable", G_CALLBACK(plugin_enable), &priv);
+	g_signal_connect(self, "disable", G_CALLBACK(plugin_disable), &priv);
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list