[Xfce4-commits] [apps/xfdashboard] 01/01: Begin implementation of theme defined focusable actors and their order

noreply at xfce.org noreply at xfce.org
Fri Dec 18 13:46:29 CET 2015


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

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

commit 6da1b4dab37e00c09fd61a8083c14f0d03163679
Author: Stephan Haller <nomad at froevel.de>
Date:   Fri Dec 18 13:44:37 2015 +0100

    Begin implementation of theme defined focusable actors and their order
    
    This commit only add parsing <focusables> and <focus> as described in issue GH #104 , it does not register and use the defined actors in focus manager yet.
    
    This commit is addressed to issue GH #104
---
 xfdashboard/theme-layout.c |  261 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 224 insertions(+), 37 deletions(-)

diff --git a/xfdashboard/theme-layout.c b/xfdashboard/theme-layout.c
index f1310e2..35c079b 100644
--- a/xfdashboard/theme-layout.c
+++ b/xfdashboard/theme-layout.c
@@ -57,7 +57,9 @@ enum
 	TAG_CHILD,
 	TAG_PROPERTY,
 	TAG_CONSTRAINT,
-	TAG_LAYOUT
+	TAG_LAYOUT,
+	TAG_FOCUSABLES,
+	TAG_FOCUS
 };
 
 typedef struct _XfdashboardThemeLayoutTagData			XfdashboardThemeLayoutTagData;
@@ -82,6 +84,11 @@ struct _XfdashboardThemeLayoutTagData
 			gboolean					translatable;
 			gchar						*refID;
 		} property;
+
+		struct
+		{
+			gchar						*refID;
+		} focus;
 	} tag;
 };
 
@@ -96,6 +103,7 @@ struct _XfdashboardThemeLayoutParsedObject
 	GSList								*constraints;	/* 0, 1 or more entries of XfdashboardThemeLayoutParsedObject */
 	XfdashboardThemeLayoutParsedObject	*layout;		/* 0 or 1 entry of XfdashboardThemeLayoutParsedObject */
 	GSList								*children;		/* 0, 1 or more entries of XfdashboardThemeLayoutParsedObject */
+	GSList								*focusables;	/* 0, 1 or more entries of XfdashboardThemeLayoutTagData (only used at <interface>) */
 };
 
 typedef struct _XfdashboardThemeLayoutParserData		XfdashboardThemeLayoutParserData;
@@ -106,6 +114,7 @@ struct _XfdashboardThemeLayoutParserData
 	XfdashboardThemeLayoutParsedObject	*interface;
 	GQueue								*stackObjects;
 	GQueue								*stackTags;
+	GSList								*focusables;	/* 0, 1 or more entries of XfdashboardThemeLayoutTagData */
 
 	gint								lastLine;
 	gint								lastPosition;
@@ -312,6 +321,8 @@ static gint _xfdashboard_theme_layout_get_tag_by_name(const gchar *inTag)
 	if(g_strcmp0(inTag, "property")==0) return(TAG_PROPERTY);
 	if(g_strcmp0(inTag, "constraint")==0) return(TAG_CONSTRAINT);
 	if(g_strcmp0(inTag, "layout")==0) return(TAG_LAYOUT);
+	if(g_strcmp0(inTag, "focusables")==0) return(TAG_FOCUSABLES);
+	if(g_strcmp0(inTag, "focus")==0) return(TAG_FOCUS);
 
 	/* If we get here we do not know tag name and return invalid ID */
 	return(-1);
@@ -343,6 +354,12 @@ static const gchar* _xfdashboard_theme_layout_get_tag_by_id(guint inTagType)
 		case TAG_LAYOUT:
 			return("layout");
 
+		case TAG_FOCUSABLES:
+			return("focusables");
+
+		case TAG_FOCUS:
+			return("focus");
+
 		default:
 			break;
 	}
@@ -408,6 +425,10 @@ static void _xfdashboard_theme_layout_tag_data_free(XfdashboardThemeLayoutTagDat
 			if(inData->tag.property.value) g_free(inData->tag.property.value);
 			if(inData->tag.property.refID) g_free(inData->tag.property.refID);
 			break;
+
+		case TAG_FOCUS:
+			if(inData->tag.focus.refID) g_free(inData->tag.focus.refID);
+			break;
 	}
 
 	/* Release common allocated resources */
