Ben Reeves wrote:> I am writing a configuration front end for the compiz gconf plugin at
> the moment, but it's proving harder than it should be because gconf
> does not record what type of compiz option the key is. For example,
> say i want a color picker for each color option the only way I can
> tell with gconf if it is color is if it has a # at the beginning, but
> there could be string option which also have a # at the beginning so
> is not reliable.
>
> My proposal is that the short_description of each gconf key should
> contain the option type
I think the solution for this is to wait until the dbus bindings
support getting information about settings. I have been working
on this and have a rough solution which I have attached.
Putting the type into the option description, or a seperate file seems
like it would cause a lot of problems. The short description is translated
so that would cause bugs, it is also not straight forward for developers.
The dbus patches are roughly my idea for how information about
options can be got via dbus. I wrote them so there is one getMetadata
function which returns all the information about the option. Your
application should cache this information as often as possible.
I think that the method should return a dictionary rather multiple
return values. I couldn't find how to create a dictionary so I stopped.
If anyone knows how to do this (or even if I can just return multiple
return values) I would like to know.
Mike
-------------- next part --------------
--- ../../clean/plugins/dbus.c 2006-11-10 00:13:43.840442488 +0000
+++ dbus.c 2006-11-13 05:51:04.328568976 +0000
@@ -32,11 +32,13 @@
#include <compiz.h>
-#define COMPIZ_DBUS_SERVICE_NAME "org.freedesktop.compiz"
-#define COMPIZ_DBUS_ACTIVATE_MEMBER_NAME "activate"
-#define COMPIZ_DBUS_DEACTIVATE_MEMBER_NAME "deactivate"
-#define COMPIZ_DBUS_SET_MEMBER_NAME "set"
-#define COMPIZ_DBUS_GET_MEMBER_NAME "get"
+#define COMPIZ_DBUS_SERVICE_NAME
"org.freedesktop.compiz"
+#define COMPIZ_DBUS_ACTIVATE_MEMBER_NAME "activate"
+#define COMPIZ_DBUS_DEACTIVATE_MEMBER_NAME "deactivate"
+#define COMPIZ_DBUS_SET_MEMBER_NAME "set"
+#define COMPIZ_DBUS_GET_MEMBER_NAME "get"
+#define COMPIZ_DBUS_GET_OPTIONS_MEMBER_NAME "getOptions"
+#define COMPIZ_DBUS_GET_OPTION_METADATA_MEMBER_NAME
"getOptionMetadata"
typedef enum {
DbusActionIndexKeyBinding = 0,
@@ -140,15 +142,14 @@
* /org/freedesktop/compiz/cube/allscreens/unfold \
* org.freedesktop.compiz.activate \
* string:'root' \
- * int32:`xwininfo -root | grep id: | awk '{ print $4 }'` \
- * string:'face' int32:1
+ * int32:`xwininfo -root | grep id: | awk '{ print $4 }'`
*
* dbus-send --type=method_call --dest=org.freedesktop.compiz \
* /org/freedesktop/compiz/cube/allscreens/unfold \
* org.freedesktop.compiz.deactivate \
* string:'root' \
- * int32:`xwininfo -root | grep id: | awk '{ print $4 }'` \
- * string:'face' int32:1
+ * int32:`xwininfo -root | grep id: | awk '{ print $4 }'`
+ *
*/
static Bool
dbusHandleActionMessage (DBusConnection *connection,
@@ -287,6 +288,16 @@
if (argument)
free (argument);
+ DBusMessage *reply;
+ Bool msgTrue = TRUE;
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply,
+ DBUS_TYPE_BOOLEAN, &msgTrue,
+ DBUS_TYPE_INVALID);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_connection_flush (connection);
+ dbus_message_unref (reply);
+
return TRUE;
}
@@ -702,6 +713,179 @@
return FALSE;
}
+static Bool
+dbusHandleGetOptionsMessage (DBusConnection *connection,
+ DBusMessage *message,
+ CompDisplay *d,
+ char **path)
+{
+ CompScreen *s;
+ CompOption *option;
+ int nOption;
+
+ option = dbusGetOptionsFromPath (d, path, &s, &nOption);
+ if (!option)
+ return FALSE;
+
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return (message);
+
+ while (nOption--)
+ {
+ dbus_message_append_args (reply,
+ DBUS_TYPE_STRING, &option->name,
+ DBUS_TYPE_INVALID);
+ option++;
+ }
+ dbus_connection_send (connection, reply, NULL);
+ dbus_connection_flush (connection);
+
+ dbus_message_unref (reply);
+
+ return TRUE;
+
+}
+
+static Bool
+dbusHandleGetOptionMetadataMessage (DBusConnection *connection,
+ DBusMessage *message,
+ CompDisplay *d,
+ char **path)
+{
+ CompScreen *s;
+ CompOption *option;
+ int nOption;
+ Bool handled = FALSE;
+ int i;
+
+ double min;
+ double max;
+ double precision;
+
+ char *msgInvalid = "INVALID";
+ char *sPossible;
+
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return (message);
+
+
+ option = dbusGetOptionsFromPath (d, path, &s, &nOption);
+ if (!option)
+ {
+ dbus_message_append_args (reply,
+ DBUS_TYPE_STRING, &msgInvalid,
+ DBUS_TYPE_INVALID);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_connection_flush (connection);
+
+ dbus_message_unref (reply);
+ return TRUE;
+ }
+
+ while (nOption--)
+ {
+ if (strcmp (option->name, path[2]) == 0)
+ {
+ char *type[16];
+ char *listtype[16];
+
+ if (option->type == CompOptionTypeAction)
+ *type = "Action";
+ else if (option->type == CompOptionTypeBool)
+ *type = "Bool";
+ else if (option->type == CompOptionTypeInt)
+ *type = "Int";
+ else if (option->type == CompOptionTypeFloat)
+ *type = "Float";
+ else if (option->type == CompOptionTypeString)
+ *type = "String";
+ else if (option->type == CompOptionTypeColor)
+ *type = "Color";
+ else if (option->type == CompOptionTypeList)
+ *type = "List";
+
+
+ dbus_message_append_args (reply,
+ DBUS_TYPE_STRING, &option->shortDesc,
+ DBUS_TYPE_STRING, &option->longDesc,
+ DBUS_TYPE_STRING, &type,
+ DBUS_TYPE_INVALID);
+
+ if (option->type == CompOptionTypeList)
+ {
+ if (option->value.list.type == CompOptionTypeBool)
+ *listtype = "Bool";
+ else if (option->value.list.type == CompOptionTypeInt)
+ *listtype = "Int";
+ else if (option->value.list.type == CompOptionTypeFloat)
+ *listtype = "Float";
+ else if (option->value.list.type == CompOptionTypeString)
+ *listtype = "String";
+ else if (option->value.list.type == CompOptionTypeColor)
+ *listtype = "Color";
+ dbus_message_append_args (reply,
+ DBUS_TYPE_STRING, &listtype,
+ DBUS_TYPE_INVALID);
+ }
+
+ if (option->type == CompOptionTypeInt ||
+ ( (option->type == CompOptionTypeList) &&
+ (option->value.list.type == CompOptionTypeInt) ) )
+ dbus_message_append_args (reply,
+ DBUS_TYPE_INT32, &option->rest.i.min,
+ DBUS_TYPE_INT32, &option->rest.i.max,
+ DBUS_TYPE_INVALID);
+
+ else if (option->type == CompOptionTypeFloat ||
+ ( (option->type == CompOptionTypeList) &&
+ (option->value.list.type == CompOptionTypeFloat) ) )
+ {
+ min = option->rest.f.min;
+ max = option->rest.f.max;
+ precision = option->rest.f.precision;
+ dbus_message_append_args (reply,
+ DBUS_TYPE_DOUBLE, &min,
+ DBUS_TYPE_DOUBLE, &max,
+ DBUS_TYPE_DOUBLE, &precision,
+ DBUS_TYPE_INVALID);
+ }
+ else if (option->type == CompOptionTypeString ||
+ ( (option->type == CompOptionTypeList) &&
+ (option->value.list.type == CompOptionTypeString) ) )
+ {
+ if (option->rest.s.nString)
+ {
+ for ( i=0; i < option->rest.s.nString; i++ )
+ {
+ sPossible = option->rest.s.string[i];
+ dbus_message_append_args (reply,
+ DBUS_TYPE_STRING, &sPossible,
+ DBUS_TYPE_INVALID);
+ }
+ }
+ }
+ handled = TRUE;
+ }
+ option++;
+ }
+
+ if (!handled)
+ dbus_message_append_args (reply,
+ DBUS_TYPE_STRING, &msgInvalid,
+ DBUS_TYPE_INVALID);
+
+
+ dbus_connection_send (connection, reply, NULL);
+ dbus_connection_flush (connection);
+
+ dbus_message_unref (reply);
+
+ return TRUE;
+
+}
+
static DBusHandlerResult
dbusHandleMessage (DBusConnection *connection,
DBusMessage *message,
@@ -728,7 +912,7 @@
if (!dbus_message_get_path_decomposed (message, &path))
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- if (!path[0] || !path[1] || !path[2] || !path[3] || !path[4] || !path[5])
+ if (!path[0] || !path[1] || !path[2] || !path[3] || !path[4])
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if (strcmp (path[0], "org") ||
@@ -736,25 +920,41 @@
strcmp (path[2], "compiz"))
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- if (dbus_message_has_member (message, COMPIZ_DBUS_ACTIVATE_MEMBER_NAME))
+ if (dbus_message_has_member (message, COMPIZ_DBUS_ACTIVATE_MEMBER_NAME)
&&
+ path[5])
{
status = dbusHandleActionMessage (connection, message, d, &path[3],
TRUE);
}
else if (dbus_message_has_member (message,
- COMPIZ_DBUS_DEACTIVATE_MEMBER_NAME))
+ COMPIZ_DBUS_DEACTIVATE_MEMBER_NAME) &&
+ path[5])
{
status = dbusHandleActionMessage (connection, message, d, &path[3],
FALSE);
}
- else if (dbus_message_has_member (message, COMPIZ_DBUS_SET_MEMBER_NAME))
+ else if (dbus_message_has_member (message, COMPIZ_DBUS_SET_MEMBER_NAME)
&&
+ path[5])
{
status = dbusHandleSetOptionMessage (connection, message, d, &path[3]);
}
- else if (dbus_message_has_member (message, COMPIZ_DBUS_GET_MEMBER_NAME))
+ else if (dbus_message_has_member (message,
+ COMPIZ_DBUS_GET_MEMBER_NAME) &&
path[5])
{
status = dbusHandleGetOptionMessage (connection, message, d, &path[3]);
}
+ else if (dbus_message_has_member (message,
+ COMPIZ_DBUS_GET_OPTIONS_MEMBER_NAME))
+ {
+ status = dbusHandleGetOptionsMessage (connection, message, d, &path[3]);
+ }
+ else if (dbus_message_has_member (message,
+ COMPIZ_DBUS_GET_OPTION_METADATA_MEMBER_NAME)
&&
+ path[5])
+ {
+ status = dbusHandleGetOptionMetadataMessage (connection, message, d,
+ &path[3]);
+ }
dbus_free_string_array (path);
@@ -875,6 +1075,7 @@
dbusFiniDisplay (CompPlugin *p,
CompDisplay *d)
{
+
DBUS_DISPLAY (d);
compRemoveWatchFd (dd->watchFdHandle);