[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