@@ -479,6 +500,7 @@ static void _xfdashboard_theme_layout_object_data_free(XfdashboardThemeLayoutPar
 	if(inData->constraints) g_slist_free_full(inData->constraints, (GDestroyNotify)_xfdashboard_theme_layout_object_data_unref);
 	if(inData->layout) _xfdashboard_theme_layout_object_data_unref(inData->layout);
 	if(inData->children) g_slist_free_full(inData->children, (GDestroyNotify)_xfdashboard_theme_layout_object_data_unref);
+	if(inData->focusables) g_slist_free_full(inData->focusables, (GDestroyNotify)_xfdashboard_theme_layout_tag_data_unref);
 	g_free(inData);
 }
 
@@ -531,9 +553,9 @@ static void _xfdashboard_theme_layout_create_object_resolve_unresolved(Xfdashboa
 																		GHashTable *inIDs,
 																		GSList *inUnresolvedIDs)
 {
-	GObject										*refObject;
-	GSList										*entry;
+	GSList										*iter;
 	XfdashboardThemeLayoutUnresolvedBuildID		*unresolvedID;
+	GObject										*refObject;
 
 	g_return_if_fail(XFDASHBOARD_IS_THEME_LAYOUT(self));
 	g_return_if_fail(inIDs);
@@ -545,23 +567,51 @@ static void _xfdashboard_theme_layout_create_object_resolve_unresolved(Xfdashboa
 	 * and get referenced object and set the pointer to this object at the
 	 * mapped property of target object.
 	 */
-	for(entry=inUnresolvedIDs; entry; entry=g_slist_next(entry))
+	for(iter=inUnresolvedIDs; iter; iter=g_slist_next(iter))
 	{
-		unresolvedID=(XfdashboardThemeLayoutUnresolvedBuildID*)entry->data;
-
-		/* Get referenced object */
-		refObject=g_hash_table_lookup(inIDs, unresolvedID->property->tag.property.refID);
-
-		/* Set pointer to referenced object in property of target object */
-		g_object_set(unresolvedID->targetObject,
-						unresolvedID->property->tag.property.name,
-						refObject,
-						NULL);
-		g_debug("Set previously unresolved object %s with ID '%s' at target object %s at property '%s'",
-					refObject ? G_OBJECT_TYPE_NAME(refObject) : "<unknown object>",
-					unresolvedID->property->tag.property.refID,
-					unresolvedID->targetObject ? G_OBJECT_TYPE_NAME(unresolvedID->targetObject) : "<unknown object>",
-					unresolvedID->property->tag.property.name);
+		unresolvedID=(XfdashboardThemeLayoutUnresolvedBuildID*)iter->data;
+		g_assert(unresolvedID);
+
+		/* Get ID of object to resolve but only from supported tag types */
+		switch(unresolvedID->property->tagType)
+		{
+			case TAG_PROPERTY:
+				/* Get referenced object */
+				refObject=g_hash_table_lookup(inIDs, unresolvedID->property->tag.property.refID);
+
+				/* Set pointer to referenced object in property of target object */
+				g_object_set(unresolvedID->targetObject,
+								unresolvedID->property->tag.property.name,
+								refObject,
+								NULL);
+				g_debug("Set previously unresolved object %s with ID '%s' at target object %s at property '%s'",
+							refObject ? G_OBJECT_TYPE_NAME(refObject) : "<unknown object>",
+							unresolvedID->property->tag.property.refID,
+							unresolvedID->targetObject ? G_OBJECT_TYPE_NAME(unresolvedID->targetObject) : "<unknown object>",
+							unresolvedID->property->tag.property.name);
+				break;
+
+			case TAG_FOCUS:
+				/* Get referenced object */
+				refObject=g_hash_table_lookup(inIDs, unresolvedID->property->tag.focus.refID);
+
+				/* Set pointer to referenced object in property of target object */
+				g_object_set(unresolvedID->targetObject,
+								"add-focus",
+								refObject,
+								NULL);
+				g_debug("Set previously unresolved object %s with ID '%s' at target object %s at property '%s'",
+							refObject ? G_OBJECT_TYPE_NAME(refObject) : "<unknown object>",
+							unresolvedID->property->tag.focus.refID,
+							unresolvedID->targetObject ? G_OBJECT_TYPE_NAME(unresolvedID->targetObject) : "<unknown object>",
+							"add-focus");
+				break;
+
+			default:
+				g_critical(_("Unsupported tag type '%s' to resolve ID"),
+							_xfdashboard_theme_layout_get_tag_by_id(unresolvedID->property->tagType));
+				break;;
+		}
 	}
 }
 
@@ -575,7 +625,7 @@ static GObject* _xfdashboard_theme_layout_create_object(XfdashboardThemeLayout *
 														GSList **ioUnresolvedIDs)
 {
 	GObject									*object;
-	GSList									*entry;
+	GSList									*iter;
 	GParameter								*properties;
 	gint									maxProperties, usedProperties, i;
 
@@ -591,11 +641,11 @@ static GObject* _xfdashboard_theme_layout_create_object(XfdashboardThemeLayout *
 	maxProperties=g_slist_length(inObjectData->properties);
 	if(maxProperties>0) properties=g_new0(GParameter, maxProperties);
 
-	for(entry=inObjectData->properties; entry; entry=g_slist_next(entry))
+	for(iter=inObjectData->properties; iter; iter=g_slist_next(iter))
 	{
 		XfdashboardThemeLayoutTagData		*property;
 
-		property=(XfdashboardThemeLayoutTagData*)entry->data;
+		property=(XfdashboardThemeLayoutTagData*)iter->data;
 
 		/* Check if property refers to an other object, if not add it */
 		if(!property->tag.property.refID)
@@ -658,12 +708,12 @@ static GObject* _xfdashboard_theme_layout_create_object(XfdashboardThemeLayout *
 	}
 
 	/* Create children */
-	for(entry=inObjectData->children; entry; entry=g_slist_next(entry))
+	for(iter=inObjectData->children; iter; iter=g_slist_next(iter))
 	{
 		XfdashboardThemeLayoutParsedObject	*childObjectData;
 		GObject								*child;
 
-		childObjectData=(XfdashboardThemeLayoutParsedObject*)entry->data;
+		childObjectData=(XfdashboardThemeLayoutParsedObject*)iter->data;
 
 		/* Create child actor */
 		child=_xfdashboard_theme_layout_create_object(self, childObjectData, ioIDs, ioUnresolvedIDs);
@@ -736,12 +786,12 @@ static GObject* _xfdashboard_theme_layout_create_object(XfdashboardThemeLayout *
 	}
 
 	/* Create constraints */
-	for(entry=inObjectData->constraints; entry; entry=g_slist_next(entry))
+	for(iter=inObjectData->constraints; iter; iter=g_slist_next(iter))
 	{
 		XfdashboardThemeLayoutParsedObject	*constraintObjectData;
 		GObject								*constraint;
 
-		constraintObjectData=(XfdashboardThemeLayoutParsedObject*)entry->data;
+		constraintObjectData=(XfdashboardThemeLayoutParsedObject*)iter->data;
 
 		/* Create constraint */
 		constraint=_xfdashboard_theme_layout_create_object(self, constraintObjectData, ioIDs, ioUnresolvedIDs);
@@ -775,25 +825,46 @@ static GObject* _xfdashboard_theme_layout_create_object(XfdashboardThemeLayout *
 	}
 
 	/* Set up properties which do reference other objects */
-	for(entry=inObjectData->properties; entry; entry=g_slist_next(entry))
+	for(iter=inObjectData->properties; iter; iter=g_slist_next(iter))
 	{
 		XfdashboardThemeLayoutTagData					*property;
 
-		property=(XfdashboardThemeLayoutTagData*)entry->data;
+		/* Get property data */
+		property=(XfdashboardThemeLayoutTagData*)iter->data;
 
 		/* Check if property refers to an other object, if it does add it */
 		if(property->tag.property.refID)
 		{
 			XfdashboardThemeLayoutUnresolvedBuildID		*unresolved;
 
+			/* Create unresolved entry */
 			unresolved=g_new0(XfdashboardThemeLayoutUnresolvedBuildID, 1);
 			unresolved->targetObject=g_object_ref(object);
 			unresolved->property=_xfdashboard_theme_layout_tag_data_ref(property);
 
+			/* Add to list of unresolved IDs */
 			*ioUnresolvedIDs=g_slist_prepend(*ioUnresolvedIDs, unresolved);
 		}
 	}
 
+	/* Set up focusables which do reference other objects */
+	for(iter=inObjectData->focusables; iter; iter=g_slist_next(iter))
+	{
+		XfdashboardThemeLayoutTagData					*focus;
+		XfdashboardThemeLayoutUnresolvedBuildID			*unresolved;
+
+		/* Get focus data */
+		focus=(XfdashboardThemeLayoutTagData*)iter->data;
+
+		/* Create unresolved entry */
+		unresolved=g_new0(XfdashboardThemeLayoutUnresolvedBuildID, 1);
+		unresolved->targetObject=g_object_ref(object);
+		unresolved->property=_xfdashboard_theme_layout_tag_data_ref(focus);
+
+		/* Add to list of unresolved IDs */
+		*ioUnresolvedIDs=g_slist_prepend(*ioUnresolvedIDs, unresolved);
+	}
+
 	/* Return created actor */
 	return(object);
 }
@@ -1151,7 +1222,8 @@ static void _xfdashboard_theme_layout_parse_general_start(GMarkupParseContext *i
 	/* Check if element name is <property> and follows expected parent tags:
 	 * <object>
 	 */
-	if(nextTag==TAG_PROPERTY && currentTag==TAG_OBJECT)
+	if(nextTag==TAG_PROPERTY &&
+		currentTag==TAG_OBJECT)
 	{
 		XfdashboardThemeLayoutTagData		*tagData;
 		static GMarkupParser				propertyParser=
@@ -1214,6 +1286,76 @@ static void _xfdashboard_theme_layout_parse_general_start(GMarkupParseContext *i
 		return;
 	}
 
+	/* Check if element name is <focusables> and follows expected parent tags:
+	 * <interface>
+	 */
+	if(nextTag==TAG_FOCUSABLES &&
+		currentTag==TAG_INTERFACE)
+	{
+		XfdashboardThemeLayoutTagData		*tagData;
+
+		/* Create tag data */
+		tagData=_xfdashboard_theme_layout_tag_data_new(inContext, nextTag, &error);
+		if(!tagData)
+		{
+			g_propagate_error(outError, error);
+			return;
+		}
+
+		/* Get tag's attributes */
+		if(!g_markup_collect_attributes(inElementName,
+											inAttributeNames,
+											inAttributeValues,
+											&error,
+											G_MARKUP_COLLECT_INVALID,
+											NULL))
+		{
+			g_propagate_error(outError, error);
+			_xfdashboard_theme_layout_tag_data_unref(tagData);
+			return;
+		}
+
+		/* Push tag onto stack */
+		g_queue_push_tail(data->stackTags, tagData);
+		return;
+	}
+
+	/* Check if element name is <focus> and follows expected parent tags:
+	 * <focusables>
+	 */
+	if(nextTag==TAG_FOCUS &&
+		currentTag==TAG_FOCUSABLES)
+	{
+		XfdashboardThemeLayoutTagData		*tagData;
+
+		/* Create tag data */
+		tagData=_xfdashboard_theme_layout_tag_data_new(inContext, nextTag, &error);
+		if(!tagData)
+		{
+			g_propagate_error(outError, error);
+			return;
+		}
+
+		/* Get tag's attributes */
+		if(!g_markup_collect_attributes(inElementName,
+											inAttributeNames,
+											inAttributeValues,
+											&error,
+											G_MARKUP_COLLECT_STRDUP,
+											"ref",
+											&tagData->tag.focus.refID,
+											G_MARKUP_COLLECT_INVALID))
+		{
+			g_propagate_error(outError, error);
+			_xfdashboard_theme_layout_tag_data_unref(tagData);
+			return;
+		}
+
+		/* Push tag onto stack */
+		g_queue_push_tail(data->stackTags, tagData);
+		return;
+	}
+
 	/* If we get here the given element name cannot follow this tag */
 	_xfdashboard_theme_layout_parse_set_error(data,
 												inContext,
@@ -1340,6 +1482,40 @@ static void _xfdashboard_theme_layout_parse_general_end(GMarkupParseContext *inC
 		g_markup_parse_context_pop(inContext);
 	}
 
+	/* Handle end of element <focus> */
+	if(subTagData->tagType==TAG_FOCUS)
+	{
+		/* Add focusable actor to parser data */
+		data->focusables=g_slist_append(data->focusables, _xfdashboard_theme_layout_tag_data_ref(subTagData));
+		g_debug("Adding focusable actor referenced by ID '%s' to parser data",
+					subTagData->tag.focus.refID);
+	}
+
+	/* Handle end of element <interface> */
+	if(subTagData->tagType==TAG_INTERFACE)
+	{
+		GSList									*iter;
+		XfdashboardThemeLayoutTagData			*iterTagData;
+
+		g_assert(data->interface);
+		g_assert(!data->interface->focusables);
+
+		g_debug("Copying %d focusable actor IDs to interface '%s'",
+					g_slist_length(data->focusables),
+					data->interface->id);
+
+		/* Copy list of focusable actors from parser data to interface object data */
+		for(iter=data->focusables; iter; iter=g_slist_next(iter))
+		{
+			iterTagData=(XfdashboardThemeLayoutTagData*)iter->data;
+
+			g_assert(iterTagData);
+
+			data->interface->focusables=g_slist_prepend(data->interface->focusables, _xfdashboard_theme_layout_tag_data_ref(iterTagData));
+		}
+		data->interface->focusables=g_slist_reverse(data->interface->focusables);
+	}
+
 	/* Unreference last tag's data */
 	_xfdashboard_theme_layout_tag_data_unref(subTagData);
 }
@@ -1659,6 +1835,8 @@ static gboolean _xfdashboard_theme_layout_parse_xml(XfdashboardThemeLayout *self
 	}
 	g_queue_free(data->stackTags);
 
+	if(data->focusables) g_slist_free_full(data->focusables, (GDestroyNotify)_xfdashboard_theme_layout_tag_data_unref);
+
 	g_free(data);
 
 	/* Return success result */
@@ -1779,7 +1957,7 @@ ClutterActor* xfdashboard_theme_layout_build_interface(XfdashboardThemeLayout *s
 														const gchar *inID)
 {
 	XfdashboardThemeLayoutPrivate				*priv;
-	GSList										*entry;
+	GSList										*iter;
 	XfdashboardThemeLayoutParsedObject			*interfaceData;
 	ClutterActor								*actor;
 	GHashTable									*ids;
@@ -1790,21 +1968,21 @@ ClutterActor* xfdashboard_theme_layout_build_interface(XfdashboardThemeLayout *s
 
 	priv=self->priv;
 	interfaceData=NULL;
-	unresolved=NULL;
 
 	/* Find parsed object data for requested interface by its ID */
-	entry=priv->interfaces;
-	while(entry && !interfaceData)
+	iter=priv->interfaces;
+	while(iter && !interfaceData)
 	{
 		XfdashboardThemeLayoutParsedObject		*objectData;
 
-		objectData=(XfdashboardThemeLayoutParsedObject*)entry->data;
+		/* Get interface object data currently iterated */
+		objectData=(XfdashboardThemeLayoutParsedObject*)iter->data;
 
 		/* Check if this object data is for the requested interface */
 		if(g_strcmp0(objectData->id, inID)==0) interfaceData=objectData;
 
 		/* Continue with next entry */
-		entry=g_slist_next(entry);
+		iter=g_slist_next(iter);
 	}
 
 	/* If we get here and we did not found the requested interface
@@ -1816,11 +1994,18 @@ ClutterActor* xfdashboard_theme_layout_build_interface(XfdashboardThemeLayout *s
 		return(NULL);
 	}
 
-	/* Create actor */
+	/* Keep interface object data alive while building interface
+	 * by taking an extra reference.
+	 */
 	_xfdashboard_theme_layout_object_data_ref(interfaceData);
 
+	/* Create hash-table to resolve IDs of objects created and
+	 * initialize empty list of IDs to resolve.
+	 */
 	ids=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
-	
+	unresolved=NULL;
+
+	/* Create actor */
 	actor=CLUTTER_ACTOR(_xfdashboard_theme_layout_create_object(self, interfaceData, ids, &unresolved));
 	if(actor)
 	{
@@ -1831,9 +2016,11 @@ ClutterActor* xfdashboard_theme_layout_build_interface(XfdashboardThemeLayout *s
 	}
 		else g_debug("Failed to create actor for interface '%s'", inID);
 
+	/* Release allocated resources */
 	if(ids) g_hash_table_destroy(ids);
 	if(unresolved) g_slist_free_full(unresolved, _xfdashboard_theme_layout_create_object_free_unresolved);
 
+	/* Release extra reference taken at interface object data */
 	_xfdashboard_theme_layout_object_data_unref(interfaceData);
 
 	/* Return created actor */

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


More information about the Xfce4-commits mailing list